Skip to content

Commit 515ab8b

Browse files
(helm/v2alpha): ensure that args are obtained and used in the helm charts
1 parent 72d4edb commit 515ab8b

File tree

14 files changed

+203
-6
lines changed

14 files changed

+203
-6
lines changed

docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/manager/manager.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ spec:
2424
containers:
2525
- args:
2626
- --metrics-bind-address=:8443
27-
- --leader-elect
2827
- --health-probe-bind-address=:8081
28+
{{- range .Values.controllerManager.args }}
29+
- {{ . }}
30+
{{- end }}
2931
{{- if and .Values.certManager.enable .Values.metrics.enable }}
3032
- --metrics-cert-path=/tmp/k8s-metrics-server/metrics-certs
3133
{{- end }}

docs/book/src/cronjob-tutorial/testdata/project/dist/chart/values.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ controllerManager:
77
tag: latest
88
pullPolicy: IfNotPresent
99

10+
# Arguments for the manager
11+
args:
12+
- --leader-elect
13+
1014
# Environment variables
1115
env: []
1216

docs/book/src/getting-started/testdata/project/dist/chart/templates/manager/manager.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ spec:
2424
containers:
2525
- args:
2626
- --metrics-bind-address=:8443
27-
- --leader-elect
2827
- --health-probe-bind-address=:8081
28+
{{- range .Values.controllerManager.args }}
29+
- {{ . }}
30+
{{- end }}
2931
command:
3032
- /manager
3133
image: "{{ .Values.controllerManager.image.repository }}:{{ .Values.controllerManager.image.tag }}"

docs/book/src/getting-started/testdata/project/dist/chart/values.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ controllerManager:
77
tag: latest
88
pullPolicy: IfNotPresent
99

10+
# Arguments for the manager
11+
args:
12+
- --leader-elect
13+
1014
# Environment variables
1115
env: []
1216

docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/manager/manager.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ spec:
2424
containers:
2525
- args:
2626
- --metrics-bind-address=:8443
27-
- --leader-elect
2827
- --health-probe-bind-address=:8081
28+
{{- range .Values.controllerManager.args }}
29+
- {{ . }}
30+
{{- end }}
2931
{{- if and .Values.certManager.enable .Values.metrics.enable }}
3032
- --metrics-cert-path=/tmp/k8s-metrics-server/metrics-certs
3133
{{- end }}

docs/book/src/multiversion-tutorial/testdata/project/dist/chart/values.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ controllerManager:
77
tag: latest
88
pullPolicy: IfNotPresent
99

10+
# Arguments for the manager
11+
args:
12+
- --leader-elect
13+
1014
# Environment variables
1115
env: []
1216

pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/chart_converter.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package kustomize
1818

1919
import (
2020
"fmt"
21+
"strings"
2122

2223
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
2324

@@ -141,6 +142,32 @@ func (c *ChartConverter) ExtractDeploymentConfig() map[string]interface{} {
141142
}
142143
}
143144

145+
// Extract container arguments
146+
if args, argsFound, argsErr := unstructured.NestedFieldNoCopy(firstContainer, "args"); argsFound && argsErr == nil {
147+
if argsList, argsOk := args.([]interface{}); argsOk && len(argsList) > 0 {
148+
filteredArgs := make([]interface{}, 0, len(argsList))
149+
for _, rawArg := range argsList {
150+
strArg, ok := rawArg.(string)
151+
if !ok {
152+
filteredArgs = append(filteredArgs, rawArg)
153+
continue
154+
}
155+
156+
if strings.Contains(strArg, "--metrics-bind-address") ||
157+
strings.Contains(strArg, "--health-probe-bind-address") ||
158+
strings.Contains(strArg, "--webhook-cert-path") ||
159+
strings.Contains(strArg, "--metrics-cert-path") {
160+
continue
161+
}
162+
filteredArgs = append(filteredArgs, strArg)
163+
}
164+
165+
if len(filteredArgs) > 0 {
166+
config["args"] = filteredArgs
167+
}
168+
}
169+
}
170+
144171
// Extract resources
145172
if resources, resFound, resErr := unstructured.NestedFieldNoCopy(firstContainer,
146173
"resources"); resFound && resErr == nil {

pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/chart_converter_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,13 @@ var _ = Describe("ChartConverter", func() {
131131
map[string]interface{}{
132132
"name": "manager",
133133
"image": "controller:latest",
134+
"args": []interface{}{
135+
"--metrics-bind-address=:8443",
136+
"--leader-elect",
137+
"--custom-flag=value",
138+
"--health-probe-bind-address=:8081",
139+
"--webhook-cert-path=/tmp/k8s-webhook-server/serving-certs",
140+
},
134141
"env": []interface{}{
135142
map[string]interface{}{
136143
"name": "TEST_ENV",
@@ -158,6 +165,14 @@ var _ = Describe("ChartConverter", func() {
158165
Expect(config).NotTo(BeNil())
159166
Expect(config).To(HaveKey("env"))
160167
Expect(config).To(HaveKey("resources"))
168+
Expect(config).To(HaveKey("args"))
169+
170+
args, ok := config["args"].([]interface{})
171+
Expect(ok).To(BeTrue())
172+
Expect(args).To(ContainElement("--leader-elect"))
173+
Expect(args).To(ContainElement("--custom-flag=value"))
174+
Expect(args).NotTo(ContainElement("--metrics-bind-address=:8443"))
175+
Expect(args).NotTo(ContainElement("--health-probe-bind-address=:8081"))
161176
})
162177

163178
It("should handle deployment without containers", func() {

pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/helm_templater.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ func (t *HelmTemplater) templateDeploymentFields(yamlContent string) string {
224224
yamlContent = t.templateSecurityContexts(yamlContent)
225225
yamlContent = t.templateVolumeMounts(yamlContent)
226226
yamlContent = t.templateVolumes(yamlContent)
227+
yamlContent = t.templateControllerManagerArgs(yamlContent)
227228

228229
return yamlContent
229230
}
@@ -263,6 +264,90 @@ func (t *HelmTemplater) templateVolumes(yamlContent string) string {
263264
return yamlContent
264265
}
265266

267+
// templateControllerManagerArgs exposes controller manager args via values.yaml while keeping core defaults
268+
func (t *HelmTemplater) templateControllerManagerArgs(yamlContent string) string {
269+
if !strings.Contains(yamlContent, "name: manager") {
270+
return yamlContent
271+
}
272+
273+
argsPattern := regexp.MustCompile(`(?m)([ \t]+)args:\n((?:[ \t]+-.*\n)+)`)
274+
loc := argsPattern.FindStringSubmatchIndex(yamlContent)
275+
if loc == nil {
276+
return yamlContent
277+
}
278+
279+
match := yamlContent[loc[0]:loc[1]]
280+
if strings.Contains(match, ".Values.controllerManager.args") {
281+
return yamlContent
282+
}
283+
284+
indent := yamlContent[loc[2]:loc[3]]
285+
itemsBlock := yamlContent[loc[4]:loc[5]]
286+
287+
itemIndent := indent + " "
288+
lines := strings.Split(itemsBlock, "\n")
289+
var (
290+
metricsLine string
291+
healthLine string
292+
preservedLines []string
293+
)
294+
295+
for _, rawLine := range lines {
296+
line := strings.TrimRight(rawLine, "\r")
297+
trimmed := strings.TrimSpace(line)
298+
if trimmed == "" {
299+
continue
300+
}
301+
302+
if itemIndent == indent+" " {
303+
if idx := strings.Index(line, "-"); idx > 0 {
304+
itemIndent = line[:idx]
305+
}
306+
}
307+
308+
switch {
309+
case strings.Contains(trimmed, "--metrics-bind-address"):
310+
metricsLine = line
311+
case strings.Contains(trimmed, "--health-probe-bind-address"):
312+
healthLine = line
313+
case strings.Contains(trimmed, "--webhook-cert-path"),
314+
strings.Contains(trimmed, "--metrics-cert-path"):
315+
preservedLines = append(preservedLines, line)
316+
default:
317+
// Remaining args will be handled through values.yaml
318+
}
319+
}
320+
321+
var builder strings.Builder
322+
builder.WriteString(indent)
323+
builder.WriteString("args:\n")
324+
325+
if metricsLine != "" {
326+
builder.WriteString(metricsLine)
327+
builder.WriteString("\n")
328+
}
329+
if healthLine != "" {
330+
builder.WriteString(healthLine)
331+
builder.WriteString("\n")
332+
}
333+
334+
builder.WriteString(itemIndent)
335+
builder.WriteString("{{- range .Values.controllerManager.args }}\n")
336+
builder.WriteString(itemIndent)
337+
builder.WriteString("- {{ . }}\n")
338+
builder.WriteString(itemIndent)
339+
builder.WriteString("{{- end }}\n")
340+
341+
for _, line := range preservedLines {
342+
builder.WriteString(line)
343+
builder.WriteString("\n")
344+
}
345+
346+
newBlock := strings.TrimRight(builder.String(), "\n") + "\n"
347+
348+
return yamlContent[:loc[0]] + newBlock + yamlContent[loc[1]:]
349+
}
350+
266351
// templateImageReference converts hardcoded image references to Helm templates
267352
func (t *HelmTemplater) templateImageReference(yamlContent string) string {
268353
// Replace hardcoded controller image with Helm template

pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/helm_templater_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,22 @@ spec:
111111
spec:
112112
containers:
113113
- args:
114+
- --metrics-bind-address=:8443
115+
- --health-probe-bind-address=:8081
114116
- --webhook-cert-path=/tmp/k8s-webhook-server/serving-certs/tls.crt
115117
- --metrics-cert-path=/tmp/k8s-metrics-server/metrics-certs/tls.crt
116118
- --leader-elect
117119
name: manager`
118120

119121
result := templater.ApplyHelmSubstitutions(content, deploymentResource)
120122

123+
// Should expose args through values.yaml templating
124+
Expect(result).To(ContainSubstring("- --metrics-bind-address=:8443"))
125+
Expect(result).To(ContainSubstring("- --health-probe-bind-address=:8081"))
126+
Expect(result).To(ContainSubstring("{{- range .Values.controllerManager.args }}"))
127+
Expect(result).To(ContainSubstring("- {{ . }}"))
128+
Expect(result).To(ContainSubstring("{{- end }}"))
129+
121130
// Should have proper conditional formatting for webhook cert path
122131
Expect(result).To(ContainSubstring("{{- if .Values.certManager.enable }}"))
123132
Expect(result).To(ContainSubstring("- --webhook-cert-path=/tmp/k8s-webhook-server/serving-certs/tls.crt"))

0 commit comments

Comments
 (0)