From 4201200f3cbe7d8503e66f2aa039a05c97328135 Mon Sep 17 00:00:00 2001 From: Steve Kuznetsov Date: Mon, 11 Sep 2023 07:27:04 -0600 Subject: [PATCH] *: track and label user-provided service-accounts Signed-off-by: Steve Kuznetsov --- pkg/controller/operators/catalog/operator.go | 15 +++++++-- pkg/controller/operators/labeller/filters.go | 33 +++++++++++++++++--- pkg/controller/operators/olm/operator.go | 2 +- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/pkg/controller/operators/catalog/operator.go b/pkg/controller/operators/catalog/operator.go index 0d1adfe257..c61e118466 100644 --- a/pkg/controller/operators/catalog/operator.go +++ b/pkg/controller/operators/catalog/operator.go @@ -186,7 +186,7 @@ func NewOperator(ctx context.Context, kubeconfigPath string, clock utilclock.Clo return nil, err } - canFilter, err := labeller.Validate(ctx, logger, metadataClient) + canFilter, err := labeller.Validate(ctx, logger, metadataClient, crClient) if err != nil { return nil, err } @@ -455,7 +455,18 @@ func NewOperator(ctx context.Context, kubeconfigPath string, clock utilclock.Clo serviceaccountsgvk := corev1.SchemeGroupVersion.WithResource("serviceaccounts") if err := labelObjects(serviceaccountsgvk, serviceAccountInformer.Informer(), labeller.ObjectLabeler[*corev1.ServiceAccount, *corev1applyconfigurations.ServiceAccountApplyConfiguration]( - ctx, op.logger, labeller.Filter(serviceaccountsgvk), + ctx, op.logger, labeller.ServiceAccountFilter(func(namespace, name string) bool { + operatorGroups, err := operatorGroupInformer.Lister().OperatorGroups(namespace).List(labels.Everything()) + if err != nil { + return false + } + for _, operatorGroup := range operatorGroups { + if operatorGroup.Spec.ServiceAccountName == name { + return true + } + } + return false + }), serviceAccountInformer.Lister().List, corev1applyconfigurations.ServiceAccount, func(namespace string, ctx context.Context, cfg *corev1applyconfigurations.ServiceAccountApplyConfiguration, opts metav1.ApplyOptions) (*corev1.ServiceAccount, error) { diff --git a/pkg/controller/operators/labeller/filters.go b/pkg/controller/operators/labeller/filters.go index 5fbdef7c49..993167391e 100644 --- a/pkg/controller/operators/labeller/filters.go +++ b/pkg/controller/operators/labeller/filters.go @@ -6,6 +6,7 @@ import ( "strings" "sync" + operators "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned" "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/reconciler" "github.com/sirupsen/logrus" "golang.org/x/sync/errgroup" @@ -16,6 +17,8 @@ import ( apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/client-go/metadata" "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/internal/alongside" @@ -45,15 +48,18 @@ func JobFilter(getConfigMap func(namespace, name string) (metav1.Object, error)) } } +func ServiceAccountFilter(isServiceAccountReferenced func(namespace, name string) bool) func(object metav1.Object) bool { + return func(object metav1.Object) bool { + return HasOLMOwnerRef(object) || HasOLMLabel(object) || isServiceAccountReferenced(object.GetNamespace(), object.GetName()) + } +} + var filters = map[schema.GroupVersionResource]func(metav1.Object) bool{ corev1.SchemeGroupVersion.WithResource("services"): HasOLMOwnerRef, corev1.SchemeGroupVersion.WithResource("pods"): func(object metav1.Object) bool { _, ok := object.GetLabels()[reconciler.CatalogSourceLabelKey] return ok }, - corev1.SchemeGroupVersion.WithResource("serviceaccounts"): func(object metav1.Object) bool { - return HasOLMOwnerRef(object) || HasOLMLabel(object) - }, appsv1.SchemeGroupVersion.WithResource("deployments"): HasOLMOwnerRef, rbacv1.SchemeGroupVersion.WithResource("roles"): HasOLMOwnerRef, rbacv1.SchemeGroupVersion.WithResource("rolebindings"): HasOLMOwnerRef, @@ -69,7 +75,7 @@ var filters = map[schema.GroupVersionResource]func(metav1.Object) bool{ }, } -func Validate(ctx context.Context, logger *logrus.Logger, metadataClient metadata.Interface) (bool, error) { +func Validate(ctx context.Context, logger *logrus.Logger, metadataClient metadata.Interface, operatorClient operators.Interface) (bool, error) { okLock := sync.Mutex{} ok := true g, ctx := errgroup.WithContext(ctx) @@ -80,6 +86,25 @@ func Validate(ctx context.Context, logger *logrus.Logger, metadataClient metadat allFilters[batchv1.SchemeGroupVersion.WithResource("jobs")] = JobFilter(func(namespace, name string) (metav1.Object, error) { return metadataClient.Resource(corev1.SchemeGroupVersion.WithResource("configmaps")).Namespace(namespace).Get(ctx, name, metav1.GetOptions{}) }) + operatorGroups, err := operatorClient.OperatorsV1().OperatorGroups(metav1.NamespaceAll).List(ctx, metav1.ListOptions{}) + if err != nil { + return false, err + } + userProvidedServiceAccounts := sets.New[types.NamespacedName]() + for _, operatorGroup := range operatorGroups.Items { + if operatorGroup.Spec.ServiceAccountName != "" { + userProvidedServiceAccounts.Insert(types.NamespacedName{ + Namespace: operatorGroup.Namespace, + Name: operatorGroup.Spec.ServiceAccountName, + }) + } + } + allFilters[corev1.SchemeGroupVersion.WithResource("serviceaccounts")] = ServiceAccountFilter(func(namespace, name string) bool { + return userProvidedServiceAccounts.Has(types.NamespacedName{ + Namespace: namespace, + Name: name, + }) + }) for gvr, filter := range allFilters { gvr, filter := gvr, filter g.Go(func() error { diff --git a/pkg/controller/operators/olm/operator.go b/pkg/controller/operators/olm/operator.go index 1eec6fb6fd..e92a904f86 100644 --- a/pkg/controller/operators/olm/operator.go +++ b/pkg/controller/operators/olm/operator.go @@ -142,7 +142,7 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat return nil, err } - canFilter, err := labeller.Validate(ctx, config.logger, config.metadataClient) + canFilter, err := labeller.Validate(ctx, config.logger, config.metadataClient, config.externalClient) if err != nil { return nil, err }