add federated resource api (#2725)

Signed-off-by: Jeff <zw0948@gmail.com>
This commit is contained in:
zryfish
2020-07-31 17:12:58 +08:00
committed by GitHub
parent 74533cb533
commit 4702beb6ac
119 changed files with 11581 additions and 205 deletions

View File

@@ -37,7 +37,7 @@ const (
StatusFailed = "failed"
StatusBound = "bound"
StatusLost = "lost"
StatusComplete = "complete"
StatusComplete = "completed"
StatusWarning = "warning"
StatusUnschedulable = "unschedulable"
Deployments = "deployments"

View File

@@ -23,6 +23,7 @@ import (
"kubesphere.io/kubesphere/pkg/api"
"kubesphere.io/kubesphere/pkg/apiserver/query"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
"strings"
)
type crdGetter struct {
@@ -76,5 +77,10 @@ func (c crdGetter) filter(object runtime.Object, filter query.Filter) bool {
return false
}
return v1alpha3.DefaultObjectMetaFilter(crd.ObjectMeta, filter)
switch filter.Field {
case query.FieldName:
return strings.Contains(crd.Name, string(filter.Value)) || strings.Contains(crd.Spec.Names.Kind, string(filter.Value))
default:
return v1alpha3.DefaultObjectMetaFilter(crd.ObjectMeta, filter)
}
}

View File

@@ -0,0 +1,92 @@
/*
Copyright 2019 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package federatedapplication
import (
"k8s.io/apimachinery/pkg/runtime"
"kubesphere.io/kubesphere/pkg/api"
"kubesphere.io/kubesphere/pkg/apis/types/v1beta1"
"kubesphere.io/kubesphere/pkg/apiserver/query"
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
)
type fedApplicationsGetter struct {
informer informers.SharedInformerFactory
}
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
return &fedApplicationsGetter{informer: sharedInformers}
}
func (d *fedApplicationsGetter) Get(namespace, name string) (runtime.Object, error) {
return d.informer.Types().V1beta1().FederatedApplications().Lister().FederatedApplications(namespace).Get(name)
}
func (d *fedApplicationsGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
applications, err := d.informer.Types().V1beta1().FederatedApplications().Lister().FederatedApplications(namespace).List(query.Selector())
if err != nil {
return nil, err
}
var result []runtime.Object
for _, app := range applications {
result = append(result, app)
}
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
}
func (d *fedApplicationsGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
leftApplication, ok := left.(*v1beta1.FederatedApplication)
if !ok {
return false
}
rightApplication, ok := right.(*v1beta1.FederatedApplication)
if !ok {
return false
}
switch field {
case query.FieldUpdateTime:
fallthrough
case query.FieldLastUpdateTimestamp:
return lastUpdateTime(leftApplication) > (lastUpdateTime(rightApplication))
default:
return v1alpha3.DefaultObjectMetaCompare(leftApplication.ObjectMeta, rightApplication.ObjectMeta, field)
}
}
func (d *fedApplicationsGetter) filter(object runtime.Object, filter query.Filter) bool {
application, ok := object.(*v1beta1.FederatedApplication)
if !ok {
return false
}
return v1alpha3.DefaultObjectMetaFilter(application.ObjectMeta, filter)
}
func lastUpdateTime(application *v1beta1.FederatedApplication) string {
lut := application.CreationTimestamp.Time.String()
for _, condition := range application.Status.Conditions {
if condition.LastUpdateTime > lut {
lut = condition.LastUpdateTime
}
}
return lut
}

View File

@@ -0,0 +1,76 @@
/*
Copyright 2019 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package federatedconfigmap
import (
"k8s.io/apimachinery/pkg/runtime"
"kubesphere.io/kubesphere/pkg/api"
"kubesphere.io/kubesphere/pkg/apis/types/v1beta1"
"kubesphere.io/kubesphere/pkg/apiserver/query"
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
)
type fedConfigMapsGetter struct {
informer informers.SharedInformerFactory
}
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
return &fedConfigMapsGetter{informer: sharedInformers}
}
func (d *fedConfigMapsGetter) Get(namespace, name string) (runtime.Object, error) {
return d.informer.Types().V1beta1().FederatedConfigMaps().Lister().FederatedConfigMaps(namespace).Get(name)
}
func (d *fedConfigMapsGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
configmaps, err := d.informer.Types().V1beta1().FederatedConfigMaps().Lister().FederatedConfigMaps(namespace).List(query.Selector())
if err != nil {
return nil, err
}
var result []runtime.Object
for _, configmap := range configmaps {
result = append(result, configmap)
}
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
}
func (d *fedConfigMapsGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
leftCM, ok := left.(*v1beta1.FederatedConfigMap)
if !ok {
return false
}
rightCM, ok := right.(*v1beta1.FederatedConfigMap)
if !ok {
return false
}
return v1alpha3.DefaultObjectMetaCompare(leftCM.ObjectMeta, rightCM.ObjectMeta, field)
}
func (d *fedConfigMapsGetter) filter(object runtime.Object, filter query.Filter) bool {
configMap, ok := object.(*v1beta1.FederatedConfigMap)
if !ok {
return false
}
return v1alpha3.DefaultObjectMetaFilter(configMap.ObjectMeta, filter)
}

View File

@@ -0,0 +1,80 @@
package federateddeployment
import (
"k8s.io/apimachinery/pkg/runtime"
"kubesphere.io/kubesphere/pkg/api"
"kubesphere.io/kubesphere/pkg/apis/types/v1beta1"
"kubesphere.io/kubesphere/pkg/apiserver/query"
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
)
type fedreatedDeploymentGetter struct {
informer informers.SharedInformerFactory
}
func New(informer informers.SharedInformerFactory) v1alpha3.Interface {
return &fedreatedDeploymentGetter{
informer: informer,
}
}
func (f *fedreatedDeploymentGetter) Get(namespace, name string) (runtime.Object, error) {
return f.informer.Types().V1beta1().FederatedDeployments().Lister().FederatedDeployments(namespace).Get(name)
}
func (f *fedreatedDeploymentGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
federatedDeployments, err := f.informer.Types().V1beta1().FederatedDeployments().Lister().FederatedDeployments(namespace).List(query.Selector())
if err != nil {
return nil, err
}
var result []runtime.Object
for _, fedDeployment := range federatedDeployments {
result = append(result, fedDeployment)
}
return v1alpha3.DefaultList(result, query, f.compare, f.filter), nil
}
func (f *fedreatedDeploymentGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
leftFedDeployment, ok := left.(*v1beta1.FederatedDeployment)
if !ok {
return false
}
rightFedDeployment, ok := right.(*v1beta1.FederatedDeployment)
if !ok {
return false
}
switch field {
case query.FieldUpdateTime:
fallthrough
case query.FieldLastUpdateTimestamp:
return lastUpdateTime(leftFedDeployment) > lastUpdateTime(rightFedDeployment)
default:
return v1alpha3.DefaultObjectMetaCompare(leftFedDeployment.ObjectMeta, rightFedDeployment.ObjectMeta, field)
}
}
func (f *fedreatedDeploymentGetter) filter(object runtime.Object, filter query.Filter) bool {
fedDeployment, ok := object.(*v1beta1.FederatedDeployment)
if !ok {
return false
}
return v1alpha3.DefaultObjectMetaFilter(fedDeployment.ObjectMeta, filter)
}
func lastUpdateTime(fedDeployment *v1beta1.FederatedDeployment) string {
lut := fedDeployment.CreationTimestamp.Time.String()
for _, condition := range fedDeployment.Status.Conditions {
if condition.LastUpdateTime > lut {
lut = condition.LastUpdateTime
}
}
return lut
}

View File

@@ -0,0 +1,82 @@
/*
Copyright 2019 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package federatedpersistentvolumeclaim
import (
"k8s.io/apimachinery/pkg/runtime"
"kubesphere.io/kubesphere/pkg/api"
"kubesphere.io/kubesphere/pkg/apis/types/v1beta1"
"kubesphere.io/kubesphere/pkg/apiserver/query"
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
)
const (
storageClassName = "storageClassName"
)
type fedPersistentVolumeClaimGetter struct {
informers informers.SharedInformerFactory
}
func New(informer informers.SharedInformerFactory) v1alpha3.Interface {
return &fedPersistentVolumeClaimGetter{informers: informer}
}
func (p *fedPersistentVolumeClaimGetter) Get(namespace, name string) (runtime.Object, error) {
return p.informers.Types().V1beta1().FederatedPersistentVolumeClaims().Lister().FederatedPersistentVolumeClaims(namespace).Get(name)
}
func (p *fedPersistentVolumeClaimGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
all, err := p.informers.Types().V1beta1().FederatedPersistentVolumeClaims().Lister().FederatedPersistentVolumeClaims(namespace).List(query.Selector())
if err != nil {
return nil, err
}
var result []runtime.Object
for _, pvc := range all {
result = append(result, pvc)
}
return v1alpha3.DefaultList(result, query, p.compare, p.filter), nil
}
func (p *fedPersistentVolumeClaimGetter) compare(left, right runtime.Object, field query.Field) bool {
leftSnapshot, ok := left.(*v1beta1.FederatedPersistentVolumeClaim)
if !ok {
return false
}
rightSnapshot, ok := right.(*v1beta1.FederatedPersistentVolumeClaim)
if !ok {
return false
}
return v1alpha3.DefaultObjectMetaCompare(leftSnapshot.ObjectMeta, rightSnapshot.ObjectMeta, field)
}
func (p *fedPersistentVolumeClaimGetter) filter(object runtime.Object, filter query.Filter) bool {
pvc, ok := object.(*v1beta1.FederatedPersistentVolumeClaim)
if !ok {
return false
}
switch filter.Field {
case storageClassName:
return pvc.Spec.Template.Spec.StorageClassName != nil && *pvc.Spec.Template.Spec.StorageClassName == string(filter.Value)
default:
return v1alpha3.DefaultObjectMetaFilter(pvc.ObjectMeta, filter)
}
}

View File

@@ -0,0 +1,82 @@
/*
Copyright 2019 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package federatedsecret
import (
"k8s.io/apimachinery/pkg/runtime"
"kubesphere.io/kubesphere/pkg/api"
"kubesphere.io/kubesphere/pkg/apis/types/v1beta1"
"kubesphere.io/kubesphere/pkg/apiserver/query"
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
"strings"
)
type fedSecretGetter struct {
sharedInformers informers.SharedInformerFactory
}
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
return &fedSecretGetter{sharedInformers: sharedInformers}
}
func (d *fedSecretGetter) Get(namespace, name string) (runtime.Object, error) {
return d.sharedInformers.Types().V1beta1().FederatedSecrets().Lister().FederatedSecrets(namespace).Get(name)
}
func (d *fedSecretGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
secrets, err := d.sharedInformers.Types().V1beta1().FederatedSecrets().Lister().FederatedSecrets(namespace).List(query.Selector())
if err != nil {
return nil, err
}
var result []runtime.Object
for _, secret := range secrets {
result = append(result, secret)
}
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
}
func (d *fedSecretGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
leftSecret, ok := left.(*v1beta1.FederatedSecret)
if !ok {
return false
}
rightSecret, ok := right.(*v1beta1.FederatedSecret)
if !ok {
return false
}
return v1alpha3.DefaultObjectMetaCompare(leftSecret.ObjectMeta, rightSecret.ObjectMeta, field)
}
func (d *fedSecretGetter) filter(object runtime.Object, filter query.Filter) bool {
fedSecret, ok := object.(*v1beta1.FederatedSecret)
if !ok {
return false
}
switch filter.Field {
case query.FieldType:
return strings.Compare(string(fedSecret.Spec.Template.Type), string(filter.Value)) == 0
default:
return v1alpha3.DefaultObjectMetaFilter(fedSecret.ObjectMeta, filter)
}
}

View File

@@ -0,0 +1,61 @@
package federatedservice
import (
"k8s.io/apimachinery/pkg/runtime"
"kubesphere.io/kubesphere/pkg/api"
"kubesphere.io/kubesphere/pkg/apis/types/v1beta1"
"kubesphere.io/kubesphere/pkg/apiserver/query"
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
)
type federatedServiceGetter struct {
informer informers.SharedInformerFactory
}
func New(informer informers.SharedInformerFactory) v1alpha3.Interface {
return &federatedServiceGetter{
informer: informer,
}
}
func (f *federatedServiceGetter) Get(namespace, name string) (runtime.Object, error) {
return f.informer.Types().V1beta1().FederatedServices().Lister().FederatedServices(namespace).Get(name)
}
func (f *federatedServiceGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
federatedServices, err := f.informer.Types().V1beta1().FederatedServices().Lister().FederatedServices(namespace).List(query.Selector())
if err != nil {
return nil, err
}
var result []runtime.Object
for _, fedService := range federatedServices {
result = append(result, fedService)
}
return v1alpha3.DefaultList(result, query, f.compare, f.filter), nil
}
func (f *federatedServiceGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
leftService, ok := left.(*v1beta1.FederatedService)
if !ok {
return false
}
rightService, ok := right.(*v1beta1.FederatedService)
if !ok {
return false
}
return v1alpha3.DefaultObjectMetaCompare(leftService.ObjectMeta, rightService.ObjectMeta, field)
}
func (f *federatedServiceGetter) filter(object runtime.Object, filter query.Filter) bool {
service, ok := object.(*v1beta1.FederatedService)
if !ok {
return false
}
return v1alpha3.DefaultObjectMetaFilter(service.ObjectMeta, filter)
}

View File

@@ -0,0 +1,77 @@
/*
Copyright 2019 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package statefulset
import (
"k8s.io/apimachinery/pkg/runtime"
"kubesphere.io/kubesphere/pkg/api"
"kubesphere.io/kubesphere/pkg/apis/types/v1beta1"
"kubesphere.io/kubesphere/pkg/apiserver/query"
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
)
type fedStatefulSetGetter struct {
sharedInformers informers.SharedInformerFactory
}
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
return &fedStatefulSetGetter{sharedInformers: sharedInformers}
}
func (d *fedStatefulSetGetter) Get(namespace, name string) (runtime.Object, error) {
return d.sharedInformers.Types().V1beta1().FederatedStatefulSets().Lister().FederatedStatefulSets(namespace).Get(name)
}
func (d *fedStatefulSetGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
// first retrieves all statefulSets within given namespace
statefulSets, err := d.sharedInformers.Types().V1beta1().FederatedStatefulSets().Lister().FederatedStatefulSets(namespace).List(query.Selector())
if err != nil {
return nil, err
}
var result []runtime.Object
for _, statefulSet := range statefulSets {
result = append(result, statefulSet)
}
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
}
func (d *fedStatefulSetGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
leftStatefulSet, ok := left.(*v1beta1.FederatedStatefulSet)
if !ok {
return false
}
rightStatefulSet, ok := right.(*v1beta1.FederatedStatefulSet)
if !ok {
return false
}
return v1alpha3.DefaultObjectMetaCompare(leftStatefulSet.ObjectMeta, rightStatefulSet.ObjectMeta, field)
}
func (d *fedStatefulSetGetter) filter(object runtime.Object, filter query.Filter) bool {
statefulSet, ok := object.(*v1beta1.FederatedStatefulSet)
if !ok {
return false
}
return v1alpha3.DefaultObjectMetaFilter(statefulSet.ObjectMeta, filter)
}

View File

@@ -40,7 +40,13 @@ import (
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/daemonset"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/deployment"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/devops"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/federatedapplication"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/federatedconfigmap"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/federateddeployment"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/federatednamespace"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/federatedpersistentvolumeclaim"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/federatedsecret"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/federatedservice"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/globalrole"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/globalrolebinding"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/ingress"
@@ -99,7 +105,15 @@ func NewResourceGetter(factory informers.InformerFactory) *ResourceGetter {
getters[snapshotv1beta1.SchemeGroupVersion.WithResource("volumesnapshots")] = volumesnapshot.New(factory.SnapshotSharedInformerFactory())
getters[schema.GroupVersionResource{Group: "cluster.kubesphere.io", Version: "v1alpha1", Resource: "clusters"}] = cluster.New(factory.KubeSphereSharedInformerFactory())
getters[schema.GroupVersionResource{Group: "apiextensions.k8s.io", Version: "v1", Resource: "customresourcedefinitions"}] = customresourcedefinition.New(factory.ApiExtensionSharedInformerFactory())
getters[typesv1beta1.SchemeGroupVersion.WithResource(typesv1beta1.ResourcesPluralFedNamespace)] = federatednamespace.New(factory.KubeSphereSharedInformerFactory())
// federated resources
getters[typesv1beta1.SchemeGroupVersion.WithResource(typesv1beta1.ResourcePluralFederatedNamespace)] = federatednamespace.New(factory.KubeSphereSharedInformerFactory())
getters[typesv1beta1.SchemeGroupVersion.WithResource(typesv1beta1.ResourcePluralFederatedDeployment)] = federateddeployment.New(factory.KubeSphereSharedInformerFactory())
getters[typesv1beta1.SchemeGroupVersion.WithResource(typesv1beta1.ResourcePluralFederatedSecret)] = federatedsecret.New(factory.KubeSphereSharedInformerFactory())
getters[typesv1beta1.SchemeGroupVersion.WithResource(typesv1beta1.ResourcePluralFederatedConfigmap)] = federatedconfigmap.New(factory.KubeSphereSharedInformerFactory())
getters[typesv1beta1.SchemeGroupVersion.WithResource(typesv1beta1.ResourcePluralFederatedService)] = federatedservice.New(factory.KubeSphereSharedInformerFactory())
getters[typesv1beta1.SchemeGroupVersion.WithResource(typesv1beta1.ResourcePluralFederatedApplication)] = federatedapplication.New(factory.KubeSphereSharedInformerFactory())
getters[typesv1beta1.SchemeGroupVersion.WithResource(typesv1beta1.ResourcePluralFederatedPersistentVolumeClaim)] = federatedpersistentvolumeclaim.New(factory.KubeSphereSharedInformerFactory())
return &ResourceGetter{
getters: getters,

View File

@@ -202,7 +202,7 @@ func (t *tenantOperator) ListFederatedNamespaces(user user.Info, workspace strin
queryParam.Filters[query.FieldLabel] = query.Value(fmt.Sprintf("%s=%s", tenantv1alpha1.WorkspaceLabel, workspace))
}
result, err := t.resourceGetter.List(typesv1beta1.ResourcesPluralFedNamespace, "", queryParam)
result, err := t.resourceGetter.List(typesv1beta1.ResourcePluralFederatedNamespace, "", queryParam)
if err != nil {
klog.Error(err)
@@ -222,7 +222,7 @@ func (t *tenantOperator) ListFederatedNamespaces(user user.Info, workspace strin
namespaces := make([]runtime.Object, 0)
for _, roleBinding := range roleBindings {
namespace, err := t.resourceGetter.Get(typesv1beta1.ResourcesPluralFedNamespace, roleBinding.Namespace, roleBinding.Namespace)
namespace, err := t.resourceGetter.Get(typesv1beta1.ResourcePluralFederatedNamespace, roleBinding.Namespace, roleBinding.Namespace)
if err != nil {
if errors.IsNotFound(err) {
continue