Skip to content

Commit b5d7478

Browse files
Refactor manager container customizer
Signed-off-by: alexander-demicev <alexandr.demicev@suse.com>
1 parent 5f3445c commit b5d7478

File tree

3 files changed

+91
-40
lines changed

3 files changed

+91
-40
lines changed

internal/controller/component_customizer.go

Lines changed: 31 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,10 @@ import (
3535
)
3636

3737
const (
38-
deploymentKind = "Deployment"
39-
namespaceKind = "Namespace"
4038
managerContainerName = "manager"
4139
defaultVerbosity = 1
4240
)
4341

44-
var bool2Str = map[bool]string{true: "true", false: "false"}
45-
4642
// customizeObjectsFn apply provider specific customization to a list of manifests.
4743
func customizeObjectsFn(provider operatorv1.GenericProvider) func(objs []unstructured.Unstructured) ([]unstructured.Unstructured, error) {
4844
return func(objs []unstructured.Unstructured) ([]unstructured.Unstructured, error) {
@@ -213,20 +209,31 @@ func customizeManagerContainer(mSpec *operatorv1.ManagerSpec, c *corev1.Containe
213209
c.Args = setArgs(c.Args, "--max-concurrent-reconciles", fmt.Sprint(mSpec.MaxConcurrentReconciles))
214210
}
215211

216-
if mSpec.CacheNamespace != "" {
217-
// This field seems somewhat in conflict with:
218-
// The `ContainerSpec.Args` will ignore the key `namespace` since the operator
219-
// enforces a deployment model where all the providers should be configured to
220-
// watch all the namespaces.
221-
c.Args = setArgs(c.Args, "--namespace", mSpec.CacheNamespace)
212+
// Data-driven string field → CLI arg mappings.
213+
// NOTE: CacheNamespace maps to --namespace, which may conflict with the operator's
214+
// deployment model where providers watch all namespaces. The ContainerSpec.Args
215+
// will ignore the key "namespace" for this reason.
216+
stringArgMappings := []struct {
217+
arg, value string
218+
}{
219+
{"--namespace", mSpec.CacheNamespace},
220+
{"--health-addr", mSpec.Health.HealthProbeBindAddress},
221+
{"--metrics-bind-addr", mSpec.Metrics.BindAddress},
222+
{"--diagnostics-address", mSpec.Metrics.DiagnosticsAddress},
223+
{"--webhook-host", mSpec.Webhook.Host},
224+
{"--webhook-cert-dir", mSpec.Webhook.CertDir},
225+
{"--profiler-address", mSpec.ProfilerAddress},
226+
}
227+
228+
for _, m := range stringArgMappings {
229+
if m.value != "" {
230+
c.Args = setArgs(c.Args, m.arg, m.value)
231+
}
222232
}
223233

224234
// TODO can't find an arg for GracefulShutdownTimeout
225235

226-
if mSpec.Health.HealthProbeBindAddress != "" {
227-
c.Args = setArgs(c.Args, "--health-addr", mSpec.Health.HealthProbeBindAddress)
228-
}
229-
236+
// Health probe endpoints
230237
if mSpec.Health.LivenessEndpointName != "" && c.LivenessProbe != nil && c.LivenessProbe.HTTPGet != nil {
231238
c.LivenessProbe.HTTPGet.Path = "/" + mSpec.Health.LivenessEndpointName
232239
}
@@ -235,48 +242,32 @@ func customizeManagerContainer(mSpec *operatorv1.ManagerSpec, c *corev1.Containe
235242
c.ReadinessProbe.HTTPGet.Path = "/" + mSpec.Health.ReadinessEndpointName
236243
}
237244

245+
// Leader election
238246
if mSpec.LeaderElection != nil && mSpec.LeaderElection.LeaderElect != nil {
239247
c.Args = leaderElectionArgs(mSpec.LeaderElection, c.Args)
240248
}
241249

242-
// metrics
243-
if mSpec.Metrics.BindAddress != "" {
244-
c.Args = setArgs(c.Args, "--metrics-bind-addr", mSpec.Metrics.BindAddress)
245-
}
246-
247-
if mSpec.Metrics.DiagnosticsAddress != "" {
248-
c.Args = setArgs(c.Args, "--diagnostics-address", mSpec.Metrics.DiagnosticsAddress)
249-
}
250-
250+
// Only pass --insecure-diagnostics when true. Some providers (e.g. CAPO) do not
251+
// register this flag via AddManagerOptions, and passing it unconditionally causes
252+
// those providers to fail on startup.
251253
if mSpec.Metrics.InsecureDiagnostics {
252-
c.Args = setArgs(c.Args, "--insecure-diagnostics", strconv.FormatBool(mSpec.Metrics.InsecureDiagnostics))
253-
}
254-
255-
// webhooks
256-
if mSpec.Webhook.Host != "" {
257-
c.Args = setArgs(c.Args, "--webhook-host", mSpec.Webhook.Host)
254+
c.Args = setArgs(c.Args, "--insecure-diagnostics", "true")
258255
}
259256

257+
// Webhook port (pointer field requires separate handling)
260258
if mSpec.Webhook.Port != nil {
261259
c.Args = setArgs(c.Args, "--webhook-port", fmt.Sprint(*mSpec.Webhook.Port))
262260
}
263261

264-
if mSpec.Webhook.CertDir != "" {
265-
c.Args = setArgs(c.Args, "--webhook-cert-dir", mSpec.Webhook.CertDir)
266-
}
267-
268-
// top level fields
262+
// Sync period (duration conversion)
269263
if mSpec.SyncPeriod != nil {
270264
syncPeriod := int(mSpec.SyncPeriod.Duration.Round(time.Second).Seconds())
271265
if syncPeriod > 0 {
272266
c.Args = setArgs(c.Args, "--sync-period", fmt.Sprintf("%ds", syncPeriod))
273267
}
274268
}
275269

276-
if mSpec.ProfilerAddress != "" {
277-
c.Args = setArgs(c.Args, "--profiler-address", mSpec.ProfilerAddress)
278-
}
279-
270+
// Verbosity (only override when non-default)
280271
if mSpec.Verbosity != defaultVerbosity {
281272
c.Args = setArgs(c.Args, "--v", fmt.Sprint(mSpec.Verbosity))
282273
}
@@ -292,7 +283,7 @@ func customizeManagerContainer(mSpec *operatorv1.ManagerSpec, c *corev1.Containe
292283

293284
fgValue := make([]string, 0, len(mergedGates))
294285
for fg, val := range mergedGates {
295-
fgValue = append(fgValue, fg+"="+bool2Str[val])
286+
fgValue = append(fgValue, fg+"="+strconv.FormatBool(val))
296287
}
297288

298289
sort.Strings(fgValue)
@@ -400,7 +391,7 @@ func removeEnv(envs []corev1.EnvVar, name string) []corev1.EnvVar {
400391

401392
// leaderElectionArgs set leader election flags.
402393
func leaderElectionArgs(lec *configv1alpha1.LeaderElectionConfiguration, args []string) []string {
403-
args = setArgs(args, "--leader-elect", bool2Str[*lec.LeaderElect])
394+
args = setArgs(args, "--leader-elect", strconv.FormatBool(*lec.LeaderElect))
404395

405396
if *lec.LeaderElect {
406397
if lec.ResourceName != "" && lec.ResourceNamespace != "" {

internal/controller/component_customizer_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,61 @@ func TestCustomizeMultipleDeployment(t *testing.T) {
798798
}
799799
}
800800

801+
func TestInsecureDiagnostics(t *testing.T) {
802+
baseContainer := func() corev1.Container {
803+
return corev1.Container{
804+
Name: "manager",
805+
Image: "registry.k8s.io/a-manager:1.6.2",
806+
Args: []string{},
807+
}
808+
}
809+
810+
t.Run("not set when false (default)", func(t *testing.T) {
811+
c := baseContainer()
812+
mSpec := &operatorv1.ManagerSpec{
813+
ControllerManagerConfiguration: operatorv1.ControllerManagerConfiguration{
814+
Metrics: operatorv1.ControllerMetrics{InsecureDiagnostics: false},
815+
},
816+
}
817+
818+
if err := customizeManagerContainer(mSpec, &c); err != nil {
819+
t.Fatalf("customizeManagerContainer failed: %v", err)
820+
}
821+
822+
for _, arg := range c.Args {
823+
if len(arg) >= 21 && arg[:21] == "--insecure-diagnostics" {
824+
t.Errorf("expected --insecure-diagnostics to be absent when false, but got %q", arg)
825+
}
826+
}
827+
})
828+
829+
t.Run("set to true when enabled", func(t *testing.T) {
830+
c := baseContainer()
831+
mSpec := &operatorv1.ManagerSpec{
832+
ControllerManagerConfiguration: operatorv1.ControllerManagerConfiguration{
833+
Metrics: operatorv1.ControllerMetrics{InsecureDiagnostics: true},
834+
},
835+
}
836+
837+
if err := customizeManagerContainer(mSpec, &c); err != nil {
838+
t.Fatalf("customizeManagerContainer failed: %v", err)
839+
}
840+
841+
found := false
842+
843+
for _, arg := range c.Args {
844+
if arg == "--insecure-diagnostics=true" {
845+
found = true
846+
break
847+
}
848+
}
849+
850+
if !found {
851+
t.Errorf("expected --insecure-diagnostics=true in args, got %v", c.Args)
852+
}
853+
})
854+
}
855+
801856
func TestParseFeatureGates(t *testing.T) {
802857
tests := []struct {
803858
name string

internal/controller/consts.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,9 @@ package controller
1919
const (
2020
// configPath is the path to the clusterctl config file.
2121
configPath = "/config/clusterctl.yaml"
22+
23+
// Kubernetes resource kind constants used across controller files.
24+
deploymentKind = "Deployment"
25+
daemonSetKind = "DaemonSet"
26+
namespaceKind = "Namespace"
2227
)

0 commit comments

Comments
 (0)