github.com/operator-framework/operator-lifecycle-manager@v0.30.0/pkg/controller/operators/labeller/rbac.go (about) 1 package labeller 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 8 "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver" 9 "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer" 10 "github.com/sirupsen/logrus" 11 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 12 "k8s.io/apimachinery/pkg/labels" 13 ) 14 15 func hasHashLabel(obj metav1.Object) bool { 16 _, ok := obj.GetLabels()[resolver.ContentHashLabelKey] 17 return ok 18 } 19 20 func ContentHashLabeler[T metav1.Object, A ApplyConfig[A]]( 21 ctx context.Context, 22 logger *logrus.Logger, 23 check func(metav1.Object) bool, 24 hasher func(object T) (string, error), 25 list func(options labels.Selector) ([]T, error), 26 applyConfigFor func(name, namespace string) A, 27 apply func(namespace string, ctx context.Context, cfg A, opts metav1.ApplyOptions) (T, error), 28 ) func(done func() bool) queueinformer.LegacySyncHandler { 29 return func(done func() bool) queueinformer.LegacySyncHandler { 30 return func(obj interface{}) error { 31 cast, ok := obj.(T) 32 if !ok { 33 err := fmt.Errorf("wrong type %T, expected %T: %#v", obj, new(T), obj) 34 logger.WithError(err).Error("casting failed") 35 return fmt.Errorf("casting failed: %w", err) 36 } 37 38 if !check(cast) || hasHashLabel(cast) { 39 // if the object we're processing does not need us to label it, it's possible that every object that requires 40 // the label already has it; in which case we should exit the process, so the Pod that succeeds us can filter 41 // the informers used to drive the controller and stop having to track extraneous objects 42 items, err := list(labels.Everything()) 43 if err != nil { 44 logger.WithError(err).Warn("failed to list all objects to check for labelling completion") 45 return nil 46 } 47 gvrFullyLabelled := true 48 for _, item := range items { 49 gvrFullyLabelled = gvrFullyLabelled && (!check(item) || hasLabel(item)) 50 } 51 if gvrFullyLabelled { 52 allObjectsLabelled := done() 53 if allObjectsLabelled { 54 logrus.Info("detected that every object is labelled, exiting to re-start the process...") 55 os.Exit(0) 56 } 57 } 58 return nil 59 } 60 61 hash, err := hasher(cast) 62 if err != nil { 63 return fmt.Errorf("failed to calculate hash: %w", err) 64 } 65 66 logger.WithFields(logrus.Fields{"namespace": cast.GetNamespace(), "name": cast.GetName()}).Info("applying content hash label") 67 cfg := applyConfigFor(cast.GetName(), cast.GetNamespace()) 68 cfg.WithLabels(map[string]string{ 69 resolver.ContentHashLabelKey: hash, 70 }) 71 _, err = apply(cast.GetNamespace(), ctx, cfg, metav1.ApplyOptions{FieldManager: "olm-hash-labeller"}) 72 return err 73 } 74 } 75 }