@@ -10,7 +10,6 @@ import (
1010 api "github.com/open-feature/open-feature-operator/apis/core/v1beta1"
1111 apicommon "github.com/open-feature/open-feature-operator/apis/core/v1beta1/common"
1212 "github.com/open-feature/open-feature-operator/common"
13- "github.com/open-feature/open-feature-operator/common/constant"
1413 "github.com/open-feature/open-feature-operator/common/flagdproxy"
1514 "github.com/open-feature/open-feature-operator/common/types"
1615 "github.com/open-feature/open-feature-operator/common/utils"
@@ -46,7 +45,7 @@ type FlagdContainerInjector struct {
4645 Client client.Client
4746 Logger logr.Logger
4847 FlagdProxyConfig * flagdproxy.FlagdProxyConfiguration
49- FlagDResourceRequirements corev1.ResourceRequirements
48+ FlagdResourceRequirements corev1.ResourceRequirements
5049 Image string
5150 Tag string
5251}
@@ -63,8 +62,8 @@ func (fi *FlagdContainerInjector) InjectFlagd(
6362
6463 // Enable probes
6564 if flagSourceConfig .ProbesEnabled != nil && * flagSourceConfig .ProbesEnabled {
66- flagdContainer .LivenessProbe = buildProbe (constant .ProbeLiveness , int (flagSourceConfig .ManagementPort ))
67- flagdContainer .ReadinessProbe = buildProbe (constant .ProbeReadiness , int (flagSourceConfig .ManagementPort ))
65+ flagdContainer .LivenessProbe = buildProbe (common .ProbeLiveness , int (flagSourceConfig .ManagementPort ))
66+ flagdContainer .ReadinessProbe = buildProbe (common .ProbeReadiness , int (flagSourceConfig .ManagementPort ))
6867 }
6968
7069 if err := fi .handleSidecarSources (ctx , objectMeta , podSpec , flagSourceConfig , & flagdContainer ); err != nil {
@@ -128,48 +127,63 @@ func (fi *FlagdContainerInjector) InjectFlagd(
128127// service account under the given namespace (required for kubernetes sync provider)
129128func (fi * FlagdContainerInjector ) EnableClusterRoleBinding (ctx context.Context , namespace , serviceAccountName string ) error {
130129 serviceAccount := client.ObjectKey {
131- Name : serviceAccountName ,
130+ Name : determineServiceAccountName ( serviceAccountName ) ,
132131 Namespace : namespace ,
133132 }
134- if serviceAccountName == "" {
135- serviceAccount .Name = "default"
136- }
133+
137134 // Check if the service account exists
138135 fi .Logger .V (1 ).Info (fmt .Sprintf ("Fetching serviceAccount: %s/%s" , serviceAccount .Namespace , serviceAccount .Name ))
139136 sa := corev1.ServiceAccount {}
140137 if err := fi .Client .Get (ctx , serviceAccount , & sa ); err != nil {
141138 fi .Logger .V (1 ).Info (fmt .Sprintf ("ServiceAccount not found: %s/%s" , serviceAccount .Namespace , serviceAccount .Name ))
142139 return err
143140 }
144- fi .Logger .V (1 ).Info (fmt .Sprintf ("Fetching clusterrolebinding: %s" , constant .ClusterRoleBindingName ))
141+
142+ fi .Logger .V (1 ).Info (fmt .Sprintf ("Fetching clusterrolebinding: %s" , common .ClusterRoleBindingName ))
145143 // Fetch service account if it exists
146144 crb := rbacv1.ClusterRoleBinding {}
147- if err := fi .Client .Get (ctx , client.ObjectKey {Name : constant .ClusterRoleBindingName }, & crb ); errors .IsNotFound (err ) {
148- fi .Logger .V (1 ).Info (fmt .Sprintf ("ClusterRoleBinding not found: %s" , constant .ClusterRoleBindingName ))
145+ if err := fi .Client .Get (ctx , client.ObjectKey {Name : common .ClusterRoleBindingName }, & crb ); errors .IsNotFound (err ) {
146+ fi .Logger .V (1 ).Info (fmt .Sprintf ("ClusterRoleBinding not found: %s" , common .ClusterRoleBindingName ))
149147 return err
150148 }
151- found := false
149+
150+ if ! fi .isServiceAccountSet (& crb , serviceAccount ) {
151+ return fi .updateServiceAccount (ctx , & crb , serviceAccount )
152+ }
153+
154+ return nil
155+ }
156+
157+ func determineServiceAccountName (name string ) string {
158+ if name == "" {
159+ return "default"
160+ }
161+ return name
162+ }
163+
164+ func (fi * FlagdContainerInjector ) isServiceAccountSet (crb * rbacv1.ClusterRoleBinding , serviceAccount client.ObjectKey ) bool {
152165 for _ , subject := range crb .Subjects {
153166 if subject .Kind == "ServiceAccount" && subject .Name == serviceAccount .Name && subject .Namespace == serviceAccount .Namespace {
154167 fi .Logger .V (1 ).Info (fmt .Sprintf ("ClusterRoleBinding already exists for service account: %s/%s" , serviceAccount .Namespace , serviceAccount .Name ))
155- found = true
168+ return true
156169 }
157170 }
158- if ! found {
159- fi .Logger .V (1 ).Info (fmt .Sprintf ("Updating ClusterRoleBinding %s for service account: %s/%s" , crb .Name ,
160- serviceAccount .Namespace , serviceAccount .Name ))
161- crb .Subjects = append (crb .Subjects , rbacv1.Subject {
162- Kind : "ServiceAccount" ,
163- Name : serviceAccount .Name ,
164- Namespace : serviceAccount .Namespace ,
165- })
166- if err := fi .Client .Update (ctx , & crb ); err != nil {
167- fi .Logger .V (1 ).Info (fmt .Sprintf ("Failed to update ClusterRoleBinding: %s" , err .Error ()))
168- return err
169- }
171+ return false
172+ }
173+
174+ func (fi * FlagdContainerInjector ) updateServiceAccount (ctx context.Context , crb * rbacv1.ClusterRoleBinding , serviceAccount client.ObjectKey ) error {
175+ fi .Logger .V (1 ).Info (fmt .Sprintf ("Updating ClusterRoleBinding %s for service account: %s/%s" , crb .Name ,
176+ serviceAccount .Namespace , serviceAccount .Name ))
177+ crb .Subjects = append (crb .Subjects , rbacv1.Subject {
178+ Kind : "ServiceAccount" ,
179+ Name : serviceAccount .Name ,
180+ Namespace : serviceAccount .Namespace ,
181+ })
182+ if err := fi .Client .Update (ctx , crb ); err != nil {
183+ fi .Logger .V (1 ).Info (fmt .Sprintf ("Failed to update ClusterRoleBinding: %s" , err .Error ()))
184+ return err
170185 }
171186 fi .Logger .V (1 ).Info (fmt .Sprintf ("Updated ClusterRoleBinding: %s" , crb .Name ))
172-
173187 return nil
174188}
175189
@@ -186,7 +200,6 @@ func (fi *FlagdContainerInjector) handleSidecarSources(ctx context.Context, obje
186200 return nil
187201}
188202
189- //nolint:gocyclo
190203func (fi * FlagdContainerInjector ) buildSources (ctx context.Context , objectMeta * metav1.ObjectMeta , flagSourceConfig * api.FeatureFlagSourceSpec , podSpec * corev1.PodSpec , sidecar * corev1.Container ) ([]types.SourceConfig , error ) {
191204 var sourceCfgCollection []types.SourceConfig
192205
@@ -195,40 +208,40 @@ func (fi *FlagdContainerInjector) buildSources(ctx context.Context, objectMeta *
195208 source .Provider = flagSourceConfig .DefaultSyncProvider
196209 }
197210
198- var sourceCfg types.SourceConfig
199- var err error
200-
201- switch {
202- case source .Provider .IsKubernetes ():
203- sourceCfg , err = fi .toKubernetesProviderConfig (ctx , objectMeta , podSpec , source )
204- if err != nil {
205- return []types.SourceConfig {}, err
206- }
207- case source .Provider .IsFilepath ():
208- sourceCfg , err = fi .toFilepathProviderConfig (ctx , objectMeta , podSpec , sidecar , source )
209- if err != nil {
210- return []types.SourceConfig {}, err
211- }
212- case source .Provider .IsHttp ():
213- sourceCfg = fi .toHttpProviderConfig (source )
214- case source .Provider .IsGrpc ():
215- sourceCfg = fi .toGrpcProviderConfig (source )
216- case source .Provider .IsFlagdProxy ():
217- sourceCfg , err = fi .toFlagdProxyConfig (ctx , objectMeta , source )
218- if err != nil {
219- return []types.SourceConfig {}, err
220- }
221- default :
222- return []types.SourceConfig {}, fmt .Errorf ("could not add provider %s: %w" , source .Provider , constant .ErrUnrecognizedSyncProvider )
211+ sourceCfg , err := fi .newSourceConfig (ctx , source , objectMeta , podSpec , sidecar )
212+ if err != nil {
213+ return []types.SourceConfig {}, err
223214 }
224215
225- sourceCfgCollection = append (sourceCfgCollection , sourceCfg )
216+ sourceCfgCollection = append (sourceCfgCollection , * sourceCfg )
226217
227218 }
228219
229220 return sourceCfgCollection , nil
230221}
231222
223+ func (fi * FlagdContainerInjector ) newSourceConfig (ctx context.Context , source api.Source , objectMeta * metav1.ObjectMeta , podSpec * corev1.PodSpec , sidecar * corev1.Container ) (* types.SourceConfig , error ) {
224+ sourceCfg := types.SourceConfig {}
225+ var err error = nil
226+
227+ switch {
228+ case source .Provider .IsKubernetes ():
229+ sourceCfg , err = fi .toKubernetesProviderConfig (ctx , objectMeta , podSpec , source )
230+ case source .Provider .IsFilepath ():
231+ sourceCfg , err = fi .toFilepathProviderConfig (ctx , objectMeta , podSpec , sidecar , source )
232+ case source .Provider .IsHttp ():
233+ sourceCfg = fi .toHttpProviderConfig (source )
234+ case source .Provider .IsGrpc ():
235+ sourceCfg = fi .toGrpcProviderConfig (source )
236+ case source .Provider .IsFlagdProxy ():
237+ sourceCfg , err = fi .toFlagdProxyConfig (ctx , objectMeta , source )
238+ default :
239+ err = fmt .Errorf ("could not add provider %s: %w" , source .Provider , common .ErrUnrecognizedSyncProvider )
240+ }
241+
242+ return & sourceCfg , err
243+ }
244+
232245func (fi * FlagdContainerInjector ) toFilepathProviderConfig (ctx context.Context , objectMeta * metav1.ObjectMeta , podSpec * corev1.PodSpec , sidecar * corev1.Container , source api.Source ) (types.SourceConfig , error ) {
233246 // create config map
234247 ns , n := utils .ParseAnnotation (source .Source , objectMeta .Namespace )
@@ -312,7 +325,7 @@ func (fi *FlagdContainerInjector) toFlagdProxyConfig(ctx context.Context, object
312325 return types.SourceConfig {}, err
313326 }
314327 if ! exists || (exists && ! ready ) {
315- return types.SourceConfig {}, constant .ErrFlagdProxyNotReady
328+ return types.SourceConfig {}, common .ErrFlagdProxyNotReady
316329 }
317330 ns , n := utils .ParseAnnotation (source .Source , objectMeta .Namespace )
318331 return types.SourceConfig {
@@ -339,7 +352,7 @@ func (fi *FlagdContainerInjector) isFlagdProxyReady(ctx context.Context) (bool,
339352 return true , false , fmt .Errorf (
340353 "flagd-proxy not ready after 3 minutes, was created at %s: %w" ,
341354 d .CreationTimestamp .Time .String (),
342- constant .ErrFlagdProxyNotReady ,
355+ common .ErrFlagdProxyNotReady ,
343356 )
344357 }
345358 return true , false , nil
@@ -365,7 +378,7 @@ func (fi *FlagdContainerInjector) toKubernetesProviderConfig(ctx context.Context
365378 if objectMeta .Annotations == nil {
366379 objectMeta .Annotations = map [string ]string {}
367380 }
368- objectMeta .Annotations [fmt .Sprintf ("%s/%s" , constant .OpenFeatureAnnotationPrefix , constant .AllowKubernetesSyncAnnotation )] = "true"
381+ objectMeta .Annotations [fmt .Sprintf ("%s/%s" , common .OpenFeatureAnnotationPrefix , common .AllowKubernetesSyncAnnotation )] = "true"
369382
370383 // build K8s config
371384 return types.SourceConfig {
@@ -381,7 +394,7 @@ func (fi *FlagdContainerInjector) generateBasicFlagdContainer(flagSourceConfig *
381394 Args : []string {
382395 "start" ,
383396 },
384- ImagePullPolicy : constant . FlagDImagePullPolicy ,
397+ ImagePullPolicy : common . FlagdImagePullPolicy ,
385398 VolumeMounts : []corev1.VolumeMount {},
386399 Env : []corev1.EnvVar {},
387400 Ports : []corev1.ContainerPort {
@@ -391,7 +404,7 @@ func (fi *FlagdContainerInjector) generateBasicFlagdContainer(flagSourceConfig *
391404 },
392405 },
393406 SecurityContext : getSecurityContext (),
394- Resources : fi .FlagDResourceRequirements ,
407+ Resources : fi .FlagdResourceRequirements ,
395408 }
396409}
397410
@@ -437,7 +450,7 @@ func appendSources(sources []types.SourceConfig, sidecar *corev1.Container) erro
437450 return err
438451 }
439452
440- sidecar .Args = append (sidecar .Args , constant .SourceConfigParam , string (bytes ))
453+ sidecar .Args = append (sidecar .Args , common .SourceConfigParam , string (bytes ))
441454 return nil
442455}
443456
@@ -479,6 +492,6 @@ func buildProbe(path string, port int) *corev1.Probe {
479492 ProbeHandler : corev1.ProbeHandler {
480493 HTTPGet : httpGetAction ,
481494 },
482- InitialDelaySeconds : constant .ProbeInitialDelay ,
495+ InitialDelaySeconds : common .ProbeInitialDelay ,
483496 }
484497}
0 commit comments