• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kubernetes-sigs / kubebuilder / 20060828660

09 Dec 2025 10:49AM UTC coverage: 60.731% (+0.1%) from 60.633%
20060828660

push

github

web-flow
✨ (go/v4): Upgrade golangci-lint to v2.7.2 and add modernize check (#5258)

add golangci-lint and support modernize lint

Signed-off-by: dongjiang1989 <dongjiang1989@126.com>

80 of 99 new or added lines in 19 files covered. (80.81%)

1 existing line in 1 file now uncovered.

5719 of 9417 relevant lines covered (60.73%)

26.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.6
/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/values_basic.go
1
/*
2
Copyright 2025 The Kubernetes Authors.
3

4
Licensed under the Apache License, Version 2.0 (the "License");
5
you may not use this file except in compliance with the License.
6
You may obtain a copy of the License at
7

8
    http://www.apache.org/licenses/LICENSE-2.0
9

10
Unless required by applicable law or agreed to in writing, software
11
distributed under the License is distributed on an "AS IS" BASIS,
12
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
See the License for the specific language governing permissions and
14
limitations under the License.
15
*/
16

17
package templates
18

19
import (
20
        "bytes"
21
        "fmt"
22
        "path/filepath"
23
        "strings"
24

25
        "go.yaml.in/yaml/v3"
26

27
        "sigs.k8s.io/kubebuilder/v4/pkg/machinery"
28
)
29

30
var _ machinery.Template = &HelmValuesBasic{}
31

32
// HelmValuesBasic scaffolds a basic values.yaml based on detected features
33
type HelmValuesBasic struct {
34
        machinery.TemplateMixin
35
        machinery.ProjectNameMixin
36

37
        // DeploymentConfig stores extracted deployment configuration (env, resources, security contexts)
38
        DeploymentConfig map[string]any
39
        // OutputDir specifies the output directory for the chart
40
        OutputDir string
41
        // Force if true allows overwriting the scaffolded file
42
        Force bool
43
        // HasWebhooks is true when webhooks were found in the config
44
        HasWebhooks bool
45
        // HasMetrics is true when metrics service/monitor were found in the config
46
        HasMetrics bool
47
}
48

49
// SetTemplateDefaults implements machinery.Template
50
func (f *HelmValuesBasic) SetTemplateDefaults() error {
23✔
51
        if f.Path == "" {
46✔
52
                outputDir := f.OutputDir
23✔
53
                if outputDir == "" {
43✔
54
                        outputDir = "dist"
20✔
55
                }
20✔
56
                f.Path = filepath.Join(outputDir, "chart", "values.yaml")
23✔
57
        }
58

59
        f.TemplateBody = f.generateBasicValues()
23✔
60

23✔
61
        if f.Force {
23✔
62
                f.IfExistsAction = machinery.OverwriteFile
×
63
        } else {
23✔
64
                f.IfExistsAction = machinery.SkipFile
23✔
65
        }
23✔
66

67
        return nil
23✔
68
}
69

70
// generateBasicValues creates a basic values.yaml based on detected features
71
func (f *HelmValuesBasic) generateBasicValues() string {
23✔
72
        var buf bytes.Buffer
23✔
73

23✔
74
        // Controller Manager configuration
23✔
75
        imageRepo := "controller"
23✔
76
        imageTag := "latest"
23✔
77
        imagePullPolicy := "IfNotPresent"
23✔
78
        if f.DeploymentConfig != nil {
42✔
79
                if imgCfg, ok := f.DeploymentConfig["image"].(map[string]any); ok {
20✔
80
                        if repo, ok := imgCfg["repository"].(string); ok && repo != "" {
2✔
81
                                imageRepo = repo
1✔
82
                        }
1✔
83
                        if tag, ok := imgCfg["tag"].(string); ok && tag != "" {
2✔
84
                                imageTag = tag
1✔
85
                        }
1✔
86
                        if policy, ok := imgCfg["pullPolicy"].(string); ok && policy != "" {
2✔
87
                                imagePullPolicy = policy
1✔
88
                        }
1✔
89
                }
90
        }
91

92
        buf.WriteString(fmt.Sprintf(`# Configure the controller manager deployment
23✔
93
manager:
23✔
94
  replicas: 1
23✔
95
  
23✔
96
  image:
23✔
97
    repository: %s
23✔
98
    tag: %s
23✔
99
    pullPolicy: %s
23✔
100

23✔
101
`, imageRepo, imageTag, imagePullPolicy))
23✔
102

23✔
103
        // Add extracted deployment configuration
23✔
104
        f.addDeploymentConfig(&buf)
23✔
105

23✔
106
        // RBAC configuration
23✔
107
        buf.WriteString(`# Essential RBAC permissions (required for controller operation)
23✔
108
# These include ServiceAccount, controller permissions, leader election, and metrics access
23✔
109
# Note: Essential RBAC is always enabled as it's required for the controller to function
23✔
110

23✔
111
# Helper RBAC roles for managing custom resources
23✔
112
# These provide convenient admin/editor/viewer roles for each CRD type
23✔
113
# Useful for giving users different levels of access to your custom resources
23✔
114
rbacHelpers:
23✔
115
  enable: false  # Install convenience admin/editor/viewer roles for CRDs
23✔
116

23✔
117
`)
23✔
118

23✔
119
        // CRD configuration
23✔
120
        buf.WriteString(`# Custom Resource Definitions
23✔
121
crd:
23✔
122
  enable: true  # Install CRDs with the chart
23✔
123
  keep: true    # Keep CRDs when uninstalling
23✔
124

23✔
125
`)
23✔
126

23✔
127
        // Metrics configuration (enable if metrics artifacts detected in kustomize output)
23✔
128
        metricsPort := 8443
23✔
129
        if f.DeploymentConfig != nil {
42✔
130
                if mp, ok := f.DeploymentConfig["metricsPort"].(int); ok && mp > 0 {
24✔
131
                        metricsPort = mp
5✔
132
                }
5✔
133
        }
134

135
        if f.HasMetrics {
36✔
136
                buf.WriteString(fmt.Sprintf(`# Controller metrics endpoint.
13✔
137
# Enable to expose /metrics endpoint with RBAC protection.
13✔
138
metrics:
13✔
139
  enable: true
13✔
140
  port: %d  # Metrics server port
13✔
141

13✔
142
`, metricsPort))
13✔
143
        } else {
23✔
144
                buf.WriteString(fmt.Sprintf(`# Controller metrics endpoint.
10✔
145
# Enable to expose /metrics endpoint with RBAC protection.
10✔
146
metrics:
10✔
147
  enable: false
10✔
148
  port: %d  # Metrics server port
10✔
149

10✔
150
`, metricsPort))
10✔
151
        }
10✔
152

153
        // Cert-manager configuration (always present, enabled based on webhooks)
154
        if f.HasWebhooks {
36✔
155
                buf.WriteString(`# Cert-manager integration for TLS certificates.
13✔
156
# Required for webhook certificates and metrics endpoint certificates.
13✔
157
certManager:
13✔
158
  enable: true
13✔
159

13✔
160
`)
13✔
161
        } else {
23✔
162
                buf.WriteString(`# Cert-manager integration for TLS certificates.
10✔
163
# Required for webhook certificates and metrics endpoint certificates.
10✔
164
certManager:
10✔
165
  enable: false
10✔
166

10✔
167
`)
10✔
168
        }
10✔
169

170
        // Webhook configuration - only if webhooks are present
171
        if f.HasWebhooks {
36✔
172
                webhookPort := 9443
13✔
173
                if f.DeploymentConfig != nil {
26✔
174
                        if wp, ok := f.DeploymentConfig["webhookPort"].(int); ok && wp > 0 {
16✔
175
                                webhookPort = wp
3✔
176
                        }
3✔
177
                }
178

179
                buf.WriteString(fmt.Sprintf(`# Webhook server configuration
13✔
180
webhook:
13✔
181
  enable: true
13✔
182
  port: %d  # Webhook server port
13✔
183

13✔
184
`, webhookPort))
13✔
185
        }
186

187
        // Prometheus configuration
188
        buf.WriteString(`# Prometheus ServiceMonitor for metrics scraping.
23✔
189
# Requires prometheus-operator to be installed in the cluster.
23✔
190
prometheus:
23✔
191
  enable: false
23✔
192
`)
23✔
193

23✔
194
        buf.WriteString("\n")
23✔
195
        return buf.String()
23✔
196
}
197

198
// addDeploymentConfig adds extracted deployment configuration to the values
199
func (f *HelmValuesBasic) addDeploymentConfig(buf *bytes.Buffer) {
23✔
200
        f.addArgsSection(buf)
23✔
201

23✔
202
        if f.DeploymentConfig == nil {
27✔
203
                // Add default sections with examples
4✔
204
                f.addDefaultDeploymentSections(buf)
4✔
205
                return
4✔
206
        }
4✔
207

208
        // Add environment variables if they exist
209
        if env, exists := f.DeploymentConfig["env"]; exists && env != nil {
21✔
210
                buf.WriteString("  # Environment variables\n")
2✔
211
                buf.WriteString("  env:\n")
2✔
212
                if envYaml, err := yaml.Marshal(env); err == nil {
4✔
213
                        // Indent the YAML properly
2✔
214
                        lines := bytes.SplitSeq(envYaml, []byte("\n"))
2✔
215
                        for line := range lines {
10✔
216
                                if len(line) > 0 {
14✔
217
                                        buf.WriteString("    ")
6✔
218
                                        buf.Write(line)
6✔
219
                                        buf.WriteString("\n")
6✔
220
                                }
6✔
221
                        }
222
                } else {
×
223
                        buf.WriteString("    []\n")
×
224
                }
×
225
                buf.WriteString("\n")
2✔
226
        } else {
17✔
227
                buf.WriteString("  # Environment variables\n")
17✔
228
                buf.WriteString("  env: []\n\n")
17✔
229
        }
17✔
230

231
        // Add podSecurityContext
232
        if podSecCtx, exists := f.DeploymentConfig["podSecurityContext"]; exists && podSecCtx != nil {
19✔
233
                buf.WriteString("  # Pod-level security settings\n")
×
234
                buf.WriteString("  podSecurityContext:\n")
×
235
                if secYaml, err := yaml.Marshal(podSecCtx); err == nil {
×
NEW
236
                        lines := bytes.SplitSeq(secYaml, []byte("\n"))
×
NEW
237
                        for line := range lines {
×
238
                                if len(line) > 0 {
×
239
                                        buf.WriteString("    ")
×
240
                                        buf.Write(line)
×
241
                                        buf.WriteString("\n")
×
242
                                }
×
243
                        }
244
                }
245
                buf.WriteString("\n")
×
246
        } else {
19✔
247
                f.addDefaultPodSecurityContext(buf)
19✔
248
        }
19✔
249

250
        // Add securityContext
251
        if secCtx, exists := f.DeploymentConfig["securityContext"]; exists && secCtx != nil {
19✔
252
                buf.WriteString("  # Container-level security settings\n")
×
253
                buf.WriteString("  securityContext:\n")
×
254
                if secYaml, err := yaml.Marshal(secCtx); err == nil {
×
NEW
255
                        lines := bytes.SplitSeq(secYaml, []byte("\n"))
×
NEW
256
                        for line := range lines {
×
257
                                if len(line) > 0 {
×
258
                                        buf.WriteString("    ")
×
259
                                        buf.Write(line)
×
260
                                        buf.WriteString("\n")
×
261
                                }
×
262
                        }
263
                }
264
                buf.WriteString("\n")
×
265
        } else {
19✔
266
                f.addDefaultSecurityContext(buf)
19✔
267
        }
19✔
268

269
        // Add resources
270
        if resources, exists := f.DeploymentConfig["resources"]; exists && resources != nil {
20✔
271
                buf.WriteString("  # Resource limits and requests\n")
1✔
272
                buf.WriteString("  resources:\n")
1✔
273
                if resYaml, err := yaml.Marshal(resources); err == nil {
2✔
274
                        lines := bytes.SplitSeq(resYaml, []byte("\n"))
1✔
275
                        for line := range lines {
5✔
276
                                if len(line) > 0 {
7✔
277
                                        buf.WriteString("    ")
3✔
278
                                        buf.Write(line)
3✔
279
                                        buf.WriteString("\n")
3✔
280
                                }
3✔
281
                        }
282
                }
283
                buf.WriteString("\n")
1✔
284
        } else {
18✔
285
                f.addDefaultResources(buf)
18✔
286
        }
18✔
287
}
288

289
// addDefaultDeploymentSections adds default sections when no deployment config is available
290
func (f *HelmValuesBasic) addDefaultDeploymentSections(buf *bytes.Buffer) {
4✔
291
        buf.WriteString("  # Environment variables\n")
4✔
292
        buf.WriteString("  env: []\n\n")
4✔
293

4✔
294
        f.addDefaultPodSecurityContext(buf)
4✔
295
        f.addDefaultSecurityContext(buf)
4✔
296
        f.addDefaultResources(buf)
4✔
297
}
4✔
298

299
// addArgsSection adds controller manager args section to the values file
300
func (f *HelmValuesBasic) addArgsSection(buf *bytes.Buffer) {
23✔
301
        buf.WriteString("  # Arguments\n")
23✔
302

23✔
303
        if f.DeploymentConfig != nil {
42✔
304
                if args, exists := f.DeploymentConfig["args"]; exists && args != nil {
20✔
305
                        if argsYaml, err := yaml.Marshal(args); err == nil {
2✔
306
                                if trimmed := strings.TrimSpace(string(argsYaml)); trimmed != "" && trimmed != "[]" {
2✔
307
                                        lines := bytes.Split(argsYaml, []byte("\n"))
1✔
308
                                        buf.WriteString("  args:\n")
1✔
309
                                        for _, line := range lines {
3✔
310
                                                if len(line) > 0 {
3✔
311
                                                        buf.WriteString("    ")
1✔
312
                                                        buf.Write(line)
1✔
313
                                                        buf.WriteString("\n")
1✔
314
                                                }
1✔
315
                                        }
316
                                        buf.WriteString("\n")
1✔
317
                                        return
1✔
318
                                }
319
                        }
320
                }
321
        }
322

323
        buf.WriteString("  args: []\n\n")
22✔
324
}
325

326
// addDefaultPodSecurityContext adds default podSecurityContext section
327
func (f *HelmValuesBasic) addDefaultPodSecurityContext(buf *bytes.Buffer) {
23✔
328
        buf.WriteString("  # Pod-level security settings\n")
23✔
329
        buf.WriteString("  podSecurityContext: {}\n")
23✔
330
        buf.WriteString("    # fsGroup: 2000\n\n")
23✔
331
}
23✔
332

333
// addDefaultSecurityContext adds default securityContext section
334
func (f *HelmValuesBasic) addDefaultSecurityContext(buf *bytes.Buffer) {
23✔
335
        buf.WriteString("  # Container-level security settings\n")
23✔
336
        buf.WriteString("  securityContext: {}\n")
23✔
337
        buf.WriteString("    # capabilities:\n")
23✔
338
        buf.WriteString("    #   drop:\n")
23✔
339
        buf.WriteString("    #   - ALL\n")
23✔
340
        buf.WriteString("    # readOnlyRootFilesystem: true\n")
23✔
341
        buf.WriteString("    # runAsNonRoot: true\n")
23✔
342
        buf.WriteString("    # runAsUser: 1000\n\n")
23✔
343
}
23✔
344

345
// addDefaultResources adds default resources section
346
func (f *HelmValuesBasic) addDefaultResources(buf *bytes.Buffer) {
22✔
347
        buf.WriteString("  # Resource limits and requests\n")
22✔
348
        buf.WriteString("  resources: {}\n")
22✔
349
        buf.WriteString("    # limits:\n")
22✔
350
        buf.WriteString("    #   cpu: 100m\n")
22✔
351
        buf.WriteString("    #   memory: 128Mi\n")
22✔
352
        buf.WriteString("    # requests:\n")
22✔
353
        buf.WriteString("    #   cpu: 100m\n")
22✔
354
        buf.WriteString("    #   memory: 128Mi\n\n")
22✔
355
}
22✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc