From 9e7031f2c0fae1391150d2efca603612f09bf141 Mon Sep 17 00:00:00 2001 From: Steve Kuznetsov Date: Thu, 24 Aug 2023 09:43:43 -0400 Subject: [PATCH] OCPBUGS-17157: label non-OLM resources (#3017) * add a round-tripper to ensure we label non-OLM resources This round-tripper is added to our *rest.Config when it's possible to detect that we're in a CI environment. Developers should set $CI=true to get this behavior locally. Signed-off-by: Steve Kuznetsov * *: label non-OLM resources Today, our controllers use un-filtered LIST+WATCH calls to monitor the state of the cluster. For OLM-specific resource types, that's fine, since we need to know (for instance) about every CSV. For non-OLM resource groups, though, that is needlessly wasteful in memory consumption and makes our controller's footprint scale with the size of the cluster itself, irrespective of the usage of OLM. Adding a label to every resource we create is the first step in being able to filter down all of those requests to only those objects with our label. Signed-off-by: Steve Kuznetsov --------- Signed-off-by: Steve Kuznetsov --- cmd/olm/main.go | 6 +- pkg/controller/bundle/bundle_unpacker.go | 10 ++++ pkg/controller/bundle/bundle_unpacker_test.go | 31 +++++++++-- pkg/controller/install/certresources.go | 5 ++ pkg/controller/install/certresources_test.go | 28 ++++++++-- pkg/controller/install/deployment.go | 4 ++ pkg/controller/install/webhook.go | 7 ++- pkg/controller/operators/catalog/operator.go | 55 ++++++++++++++++++- .../operators/catalog/operator_test.go | 23 ++++++-- pkg/controller/operators/catalog/step.go | 9 +++ .../operators/catalog/step_ensurer.go | 4 ++ pkg/controller/operators/olm/apiservices.go | 3 + pkg/controller/operators/olm/operatorgroup.go | 6 +- .../operators/operatorcondition_controller.go | 9 ++- .../validating_round_tripper.go | 53 ++++++++++++++++++ .../registry/reconciler/configmap.go | 17 +++++- pkg/controller/registry/reconciler/grpc.go | 6 +- .../registry/reconciler/grpc_test.go | 2 + .../registry/reconciler/reconciler.go | 2 + .../registry/reconciler/reconciler_test.go | 4 +- test/e2e/csv_e2e_test.go | 5 +- test/e2e/operator_groups_e2e_test.go | 31 ++++++----- test/e2e/util.go | 2 +- 23 files changed, 275 insertions(+), 47 deletions(-) create mode 100644 pkg/controller/operators/validatingroundtripper/validating_round_tripper.go diff --git a/cmd/olm/main.go b/cmd/olm/main.go index c0b6868f2b..4473496787 100644 --- a/cmd/olm/main.go +++ b/cmd/olm/main.go @@ -11,6 +11,7 @@ import ( configclientset "github.com/openshift/client-go/config/clientset/versioned" configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1" + "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/validatingroundtripper" "github.com/sirupsen/logrus" "github.com/spf13/pflag" corev1 "k8s.io/api/core/v1" @@ -139,6 +140,9 @@ func main() { } config := mgr.GetConfig() + // create a config that validates we're creating objects with labels + validatingConfig := validatingroundtripper.Wrap(config) + versionedConfigClient, err := configclientset.NewForConfig(config) if err != nil { logger.WithError(err).Fatal("error configuring openshift proxy client") @@ -147,7 +151,7 @@ func main() { if err != nil { logger.WithError(err).Fatal("error configuring config client") } - opClient, err := operatorclient.NewClientFromRestConfig(config) + opClient, err := operatorclient.NewClientFromRestConfig(validatingConfig) if err != nil { logger.WithError(err).Fatal("error configuring operator client") } diff --git a/pkg/controller/bundle/bundle_unpacker.go b/pkg/controller/bundle/bundle_unpacker.go index 37686e8627..79f67ab177 100644 --- a/pkg/controller/bundle/bundle_unpacker.go +++ b/pkg/controller/bundle/bundle_unpacker.go @@ -86,11 +86,19 @@ func newBundleUnpackResult(lookup *operatorsv1alpha1.BundleLookup) *BundleUnpack func (c *ConfigMapUnpacker) job(cmRef *corev1.ObjectReference, bundlePath string, secrets []corev1.LocalObjectReference, annotationUnpackTimeout time.Duration) *batchv1.Job { job := &batchv1.Job{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + install.OLMManagedLabelKey: install.OLMManagedLabelValue, + }, + }, Spec: batchv1.JobSpec{ //ttlSecondsAfterFinished: 0 // can use in the future to not have to clean up job Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Name: cmRef.Name, + Labels: map[string]string{ + install.OLMManagedLabelKey: install.OLMManagedLabelValue, + }, }, Spec: corev1.PodSpec{ // With restartPolicy = "OnFailure" when the spec.backoffLimit is reached, the job controller will delete all @@ -687,6 +695,7 @@ func (c *ConfigMapUnpacker) ensureRole(cmRef *corev1.ObjectReference) (role *rba fresh.SetNamespace(cmRef.Namespace) fresh.SetName(cmRef.Name) fresh.SetOwnerReferences([]metav1.OwnerReference{ownerRef(cmRef)}) + fresh.SetLabels(map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}) role, err = c.roleLister.Roles(fresh.GetNamespace()).Get(fresh.GetName()) if err != nil { @@ -730,6 +739,7 @@ func (c *ConfigMapUnpacker) ensureRoleBinding(cmRef *corev1.ObjectReference) (ro fresh.SetNamespace(cmRef.Namespace) fresh.SetName(cmRef.Name) fresh.SetOwnerReferences([]metav1.OwnerReference{ownerRef(cmRef)}) + fresh.SetLabels(map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}) roleBinding, err = c.rbLister.RoleBindings(fresh.GetNamespace()).Get(fresh.GetName()) if err != nil { diff --git a/pkg/controller/bundle/bundle_unpacker_test.go b/pkg/controller/bundle/bundle_unpacker_test.go index ffb006d45c..2bb0d47025 100644 --- a/pkg/controller/bundle/bundle_unpacker_test.go +++ b/pkg/controller/bundle/bundle_unpacker_test.go @@ -208,6 +208,7 @@ func TestConfigMapUnpacker(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: pathHash, Namespace: "ns-a", + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, OwnerReferences: []metav1.OwnerReference{ { APIVersion: "v1", @@ -224,7 +225,8 @@ func TestConfigMapUnpacker(t *testing.T) { BackoffLimit: &backoffLimit, Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ - Name: pathHash, + Name: pathHash, + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, }, Spec: corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, @@ -369,6 +371,7 @@ func TestConfigMapUnpacker(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: pathHash, Namespace: "ns-a", + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, OwnerReferences: []metav1.OwnerReference{ { APIVersion: "v1", @@ -402,6 +405,7 @@ func TestConfigMapUnpacker(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: pathHash, Namespace: "ns-a", + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, OwnerReferences: []metav1.OwnerReference{ { APIVersion: "v1", @@ -437,6 +441,7 @@ func TestConfigMapUnpacker(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: digestHash, Namespace: "ns-a", + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, OwnerReferences: []metav1.OwnerReference{ { APIVersion: "v1", @@ -452,7 +457,8 @@ func TestConfigMapUnpacker(t *testing.T) { BackoffLimit: &backoffLimit, Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ - Name: digestHash, + Name: digestHash, + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, }, Spec: corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, @@ -607,6 +613,7 @@ func TestConfigMapUnpacker(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: digestHash, Namespace: "ns-a", + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, OwnerReferences: []metav1.OwnerReference{ { APIVersion: "operators.coreos.com/v1alpha1", @@ -705,6 +712,7 @@ func TestConfigMapUnpacker(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: digestHash, Namespace: "ns-a", + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, OwnerReferences: []metav1.OwnerReference{ { APIVersion: "v1", @@ -720,7 +728,8 @@ func TestConfigMapUnpacker(t *testing.T) { BackoffLimit: &backoffLimit, Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ - Name: digestHash, + Name: digestHash, + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, }, Spec: corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, @@ -877,6 +886,7 @@ func TestConfigMapUnpacker(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: digestHash, Namespace: "ns-a", + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, OwnerReferences: []metav1.OwnerReference{ { APIVersion: "v1", @@ -910,6 +920,7 @@ func TestConfigMapUnpacker(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: digestHash, Namespace: "ns-a", + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, OwnerReferences: []metav1.OwnerReference{ { APIVersion: "v1", @@ -967,6 +978,7 @@ func TestConfigMapUnpacker(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: pathHash, Namespace: "ns-a", + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, OwnerReferences: []metav1.OwnerReference{ { APIVersion: "v1", @@ -982,7 +994,8 @@ func TestConfigMapUnpacker(t *testing.T) { BackoffLimit: &backoffLimit, Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ - Name: pathHash, + Name: pathHash, + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, }, Spec: corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, @@ -1124,6 +1137,7 @@ func TestConfigMapUnpacker(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: pathHash, Namespace: "ns-a", + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, OwnerReferences: []metav1.OwnerReference{ { APIVersion: "operators.coreos.com/v1alpha1", @@ -1199,6 +1213,7 @@ func TestConfigMapUnpacker(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: pathHash, Namespace: "ns-a", + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, OwnerReferences: []metav1.OwnerReference{ { APIVersion: "v1", @@ -1214,7 +1229,8 @@ func TestConfigMapUnpacker(t *testing.T) { BackoffLimit: &backoffLimit, Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ - Name: pathHash, + Name: pathHash, + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, }, Spec: corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, @@ -1368,6 +1384,7 @@ func TestConfigMapUnpacker(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: pathHash, Namespace: "ns-a", + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, OwnerReferences: []metav1.OwnerReference{ { APIVersion: "operators.coreos.com/v1alpha1", @@ -1442,6 +1459,7 @@ func TestConfigMapUnpacker(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: pathHash, Namespace: "ns-a", + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, OwnerReferences: []metav1.OwnerReference{ { APIVersion: "v1", @@ -1457,7 +1475,8 @@ func TestConfigMapUnpacker(t *testing.T) { BackoffLimit: &backoffLimit, Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ - Name: pathHash, + Name: pathHash, + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, }, Spec: corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, diff --git a/pkg/controller/install/certresources.go b/pkg/controller/install/certresources.go index f48e62b771..1a2dcbca7d 100644 --- a/pkg/controller/install/certresources.go +++ b/pkg/controller/install/certresources.go @@ -251,6 +251,7 @@ func (i *StrategyDeploymentInstaller) installCertRequirementsForDeployment(deplo service.SetName(ServiceName(deploymentName)) service.SetNamespace(i.owner.GetNamespace()) ownerutil.AddNonBlockingOwner(service, i.owner) + service.SetLabels(map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}) existingService, err := i.strategyClient.GetOpLister().CoreV1().ServiceLister().Services(i.owner.GetNamespace()).Get(service.GetName()) if err == nil { @@ -366,6 +367,7 @@ func (i *StrategyDeploymentInstaller) installCertRequirementsForDeployment(deplo } secretRole.SetName(secret.GetName()) secretRole.SetNamespace(i.owner.GetNamespace()) + secretRole.SetLabels(map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}) existingSecretRole, err := i.strategyClient.GetOpLister().RbacV1().RoleLister().Roles(i.owner.GetNamespace()).Get(secretRole.GetName()) if err == nil { @@ -412,6 +414,7 @@ func (i *StrategyDeploymentInstaller) installCertRequirementsForDeployment(deplo } secretRoleBinding.SetName(secret.GetName()) secretRoleBinding.SetNamespace(i.owner.GetNamespace()) + secretRoleBinding.SetLabels(map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}) existingSecretRoleBinding, err := i.strategyClient.GetOpLister().RbacV1().RoleBindingLister().RoleBindings(i.owner.GetNamespace()).Get(secretRoleBinding.GetName()) if err == nil { @@ -454,6 +457,7 @@ func (i *StrategyDeploymentInstaller) installCertRequirementsForDeployment(deplo }, } authDelegatorClusterRoleBinding.SetName(service.GetName() + "-system:auth-delegator") + authDelegatorClusterRoleBinding.SetLabels(map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}) existingAuthDelegatorClusterRoleBinding, err := i.strategyClient.GetOpLister().RbacV1().ClusterRoleBindingLister().Get(authDelegatorClusterRoleBinding.GetName()) if err == nil { @@ -502,6 +506,7 @@ func (i *StrategyDeploymentInstaller) installCertRequirementsForDeployment(deplo } authReaderRoleBinding.SetName(service.GetName() + "-auth-reader") authReaderRoleBinding.SetNamespace(KubeSystem) + authReaderRoleBinding.SetLabels(map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}) existingAuthReaderRoleBinding, err := i.strategyClient.GetOpLister().RbacV1().RoleBindingLister().RoleBindings(KubeSystem).Get(authReaderRoleBinding.GetName()) if err == nil { diff --git a/pkg/controller/install/certresources_test.go b/pkg/controller/install/certresources_test.go index 3823f29f37..ad8e1041b4 100644 --- a/pkg/controller/install/certresources_test.go +++ b/pkg/controller/install/certresources_test.go @@ -7,6 +7,7 @@ import ( "time" "github.com/golang/mock/gomock" + "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" appsv1 "k8s.io/api/apps/v1" @@ -155,7 +156,8 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) { mockOpClient.EXPECT().DeleteService(namespace, "test-service", &metav1.DeleteOptions{}).Return(nil) service := corev1.Service{ ObjectMeta: metav1.ObjectMeta{ - Name: "test-service", + Name: "test-service", + Labels: map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}, OwnerReferences: []metav1.OwnerReference{ ownerutil.NonBlockingOwner(&v1alpha1.ClusterServiceVersion{}), }, @@ -198,6 +200,7 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: secret.GetName(), Namespace: namespace, + Labels: map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}, }, Rules: []rbacv1.PolicyRule{ { @@ -214,6 +217,7 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: secret.GetName(), Namespace: namespace, + Labels: map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}, }, Subjects: []rbacv1.Subject{ { @@ -233,7 +237,8 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) { authDelegatorClusterRoleBinding := &rbacv1.ClusterRoleBinding{ ObjectMeta: metav1.ObjectMeta{ - Name: service.GetName() + "-system:auth-delegator", + Name: service.GetName() + "-system:auth-delegator", + Labels: map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}, }, Subjects: []rbacv1.Subject{ { @@ -269,6 +274,7 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) { } authReaderRoleBinding.SetName(service.GetName() + "-auth-reader") authReaderRoleBinding.SetNamespace(KubeSystem) + authReaderRoleBinding.SetLabels(map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}) mockOpClient.EXPECT().UpdateRoleBinding(authReaderRoleBinding).Return(authReaderRoleBinding, nil) }, @@ -380,6 +386,7 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "test-service", Namespace: owner.GetNamespace(), + Labels: map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}, OwnerReferences: []metav1.OwnerReference{ ownerutil.NonBlockingOwner(owner), }, @@ -422,6 +429,7 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: secret.GetName(), Namespace: namespace, + Labels: map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}, }, Rules: []rbacv1.PolicyRule{ { @@ -438,6 +446,7 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: secret.GetName(), Namespace: namespace, + Labels: map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}, }, Subjects: []rbacv1.Subject{ { @@ -457,7 +466,8 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) { authDelegatorClusterRoleBinding := &rbacv1.ClusterRoleBinding{ ObjectMeta: metav1.ObjectMeta{ - Name: service.GetName() + "-system:auth-delegator", + Name: service.GetName() + "-system:auth-delegator", + Labels: map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}, }, Subjects: []rbacv1.Subject{ { @@ -493,6 +503,7 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) { } authReaderRoleBinding.SetName(service.GetName() + "-auth-reader") authReaderRoleBinding.SetNamespace(KubeSystem) + authReaderRoleBinding.SetLabels(map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}) mockOpClient.EXPECT().UpdateRoleBinding(authReaderRoleBinding).Return(authReaderRoleBinding, nil) }, @@ -596,7 +607,8 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) { mockOpClient.EXPECT().DeleteService(namespace, "test-service", &metav1.DeleteOptions{}).Return(nil) service := corev1.Service{ ObjectMeta: metav1.ObjectMeta{ - Name: "test-service", + Name: "test-service", + Labels: map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}, OwnerReferences: []metav1.OwnerReference{ ownerutil.NonBlockingOwner(&v1alpha1.ClusterServiceVersion{}), }, @@ -649,6 +661,7 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: secret.GetName(), Namespace: namespace, + Labels: map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}, }, Rules: []rbacv1.PolicyRule{ { @@ -665,6 +678,7 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: secret.GetName(), Namespace: namespace, + Labels: map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}, }, Subjects: []rbacv1.Subject{ { @@ -684,7 +698,8 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) { authDelegatorClusterRoleBinding := &rbacv1.ClusterRoleBinding{ ObjectMeta: metav1.ObjectMeta{ - Name: service.GetName() + "-system:auth-delegator", + Name: service.GetName() + "-system:auth-delegator", + Labels: map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}, }, Subjects: []rbacv1.Subject{ { @@ -720,6 +735,7 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) { } authReaderRoleBinding.SetName(service.GetName() + "-auth-reader") authReaderRoleBinding.SetNamespace(KubeSystem) + authReaderRoleBinding.SetLabels(map[string]string{OLMManagedLabelKey: OLMManagedLabelValue}) mockOpClient.EXPECT().UpdateRoleBinding(authReaderRoleBinding).Return(authReaderRoleBinding, nil) }, @@ -853,7 +869,7 @@ func TestInstallCertRequirementsForDeployment(t *testing.T) { return } if !reflect.DeepEqual(got, tt.want) { - t.Errorf("installCertRequirementsForDeployment() \n got = %v \n want = %v", got, tt.want) + t.Errorf("installCertRequirementsForDeployment() \n got = %v \n want = %v\n diff=%s\n", got, tt.want, cmp.Diff(got, tt.want)) } }) } diff --git a/pkg/controller/install/deployment.go b/pkg/controller/install/deployment.go index 43aab8e1ce..12e8044b25 100644 --- a/pkg/controller/install/deployment.go +++ b/pkg/controller/install/deployment.go @@ -152,6 +152,10 @@ func (i *StrategyDeploymentInstaller) deploymentForSpec(name string, spec appsv1 dep.Spec.Template.SetAnnotations(annotations) // Set custom labels before CSV owner labels + if dep.Labels == nil { + dep.Labels = map[string]string{} + } + dep.Labels[OLMManagedLabelKey] = OLMManagedLabelValue dep.SetLabels(specLabels) ownerutil.AddNonBlockingOwner(dep, i.owner) diff --git a/pkg/controller/install/webhook.go b/pkg/controller/install/webhook.go index 74c1987516..a152434ced 100644 --- a/pkg/controller/install/webhook.go +++ b/pkg/controller/install/webhook.go @@ -67,11 +67,11 @@ func (i *StrategyDeploymentInstaller) createOrUpdateWebhook(caPEM []byte, desc v switch desc.Type { case v1alpha1.ValidatingAdmissionWebhook: - i.createOrUpdateValidatingWebhook(ogNamespacelabelSelector, caPEM, desc) + return i.createOrUpdateValidatingWebhook(ogNamespacelabelSelector, caPEM, desc) case v1alpha1.MutatingAdmissionWebhook: - i.createOrUpdateMutatingWebhook(ogNamespacelabelSelector, caPEM, desc) + return i.createOrUpdateMutatingWebhook(ogNamespacelabelSelector, caPEM, desc) case v1alpha1.ConversionWebhook: - i.createOrUpdateConversionWebhook(caPEM, desc) + return i.createOrUpdateConversionWebhook(caPEM, desc) } return nil } @@ -287,6 +287,7 @@ func addWebhookLabels(object metav1.Object, webhookDesc v1alpha1.WebhookDescript } labels[WebhookDescKey] = webhookDesc.GenerateName labels[WebhookHashKey] = HashWebhookDesc(webhookDesc) + labels[OLMManagedLabelKey] = OLMManagedLabelValue object.SetLabels(labels) return nil diff --git a/pkg/controller/operators/catalog/operator.go b/pkg/controller/operators/catalog/operator.go index 8ad84dea86..9f091dc997 100644 --- a/pkg/controller/operators/catalog/operator.go +++ b/pkg/controller/operators/catalog/operator.go @@ -11,6 +11,7 @@ import ( "sync" "time" + "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/validatingroundtripper" errorwrap "github.com/pkg/errors" "github.com/sirupsen/logrus" "google.golang.org/grpc/connectivity" @@ -140,8 +141,11 @@ func NewOperator(ctx context.Context, kubeconfigPath string, clock utilclock.Clo return nil, err } + // create a config that validates we're creating objects with labels + validatingConfig := validatingroundtripper.Wrap(config) + // Create a new client for dynamic types (CRs) - dynamicClient, err := dynamic.NewForConfig(config) + dynamicClient, err := dynamic.NewForConfig(validatingConfig) if err != nil { return nil, err } @@ -152,7 +156,7 @@ func NewOperator(ctx context.Context, kubeconfigPath string, clock utilclock.Clo } // Create a new queueinformer-based operator. - opClient, err := operatorclient.NewClientFromRestConfig(config) + opClient, err := operatorclient.NewClientFromRestConfig(validatingConfig) if err != nil { return nil, err } @@ -2113,6 +2117,10 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error { // Attempt to create the CSV. csv.SetNamespace(namespace) + if csv.Labels == nil { + csv.Labels = map[string]string{} + } + csv.Labels[install.OLMManagedLabelKey] = install.OLMManagedLabelValue status, err := ensurer.EnsureClusterServiceVersion(&csv) if err != nil { @@ -2138,6 +2146,10 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error { // Attempt to create the Subscription sub.SetNamespace(namespace) + if sub.Labels == nil { + sub.Labels = map[string]string{} + } + sub.Labels[install.OLMManagedLabelKey] = install.OLMManagedLabelValue status, err := ensurer.EnsureSubscription(&sub) if err != nil { @@ -2168,6 +2180,10 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error { } s.SetOwnerReferences(updated) s.SetNamespace(namespace) + if s.Labels == nil { + s.Labels = map[string]string{} + } + s.Labels[install.OLMManagedLabelKey] = install.OLMManagedLabelValue status, err := ensurer.EnsureBundleSecret(plan.Namespace, &s) if err != nil { @@ -2192,6 +2208,11 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error { return errorwrap.Wrapf(err, "error parsing step manifest: %s", step.Resource.Name) } + if cr.Labels == nil { + cr.Labels = map[string]string{} + } + cr.Labels[install.OLMManagedLabelKey] = install.OLMManagedLabelValue + status, err := ensurer.EnsureClusterRole(&cr, step) if err != nil { return err @@ -2206,6 +2227,10 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error { if err != nil { return errorwrap.Wrapf(err, "error parsing step manifest: %s", step.Resource.Name) } + if rb.Labels == nil { + rb.Labels = map[string]string{} + } + rb.Labels[install.OLMManagedLabelKey] = install.OLMManagedLabelValue status, err := ensurer.EnsureClusterRoleBinding(&rb, step) if err != nil { @@ -2229,6 +2254,10 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error { } r.SetOwnerReferences(updated) r.SetNamespace(namespace) + if r.Labels == nil { + r.Labels = map[string]string{} + } + r.Labels[install.OLMManagedLabelKey] = install.OLMManagedLabelValue status, err := ensurer.EnsureRole(plan.Namespace, &r) if err != nil { @@ -2252,6 +2281,10 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error { } rb.SetOwnerReferences(updated) rb.SetNamespace(namespace) + if rb.Labels == nil { + rb.Labels = map[string]string{} + } + rb.Labels[install.OLMManagedLabelKey] = install.OLMManagedLabelValue status, err := ensurer.EnsureRoleBinding(plan.Namespace, &rb) if err != nil { @@ -2275,6 +2308,10 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error { } sa.SetOwnerReferences(updated) sa.SetNamespace(namespace) + if sa.Labels == nil { + sa.Labels = map[string]string{} + } + sa.Labels[install.OLMManagedLabelKey] = install.OLMManagedLabelValue status, err := ensurer.EnsureServiceAccount(namespace, &sa) if err != nil { @@ -2306,6 +2343,10 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error { } s.SetOwnerReferences(updated) s.SetNamespace(namespace) + if s.Labels == nil { + s.Labels = map[string]string{} + } + s.Labels[install.OLMManagedLabelKey] = install.OLMManagedLabelValue status, err := ensurer.EnsureService(namespace, &s) if err != nil { @@ -2336,6 +2377,10 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error { } cfg.SetOwnerReferences(updated) cfg.SetNamespace(namespace) + if cfg.Labels == nil { + cfg.Labels = map[string]string{} + } + cfg.Labels[install.OLMManagedLabelKey] = install.OLMManagedLabelValue status, err := ensurer.EnsureConfigMap(plan.Namespace, &cfg) if err != nil { @@ -2395,6 +2440,12 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error { } } } + l := unstructuredObject.GetLabels() + if l == nil { + l = map[string]string{} + } + l[install.OLMManagedLabelKey] = install.OLMManagedLabelValue + unstructuredObject.SetLabels(l) // Set up the dynamic client ResourceInterface and set ownerrefs var resourceInterface dynamic.ResourceInterface diff --git a/pkg/controller/operators/catalog/operator_test.go b/pkg/controller/operators/catalog/operator_test.go index cdf31e4d5a..2da5979285 100644 --- a/pkg/controller/operators/catalog/operator_test.go +++ b/pkg/controller/operators/catalog/operator_test.go @@ -13,6 +13,7 @@ import ( "testing/quick" "time" + "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" "github.com/sirupsen/logrus" @@ -568,6 +569,14 @@ func TestExecutePlan(t *testing.T) { modify(t, decodeFile(t, "./testdata/prometheusrule.cr.yaml", &unstructured.Unstructured{}), withNamespace(namespace), withOwner(csv("csv", namespace, nil, nil)), + modifyMeta(func(m metav1.Object) { + labels := m.GetLabels() + if labels == nil { + labels = map[string]string{} + } + labels[install.OLMManagedLabelKey] = install.OLMManagedLabelValue + m.SetLabels(labels) + }), ), }, err: nil, @@ -599,7 +608,7 @@ func TestExecutePlan(t *testing.T) { }), want: []runtime.Object{ &apiextensionsv1.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "test"}, + ObjectMeta: metav1.ObjectMeta{Name: "test", Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}}, TypeMeta: metav1.TypeMeta{ Kind: "CustomResourceDefinition", APIVersion: "apiextensions.k8s.io/v1", // v1 CRD version of API @@ -1826,6 +1835,7 @@ func csv(name, namespace string, owned, required []string) *v1alpha1.ClusterServ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: namespace, + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, }, Spec: v1alpha1.ClusterServiceVersionSpec{ CustomResourceDefinitions: v1alpha1.CustomResourceDefinitions{ @@ -1839,7 +1849,8 @@ func csv(name, namespace string, owned, required []string) *v1alpha1.ClusterServ func crd(name string) apiextensionsv1beta1.CustomResourceDefinition { return apiextensionsv1beta1.CustomResourceDefinition{ ObjectMeta: metav1.ObjectMeta{ - Name: name, + Name: name, + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, }, Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{ Group: name + "group", @@ -1860,6 +1871,7 @@ func service(name, namespace string) *corev1.Service { ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: namespace, + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, }, } } @@ -1869,6 +1881,7 @@ func secret(name, namespace string) *corev1.Secret { ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: namespace, + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, }, } } @@ -1877,12 +1890,12 @@ func serviceAccount(name, namespace, generateName string, secretRef *corev1.Obje if secretRef == nil { return &corev1.ServiceAccount{ TypeMeta: metav1.TypeMeta{Kind: serviceAccountKind, APIVersion: ""}, - ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: namespace, GenerateName: generateName}, + ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: namespace, GenerateName: generateName, Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}}, } } return &corev1.ServiceAccount{ TypeMeta: metav1.TypeMeta{Kind: serviceAccountKind, APIVersion: ""}, - ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: namespace, GenerateName: generateName}, + ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: namespace, GenerateName: generateName, Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}}, Secrets: []corev1.ObjectReference{*secretRef}, } } @@ -1890,7 +1903,7 @@ func serviceAccount(name, namespace, generateName string, secretRef *corev1.Obje func configMap(name, namespace string) *corev1.ConfigMap { return &corev1.ConfigMap{ TypeMeta: metav1.TypeMeta{Kind: configMapKind}, - ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: namespace}, + ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: namespace, Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}}, } } diff --git a/pkg/controller/operators/catalog/step.go b/pkg/controller/operators/catalog/step.go index 54abd56bf9..d3f54f1827 100644 --- a/pkg/controller/operators/catalog/step.go +++ b/pkg/controller/operators/catalog/step.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install" "github.com/pkg/errors" "github.com/sirupsen/logrus" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" @@ -128,6 +129,10 @@ func (b *builder) NewCRDV1Step(client apiextensionsv1client.ApiextensionsV1Inter } setInstalledAlongsideAnnotation(b.annotator, crd, b.plan.GetNamespace(), step.Resolving, b.csvLister, crd) + if crd.Labels == nil { + crd.Labels = map[string]string{} + } + crd.Labels[install.OLMManagedLabelKey] = install.OLMManagedLabelValue _, createError := client.CustomResourceDefinitions().Create(context.TODO(), crd, metav1.CreateOptions{}) if apierrors.IsAlreadyExists(createError) { @@ -211,6 +216,10 @@ func (b *builder) NewCRDV1Beta1Step(client apiextensionsv1beta1client.Apiextensi } setInstalledAlongsideAnnotation(b.annotator, crd, b.plan.GetNamespace(), step.Resolving, b.csvLister, crd) + if crd.Labels == nil { + crd.Labels = map[string]string{} + } + crd.Labels[install.OLMManagedLabelKey] = install.OLMManagedLabelValue _, createError := client.CustomResourceDefinitions().Create(context.TODO(), crd, metav1.CreateOptions{}) if apierrors.IsAlreadyExists(createError) { diff --git a/pkg/controller/operators/catalog/step_ensurer.go b/pkg/controller/operators/catalog/step_ensurer.go index 91c309f97a..3369aa6561 100644 --- a/pkg/controller/operators/catalog/step_ensurer.go +++ b/pkg/controller/operators/catalog/step_ensurer.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install" errorwrap "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" @@ -91,6 +92,9 @@ func (o *StepEnsurer) EnsureSecret(operatorNamespace, planNamespace, name string ObjectMeta: metav1.ObjectMeta{ Name: secret.Name, Namespace: planNamespace, + Labels: map[string]string{ + install.OLMManagedLabelKey: install.OLMManagedLabelValue, + }, }, Data: secret.Data, Type: secret.Type, diff --git a/pkg/controller/operators/olm/apiservices.go b/pkg/controller/operators/olm/apiservices.go index c71b5594f3..cb052f510f 100644 --- a/pkg/controller/operators/olm/apiservices.go +++ b/pkg/controller/operators/olm/apiservices.go @@ -228,6 +228,7 @@ func (a *Operator) areAPIServicesAvailable(csv *v1alpha1.ClusterServiceVersion) for _, desc := range csv.Spec.APIServiceDefinitions.Owned { apiService, err := a.lister.APIRegistrationV1().APIServiceLister().Get(desc.GetName()) if apierrors.IsNotFound(err) { + a.logger.Debugf("APIRegistration APIService %s not found", desc.GetName()) return false, nil } @@ -236,10 +237,12 @@ func (a *Operator) areAPIServicesAvailable(csv *v1alpha1.ClusterServiceVersion) } if !install.IsAPIServiceAvailable(apiService) { + a.logger.Debugf("APIService not available for %s", desc.GetName()) return false, nil } if ok, err := a.isGVKRegistered(desc.Group, desc.Version, desc.Kind); !ok || err != nil { + a.logger.Debugf("%s.%s/%s not registered for %s", desc.Group, desc.Version, desc.Kind, desc.GetName()) return false, err } } diff --git a/pkg/controller/operators/olm/operatorgroup.go b/pkg/controller/operators/olm/operatorgroup.go index 9900bc3844..90d2cb8994 100644 --- a/pkg/controller/operators/olm/operatorgroup.go +++ b/pkg/controller/operators/olm/operatorgroup.go @@ -383,7 +383,8 @@ func (a *Operator) ensureProvidedAPIClusterRole(namePrefix, suffix string, verbs // Matches aggregation rules on the bootstrap ClusterRoles. // https://github.com/kubernetes/kubernetes/blob/61847eab61788fb0543b4cf147773c9da646ed2f/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go#L232 fmt.Sprintf("rbac.authorization.k8s.io/aggregate-to-%s", suffix): "true", - aggregationLabel: "true", + aggregationLabel: "true", + install.OLMManagedLabelKey: install.OLMManagedLabelValue, }, OwnerReferences: []metav1.OwnerReference{ownerutil.NonBlockingOwner(api)}, }, @@ -983,7 +984,8 @@ func (a *Operator) updateNamespaceList(op *operatorsv1.OperatorGroup) ([]string, func (a *Operator) ensureOpGroupClusterRole(op *operatorsv1.OperatorGroup, suffix string, apis cache.APISet) error { clusterRole := &rbacv1.ClusterRole{ ObjectMeta: metav1.ObjectMeta{ - Name: strings.Join([]string{op.GetName(), suffix}, "-"), + Name: strings.Join([]string{op.GetName(), suffix}, "-"), + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, }, } var selectors []metav1.LabelSelector diff --git a/pkg/controller/operators/operatorcondition_controller.go b/pkg/controller/operators/operatorcondition_controller.go index 45e85e44cb..c805977c01 100644 --- a/pkg/controller/operators/operatorcondition_controller.go +++ b/pkg/controller/operators/operatorcondition_controller.go @@ -5,11 +5,12 @@ import ( "reflect" "github.com/go-logr/logr" + "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" - meta "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" @@ -128,6 +129,9 @@ func (r *OperatorConditionReconciler) ensureOperatorConditionRole(operatorCondit ObjectMeta: metav1.ObjectMeta{ Name: operatorCondition.GetName(), Namespace: operatorCondition.GetNamespace(), + Labels: map[string]string{ + install.OLMManagedLabelKey: install.OLMManagedLabelValue, + }, }, Rules: []rbacv1.PolicyRule{ { @@ -176,6 +180,9 @@ func (r *OperatorConditionReconciler) ensureOperatorConditionRoleBinding(operato ObjectMeta: metav1.ObjectMeta{ Name: operatorCondition.GetName(), Namespace: operatorCondition.GetNamespace(), + Labels: map[string]string{ + install.OLMManagedLabelKey: install.OLMManagedLabelValue, + }, }, Subjects: subjects, RoleRef: rbacv1.RoleRef{ diff --git a/pkg/controller/operators/validatingroundtripper/validating_round_tripper.go b/pkg/controller/operators/validatingroundtripper/validating_round_tripper.go new file mode 100644 index 0000000000..c9c1cbd395 --- /dev/null +++ b/pkg/controller/operators/validatingroundtripper/validating_round_tripper.go @@ -0,0 +1,53 @@ +package validatingroundtripper + +import ( + "fmt" + "net/http" + "os" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/util/yaml" + "k8s.io/client-go/rest" +) + +type validatingRoundTripper struct { + delegate http.RoundTripper +} + +func (rt *validatingRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + if req.Method == "POST" { + b, err := req.GetBody() + if err != nil { + panic(err) + } + dec := yaml.NewYAMLOrJSONDecoder(b, 10) + unstructuredObject := &unstructured.Unstructured{} + if err := dec.Decode(unstructuredObject); err != nil { + panic(fmt.Errorf("error decoding object to an unstructured object: %w", err)) + } + gvk := unstructuredObject.GroupVersionKind() + if gvk.Kind != "Event" { + if labels := unstructuredObject.GetLabels(); labels[install.OLMManagedLabelKey] != install.OLMManagedLabelValue { + panic(fmt.Errorf("%s.%s/%v %s/%s does not have labels[%s]=%s", gvk.Kind, gvk.Group, gvk.Version, unstructuredObject.GetNamespace(), unstructuredObject.GetName(), install.OLMManagedLabelKey, install.OLMManagedLabelValue)) + } + } + } + return rt.delegate.RoundTrip(req) +} + +var _ http.RoundTripper = (*validatingRoundTripper)(nil) + +// Wrap is meant to be used in developer environments and CI to make it easy to find places +// where we accidentally create Kubernetes objects without our management label. +func Wrap(cfg *rest.Config) *rest.Config { + if _, set := os.LookupEnv("CI"); !set { + return cfg + } + + cfgCopy := *cfg + cfgCopy.Wrap(func(rt http.RoundTripper) http.RoundTripper { + return &validatingRoundTripper{delegate: rt} + }) + return &cfgCopy +} diff --git a/pkg/controller/registry/reconciler/configmap.go b/pkg/controller/registry/reconciler/configmap.go index 11a87a8746..a4aee1c2f0 100644 --- a/pkg/controller/registry/reconciler/configmap.go +++ b/pkg/controller/registry/reconciler/configmap.go @@ -5,6 +5,7 @@ import ( "context" "fmt" + "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install" "github.com/pkg/errors" "github.com/sirupsen/logrus" corev1 "k8s.io/api/core/v1" @@ -52,7 +53,8 @@ const ( func (s *configMapCatalogSourceDecorator) Labels() map[string]string { labels := map[string]string{ - CatalogSourceLabelKey: s.GetName(), + CatalogSourceLabelKey: s.GetName(), + install.OLMManagedLabelKey: install.OLMManagedLabelValue, } if s.Spec.SourceType == v1alpha1.SourceTypeInternal || s.Spec.SourceType == v1alpha1.SourceTypeConfigmap { labels[ConfigMapRVLabelKey] = s.Status.ConfigMapResource.ResourceVersion @@ -93,7 +95,9 @@ func (s *configMapCatalogSourceDecorator) Service() *corev1.Service { }, } - labels := map[string]string{} + labels := map[string]string{ + install.OLMManagedLabelKey: install.OLMManagedLabelValue, + } hash := HashServiceSpec(svc.Spec) labels[ServiceHashLabelKey] = hash svc.SetLabels(labels) @@ -114,6 +118,9 @@ func (s *configMapCatalogSourceDecorator) ServiceAccount() *corev1.ServiceAccoun ObjectMeta: metav1.ObjectMeta{ Name: s.serviceAccountName(), Namespace: s.GetNamespace(), + Labels: map[string]string{ + install.OLMManagedLabelKey: install.OLMManagedLabelValue, + }, }, } ownerutil.AddOwner(sa, s.CatalogSource, false, false) @@ -125,6 +132,9 @@ func (s *configMapCatalogSourceDecorator) Role() *rbacv1.Role { ObjectMeta: metav1.ObjectMeta{ Name: s.roleName(), Namespace: s.GetNamespace(), + Labels: map[string]string{ + install.OLMManagedLabelKey: install.OLMManagedLabelValue, + }, }, Rules: []rbacv1.PolicyRule{ { @@ -144,6 +154,9 @@ func (s *configMapCatalogSourceDecorator) RoleBinding() *rbacv1.RoleBinding { ObjectMeta: metav1.ObjectMeta{ Name: s.GetName() + "-server-configmap-reader", Namespace: s.GetNamespace(), + Labels: map[string]string{ + install.OLMManagedLabelKey: install.OLMManagedLabelValue, + }, }, Subjects: []rbacv1.Subject{ { diff --git a/pkg/controller/registry/reconciler/grpc.go b/pkg/controller/registry/reconciler/grpc.go index 117c081b23..a73c9833c0 100644 --- a/pkg/controller/registry/reconciler/grpc.go +++ b/pkg/controller/registry/reconciler/grpc.go @@ -6,6 +6,7 @@ import ( "hash/fnv" "time" + "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install" "github.com/pkg/errors" "github.com/sirupsen/logrus" corev1 "k8s.io/api/core/v1" @@ -58,7 +59,8 @@ func (s *grpcCatalogSourceDecorator) SelectorForUpdate() labels.Selector { func (s *grpcCatalogSourceDecorator) Labels() map[string]string { return map[string]string{ - CatalogSourceLabelKey: s.GetName(), + CatalogSourceLabelKey: s.GetName(), + install.OLMManagedLabelKey: install.OLMManagedLabelValue, } } @@ -88,6 +90,7 @@ func (s *grpcCatalogSourceDecorator) Service() *corev1.Service { labels := map[string]string{} hash := HashServiceSpec(svc.Spec) labels[ServiceHashLabelKey] = hash + labels[install.OLMManagedLabelKey] = install.OLMManagedLabelValue svc.SetLabels(labels) ownerutil.AddOwner(svc, s.CatalogSource, false, false) return svc @@ -107,6 +110,7 @@ func (s *grpcCatalogSourceDecorator) ServiceAccount() *corev1.ServiceAccount { ObjectMeta: metav1.ObjectMeta{ Name: s.GetName(), Namespace: s.GetNamespace(), + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, OwnerReferences: []metav1.OwnerReference{ { Name: s.GetName(), diff --git a/pkg/controller/registry/reconciler/grpc_test.go b/pkg/controller/registry/reconciler/grpc_test.go index c219329b3d..7fa8da39d0 100644 --- a/pkg/controller/registry/reconciler/grpc_test.go +++ b/pkg/controller/registry/reconciler/grpc_test.go @@ -5,6 +5,7 @@ import ( "testing" "time" + "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -250,6 +251,7 @@ func TestGrpcRegistryReconciler(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "private-catalog", Namespace: testNamespace, + Labels: map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}, OwnerReferences: []metav1.OwnerReference{ { Name: "private-catalog", diff --git a/pkg/controller/registry/reconciler/reconciler.go b/pkg/controller/registry/reconciler/reconciler.go index 4eb6a542f4..1fe786c692 100644 --- a/pkg/controller/registry/reconciler/reconciler.go +++ b/pkg/controller/registry/reconciler/reconciler.go @@ -5,6 +5,7 @@ import ( "fmt" "hash/fnv" + "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -115,6 +116,7 @@ func Pod(source *operatorsv1alpha1.CatalogSource, name string, img string, saNam for key, value := range labels { podLabels[key] = value } + podLabels[install.OLMManagedLabelKey] = install.OLMManagedLabelValue for key, value := range annotations { podAnnotations[key] = value diff --git a/pkg/controller/registry/reconciler/reconciler_test.go b/pkg/controller/registry/reconciler/reconciler_test.go index fe2e256d7b..7e288338f5 100644 --- a/pkg/controller/registry/reconciler/reconciler_test.go +++ b/pkg/controller/registry/reconciler/reconciler_test.go @@ -35,7 +35,7 @@ func TestPodMemoryTarget(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ GenerateName: "test-", Namespace: "testns", - Labels: map[string]string{"olm.pod-spec-hash": "68d7885bb7"}, + Labels: map[string]string{"olm.pod-spec-hash": "68d7885bb7", "olm.managed": "true"}, Annotations: map[string]string{"cluster-autoscaler.kubernetes.io/safe-to-evict": "true"}, }, Spec: corev1.PodSpec{ @@ -107,7 +107,7 @@ func TestPodMemoryTarget(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ GenerateName: "test-", Namespace: "testns", - Labels: map[string]string{"olm.pod-spec-hash": "5c6bb6945f"}, + Labels: map[string]string{"olm.pod-spec-hash": "5c6bb6945f", "olm.managed": "true"}, Annotations: map[string]string{"cluster-autoscaler.kubernetes.io/safe-to-evict": "true"}, }, Spec: corev1.PodSpec{ diff --git a/test/e2e/csv_e2e_test.go b/test/e2e/csv_e2e_test.go index 5afda922dc..ea7409745f 100644 --- a/test/e2e/csv_e2e_test.go +++ b/test/e2e/csv_e2e_test.go @@ -4432,17 +4432,18 @@ func fetchCSV(c versioned.Interface, name, namespace string, checker csvConditio var fetchedCSV *operatorsv1alpha1.ClusterServiceVersion var err error + ctx.Ctx().Logf("waiting for CSV %s/%s to reach condition", namespace, name) Eventually(func() (bool, error) { fetchedCSV, err = c.OperatorsV1alpha1().ClusterServiceVersions(namespace).Get(context.TODO(), name, metav1.GetOptions{}) if err != nil { return false, err } - ctx.Ctx().Logf("%s (%s): %s", fetchedCSV.Status.Phase, fetchedCSV.Status.Reason, fetchedCSV.Status.Message) + ctx.Ctx().Logf("CSV %s/%s: phase %s (%s): %s", namespace, name, fetchedCSV.Status.Phase, fetchedCSV.Status.Reason, fetchedCSV.Status.Message) return checker(fetchedCSV), nil }).Should(BeTrue()) if err != nil { - ctx.Ctx().Logf("never got correct status: %#v", fetchedCSV.Status) + ctx.Ctx().Logf("CSV %s/%s never got correct status: %#v", namespace, name, fetchedCSV.Status) } return fetchedCSV, err } diff --git a/test/e2e/operator_groups_e2e_test.go b/test/e2e/operator_groups_e2e_test.go index a112aa5055..feebdc0675 100644 --- a/test/e2e/operator_groups_e2e_test.go +++ b/test/e2e/operator_groups_e2e_test.go @@ -426,8 +426,8 @@ var _ = Describe("Operator Group", func() { // Create crd so csv succeeds // Ensure clusterroles created and aggregated for access provided APIs - // Generate namespaceA nsA := genName("a") + GinkgoT().Logf("generating namespaceA: %s", nsA) c := newKubeClient() for _, ns := range []string{nsA} { namespace := &corev1.Namespace{ @@ -442,25 +442,29 @@ var _ = Describe("Operator Group", func() { }(ns) } - // Generate operatorGroupA - OwnNamespace - groupA := newOperatorGroup(nsA, genName("a"), nil, nil, []string{nsA}, false) + groupAName := genName("a") + GinkgoT().Logf("Generate operatorGroupA - OwnNamespace: %s", groupAName) + groupA := newOperatorGroup(nsA, groupAName, nil, nil, []string{nsA}, false) _, err := crc.OperatorsV1().OperatorGroups(nsA).Create(context.TODO(), groupA, metav1.CreateOptions{}) require.NoError(GinkgoT(), err) defer func() { require.NoError(GinkgoT(), crc.OperatorsV1().OperatorGroups(nsA).Delete(context.TODO(), groupA.GetName(), metav1.DeleteOptions{})) }() - // Generate csvA in namespaceA with all installmodes supported - crd := newCRD(genName("a")) - namedStrategy := newNginxInstallStrategy(genName("dep-"), nil, nil) - csvA := newCSV("nginx-a", nsA, "", semver.MustParse("0.1.0"), []apiextensions.CustomResourceDefinition{crd}, nil, &namedStrategy) + crdAName := genName("a") + strategyName := genName("dep-") + csvAName := "nginx-a" + GinkgoT().Logf("Generate csv (%s/%s) with crd %s and with all installmodes supported: %s", nsA, csvAName, crdAName, strategyName) + crd := newCRD(crdAName) + namedStrategy := newNginxInstallStrategy(strategyName, nil, nil) + csvA := newCSV(csvAName, nsA, "", semver.MustParse("0.1.0"), []apiextensions.CustomResourceDefinition{crd}, nil, &namedStrategy) _, err = crc.OperatorsV1alpha1().ClusterServiceVersions(nsA).Create(context.TODO(), &csvA, metav1.CreateOptions{}) require.NoError(GinkgoT(), err) defer func() { require.NoError(GinkgoT(), crc.OperatorsV1alpha1().ClusterServiceVersions(nsA).Delete(context.TODO(), csvA.GetName(), metav1.DeleteOptions{})) }() - // Create crd so csv succeeds + GinkgoT().Logf("Create crd %s so csv %s/%s succeeds", crdAName, nsA, csvAName) cleanupCRD, err := createCRD(c, crd) require.NoError(GinkgoT(), err) defer cleanupCRD() @@ -468,8 +472,8 @@ var _ = Describe("Operator Group", func() { _, err = fetchCSV(crc, csvA.GetName(), nsA, csvSucceededChecker) require.NoError(GinkgoT(), err) - // Create a csv for an apiserver depName := genName("hat-server") + GinkgoT().Logf("Create csv %s/%s for an apiserver", nsA, depName) mockGroup := fmt.Sprintf("hats.%s.redhat.com", genName("")) version := "v1alpha1" mockGroupVersion := strings.Join([]string{mockGroup, version}, "/") @@ -531,19 +535,20 @@ var _ = Describe("Operator Group", func() { } csvB.SetName(depName) - // Create the APIService CSV + GinkgoT().Logf("Create the APIService CSV %s/%s", nsA, depName) cleanupCSV, err := createCSV(c, crc, csvB, nsA, false, true) require.NoError(GinkgoT(), err) defer cleanupCSV() + GinkgoT().Logf("Fetch the APIService CSV %s/%s", nsA, depName) _, err = fetchCSV(crc, csvB.GetName(), nsA, csvSucceededChecker) require.NoError(GinkgoT(), err) - // Ensure clusterroles created and aggregated for access provided APIs + GinkgoT().Logf("Ensure clusterroles created and aggregated for access provided APIs") padmin, cleanupPadmin := createProjectAdmin(GinkgoT(), c, nsA) defer cleanupPadmin() - // Check CRD access aggregated + GinkgoT().Logf("Check CRD access aggregated") err = wait.Poll(pollInterval, pollDuration, func() (bool, error) { res, err := c.KubernetesInterface().AuthorizationV1().SubjectAccessReviews().Create(context.TODO(), &authorizationv1.SubjectAccessReview{ Spec: authorizationv1.SubjectAccessReviewSpec{ @@ -568,7 +573,7 @@ var _ = Describe("Operator Group", func() { }) require.NoError(GinkgoT(), err) - // Check apiserver access aggregated + GinkgoT().Logf("Check apiserver access aggregated") err = wait.Poll(pollInterval, pollDuration, func() (bool, error) { res, err := c.KubernetesInterface().AuthorizationV1().SubjectAccessReviews().Create(context.TODO(), &authorizationv1.SubjectAccessReview{ Spec: authorizationv1.SubjectAccessReviewSpec{ diff --git a/test/e2e/util.go b/test/e2e/util.go index 1764292bf6..ee5aa47c22 100644 --- a/test/e2e/util.go +++ b/test/e2e/util.go @@ -346,7 +346,7 @@ func catalogSourceRegistryPodSynced(catalog *operatorsv1alpha1.CatalogSource) bo if connState != nil { state = connState.LastObservedState } - fmt.Printf("waiting for catalog pod %v to be available (for sync) - %s\n", catalog.GetName(), state) + fmt.Printf("waiting for catalog pod %s/%s to be available (for sync) - %s\n", catalog.GetNamespace(), catalog.GetName(), state) return false }