Skip to content

Commit

Permalink
*: track and label user-provided service-accounts
Browse files Browse the repository at this point in the history
Signed-off-by: Steve Kuznetsov <skuznets@redhat.com>
  • Loading branch information
stevekuznetsov committed Sep 20, 2023
1 parent fc058f9 commit 340f2a7
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 15 deletions.
15 changes: 13 additions & 2 deletions pkg/controller/operators/catalog/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,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
}
Expand Down Expand Up @@ -490,7 +490,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) {
Expand Down
35 changes: 31 additions & 4 deletions pkg/controller/operators/labeller/filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand Down Expand Up @@ -49,15 +52,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,
Expand All @@ -73,7 +79,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)
Expand All @@ -96,6 +102,27 @@ func Validate(ctx context.Context, logger *logrus.Logger, metadataClient metadat
return previous != nil && previous(object) && ContentHashFilter(object)
}
}

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 {
Expand Down
2 changes: 1 addition & 1 deletion pkg/controller/operators/olm/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,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
}
Expand Down
16 changes: 8 additions & 8 deletions pkg/lib/scoped/syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,6 @@ func (s *UserDefinedServiceAccountSyncer) SyncOperatorGroup(in *v1.OperatorGroup
return
}

// A service account has been specified, but likely does not have the labels we expect it to have so it will
// show up in our listers, so let's add that and queue again later
config := corev1applyconfigurations.ServiceAccount(serviceAccountName, namespace)
config.Labels = map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}
if _, err := s.client.KubernetesInterface().CoreV1().ServiceAccounts(namespace).Apply(context.TODO(), config, metav1.ApplyOptions{FieldManager: "operator-lifecycle-manager"}); err != nil {
return out, fmt.Errorf("failed to apply labels[%s]=%s to serviceaccount %s/%s: %w", install.OLMManagedLabelKey, install.OLMManagedLabelValue, namespace, serviceAccountName, err)
}

// A service account has been specified, we need to update the status.
sa, err := s.client.KubernetesInterface().CoreV1().ServiceAccounts(namespace).Get(context.TODO(), serviceAccountName, metav1.GetOptions{})
if err != nil {
Expand All @@ -108,6 +100,14 @@ func (s *UserDefinedServiceAccountSyncer) SyncOperatorGroup(in *v1.OperatorGroup
return
}

// A service account has been specified, but likely does not have the labels we expect it to have so it will
// show up in our listers, so let's add that and queue again later
config := corev1applyconfigurations.ServiceAccount(serviceAccountName, namespace)
config.Labels = map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}
if _, err := s.client.KubernetesInterface().CoreV1().ServiceAccounts(namespace).Apply(context.TODO(), config, metav1.ApplyOptions{FieldManager: "operator-lifecycle-manager"}); err != nil {
return out, fmt.Errorf("failed to apply labels[%s]=%s to serviceaccount %s/%s: %w", install.OLMManagedLabelKey, install.OLMManagedLabelValue, namespace, serviceAccountName, err)
}

ref, err := reference.GetReference(s.scheme, sa)
if err != nil {
return
Expand Down

0 comments on commit 340f2a7

Please sign in to comment.