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