github.com/operator-framework/operator-lifecycle-manager@v0.30.0/pkg/controller/operators/openshift/options.go (about) 1 package openshift 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 "time" 8 9 "github.com/go-logr/logr" 10 configv1 "github.com/openshift/api/config/v1" 11 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 12 "k8s.io/apimachinery/pkg/runtime" 13 "k8s.io/apimachinery/pkg/types" 14 ctrl "sigs.k8s.io/controller-runtime" 15 "sigs.k8s.io/controller-runtime/pkg/builder" 16 "sigs.k8s.io/controller-runtime/pkg/client" 17 "sigs.k8s.io/controller-runtime/pkg/handler" 18 "sigs.k8s.io/controller-runtime/pkg/predicate" 19 "sigs.k8s.io/controller-runtime/pkg/reconcile" 20 21 operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1" 22 olmversion "github.com/operator-framework/operator-lifecycle-manager/pkg/version" 23 ) 24 25 type NowFunc func() metav1.Time 26 27 type ReconcilerConfig struct { 28 Client client.Client 29 Scheme *runtime.Scheme 30 Log logr.Logger 31 RequeueDelay time.Duration 32 TweakBuilder func(*builder.Builder) *builder.Builder 33 Now NowFunc 34 35 Name string 36 Namespace string 37 SyncCh <-chan error 38 TargetVersions []configv1.OperandVersion 39 40 Mutator Mutator 41 } 42 43 type ReconcilerOption func(*ReconcilerConfig) 44 45 func (c *ReconcilerConfig) apply(opts []ReconcilerOption) { 46 for _, opt := range opts { 47 opt(c) 48 } 49 } 50 51 func (c *ReconcilerConfig) complete() error { 52 if c.Client == nil { 53 return fmt.Errorf("no client specified") 54 } 55 if c.Name == "" { 56 return fmt.Errorf("no ClusterOperator name specified") 57 } 58 if c.Log.GetSink() == nil { 59 c.Log = ctrl.Log.WithName(c.Name) 60 } 61 if c.Now == nil { 62 c.Now = NowFunc(metav1.Now) 63 } 64 if c.Scheme == nil { 65 c.Scheme = runtime.NewScheme() 66 } 67 if c.RequeueDelay == 0 { 68 c.RequeueDelay = time.Second * 5 69 } 70 if err := AddToScheme(c.Scheme); err != nil { 71 return err 72 } 73 74 if len(c.TargetVersions) < 1 { 75 c.TargetVersions = []configv1.OperandVersion{ 76 { 77 Name: "operator", 78 Version: os.Getenv("RELEASE_VERSION"), 79 }, 80 { 81 Name: c.Name, 82 Version: olmversion.OLMVersion, 83 }, 84 } 85 } 86 87 return nil 88 } 89 90 func (c *ReconcilerConfig) mapClusterOperator(_ context.Context, _ client.Object) []reconcile.Request { 91 // Enqueue the cluster operator 92 return []reconcile.Request{ 93 {NamespacedName: types.NamespacedName{Name: c.Name}}, 94 } 95 } 96 97 func WithClient(cli client.Client) ReconcilerOption { 98 return func(config *ReconcilerConfig) { 99 config.Client = cli 100 } 101 } 102 103 func WithScheme(scheme *runtime.Scheme) ReconcilerOption { 104 return func(config *ReconcilerConfig) { 105 config.Scheme = scheme 106 } 107 } 108 109 func WithName(name string) ReconcilerOption { 110 return func(config *ReconcilerConfig) { 111 config.Name = name 112 } 113 } 114 115 func WithNamespace(namespace string) ReconcilerOption { 116 return func(config *ReconcilerConfig) { 117 config.Namespace = namespace 118 } 119 } 120 121 func WithSyncChannel(syncCh <-chan error) ReconcilerOption { 122 return func(config *ReconcilerConfig) { 123 config.SyncCh = syncCh 124 } 125 } 126 127 func WithNow(now NowFunc) ReconcilerOption { 128 return func(config *ReconcilerConfig) { 129 config.Now = now 130 } 131 } 132 133 func WithLog(log logr.Logger) ReconcilerOption { 134 return func(config *ReconcilerConfig) { 135 config.Log = log 136 } 137 } 138 139 func WithTargetVersions(targetVersions ...configv1.OperandVersion) ReconcilerOption { 140 return func(config *ReconcilerConfig) { 141 config.TargetVersions = targetVersions 142 } 143 } 144 145 func WithOLMOperator() ReconcilerOption { 146 return func(config *ReconcilerConfig) { 147 var mutations SerialMutations 148 if config.Mutator != nil { 149 mutations = append(mutations, config.Mutator) 150 } 151 152 mutations = append(mutations, MutateFunc(func(ctx context.Context, co *ClusterOperator) error { 153 refs, err := olmOperatorRelatedObjects(ctx, config.Client, config.Namespace) 154 if len(refs) > 0 { 155 // Set any refs we found, regardless of any errors encountered (best effort) 156 co.Status.RelatedObjects = refs 157 } 158 159 return err 160 })) 161 config.Mutator = mutations 162 163 enqueue := handler.EnqueueRequestsFromMapFunc(config.mapClusterOperator) 164 165 originalCSV := predicate.NewPredicateFuncs(func(obj client.Object) bool { 166 csv, ok := obj.(*operatorsv1alpha1.ClusterServiceVersion) 167 if !ok { 168 // Not a CSV, throw out 169 return false 170 } 171 172 return !csv.IsCopied() // Keep original CSVs only 173 }) 174 config.TweakBuilder = func(bldr *builder.Builder) *builder.Builder { 175 return bldr.Watches(&operatorsv1alpha1.ClusterServiceVersion{}, enqueue, builder.WithPredicates(originalCSV)) 176 } 177 } 178 }