Skip to content

Commit 22e03cd

Browse files
RealAnnabacherfl
andcommitted
feat: introduce readiness and liveness probe feature
Signed-off-by: RealAnna <anna.reale@dynatrace.com> feat: added tests Signed-off-by: RealAnna <anna.reale@dynatrace.com> feat: introduce readiness and liveness probe feature Signed-off-by: RealAnna <anna.reale@dynatrace.com> feat: added fix Signed-off-by: RealAnna <anna.reale@dynatrace.com> feat: added fix Signed-off-by: RealAnna <anna.reale@dynatrace.com> feat: added fix Signed-off-by: RealAnna <anna.reale@dynatrace.com> feat: added fix Signed-off-by: RealAnna <anna.reale@dynatrace.com> feat: introduce readiness and liveness probe feature (#3) * feat: introduce readiness and liveness probe feature feat: introduce readiness and liveness probe feature Signed-off-by: realanna <anna.reale@dynatrace.com> * Update pkg/processor/probes/probes.go Co-authored-by: Florian Bacher <florian.bacher@dynatrace.com> Signed-off-by: realanna <anna.reale@dynatrace.com> --------- Signed-off-by: realanna <anna.reale@dynatrace.com> Co-authored-by: Florian Bacher <florian.bacher@dynatrace.com>
1 parent 5b663ea commit 22e03cd

11 files changed

Lines changed: 368 additions & 31 deletions

File tree

cmd/helmify/flags.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ func ReadFlags() config.Config {
3737
flag.BoolVar(&result.VeryVerbose, "vv", false, "Enable very verbose output. Same as verbose but with DEBUG. Example: helmify -vv")
3838
flag.BoolVar(&crd, "crd-dir", false, "Enable crd install into 'crds' directory.\nWarning: CRDs placed in 'crds' directory will not be templated by Helm.\nSee https://helm.sh/docs/chart_best_practices/custom_resource_definitions/#some-caveats-and-explanations\nExample: helmify -crd-dir")
3939
flag.BoolVar(&result.ImagePullSecrets, "image-pull-secrets", false, "Allows the user to use existing secrets as imagePullSecrets in values.yaml")
40+
flag.BoolVar(&result.Probes, "probes", true, "Allows the user to customize liveness and readiness probes")
4041

4142
flag.Parse()
4243
if h || help {

examples/operator/templates/_helpers.tpl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,17 @@ Create the name of the service account to use
6060
{{- default "default" .Values.serviceAccount.name }}
6161
{{- end }}
6262
{{- end }}
63+
64+
{{/*
65+
Renders a value that contains template.
66+
Usage:
67+
{{ include "tplvalues.render" ( dict "value" .Values.path.to.the.Value "context" $) }}
68+
*/}}
69+
{{- define "tplvalues.render" -}}
70+
{{- if typeIs "string" .value }}
71+
{{- tpl .value .context }}
72+
{{- else }}
73+
{{- tpl (.value | toYaml) .context }}
74+
{{- end }}
75+
{{- end -}}
76+

examples/operator/templates/deployment.yaml

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -53,28 +53,15 @@ spec:
5353
key: VAR1
5454
name: {{ include "operator.fullname" . }}-secret-vars
5555
- name: VAR2
56-
value: {{ .Values.controllerManager.manager.var2 }}
56+
value: {{ .Values.controllerManager.manager.env.var2 }}
5757
- name: VAR3_MY_ENV
58-
value: {{ .Values.controllerManager.manager.var3MyEnv }}
58+
value: {{ .Values.controllerManager.manager.env.var3MyEnv }}
5959
- name: KUBERNETES_CLUSTER_DOMAIN
6060
value: {{ .Values.kubernetesClusterDomain }}
6161
image: {{ .Values.controllerManager.manager.image.repository }}:{{ .Values.controllerManager.manager.image.tag
6262
| default .Chart.AppVersion }}
63-
livenessProbe:
64-
httpGet:
65-
path: /healthz
66-
port: 8081
67-
initialDelaySeconds: 15
68-
periodSeconds: 20
6963
name: manager
70-
readinessProbe:
71-
httpGet:
72-
path: /readyz
73-
port: 8081
74-
initialDelaySeconds: 5
75-
periodSeconds: 10
76-
resources: {{- toYaml .Values.controllerManager.manager.resources | nindent 10
77-
}}
64+
resources: {{- toYaml .Values.controllerManager.manager.resources | nindent 10 }}
7865
securityContext:
7966
allowPrivilegeEscalation: false
8067
volumeMounts:
@@ -83,6 +70,26 @@ spec:
8370
subPath: controller_manager_config.yaml
8471
- mountPath: /my.ca
8572
name: secret-volume
73+
{{- if .Values.controllerManager.manager.livenessProbe }}
74+
livenessProbe: {{- include "tplvalues.render" (dict "value" .Values.controllerManager.manager.livenessProbe "context" $) | nindent 10 }}
75+
{{- else }}
76+
livenessProbe:
77+
httpGet:
78+
path: /healthz
79+
port: 8081
80+
initialDelaySeconds: 15
81+
periodSeconds: 20
82+
{{- end }}
83+
{{- if .Values.controllerManager.manager.readinessProbe }}
84+
readinessProbe: {{- include "tplvalues.render" (dict "value" .Values.controllerManager.manager.readinessProbe "context" $) | nindent 10 }}
85+
{{- else }}
86+
readinessProbe:
87+
httpGet:
88+
path: /readyz
89+
port: 8081
90+
initialDelaySeconds: 5
91+
periodSeconds: 10
92+
{{- end }}
8693
imagePullSecrets:
8794
- name: {{ include "operator.fullname" . }}-secret-registry-credentials
8895
securityContext:

examples/operator/values.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@ controllerManager:
1010
image:
1111
repository: controller
1212
tag: latest
13+
livenessProbe:
14+
httpGet:
15+
path: /healthz
16+
port: 8081
17+
initialDelaySeconds: 15
18+
periodSeconds: 20
19+
readinessProbe:
20+
httpGet:
21+
path: /readyz
22+
port: 8081
23+
initialDelaySeconds: 5
24+
periodSeconds: 10
1325
resources:
1426
limits:
1527
cpu: 100m

pkg/config/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ type Config struct {
2323
Crd bool
2424
// ImagePullSecrets flag
2525
ImagePullSecrets bool
26+
// Probes flag if true the probes will be parametrised
27+
Probes bool
2628
}
2729

2830
func (c *Config) Validate() error {

pkg/helm/init.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,20 @@ Create the name of the service account to use
9999
{{- default "default" .Values.serviceAccount.name }}
100100
{{- end }}
101101
{{- end }}
102+
103+
{{/*
104+
Renders a value that contains template.
105+
Usage:
106+
{{ include "tplvalues.render" ( dict "value" .Values.path.to.the.Value "context" $) }}
107+
*/}}
108+
{{- define "tplvalues.render" -}}
109+
{{- if typeIs "string" .value }}
110+
{{- tpl .value .context }}
111+
{{- else }}
112+
{{- tpl (.value | toYaml) .context }}
113+
{{- end }}
114+
{{- end -}}
115+
102116
`
103117

104118
const defaultChartfile = `apiVersion: v2

pkg/helmify/model.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package helmify
22

33
import (
4-
"github.com/arttor/helmify/pkg/config"
54
"io"
65

6+
"github.com/arttor/helmify/pkg/config"
7+
78
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
89
)
910

pkg/metadata/metadata.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ package metadata
22

33
import (
44
"fmt"
5-
"github.com/arttor/helmify/pkg/config"
65
"strings"
76

7+
"github.com/arttor/helmify/pkg/config"
8+
89
"github.com/arttor/helmify/pkg/helmify"
910
"github.com/sirupsen/logrus"
1011
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"

pkg/processor/deployment/deployment.go

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import (
77
"text/template"
88

99
"github.com/arttor/helmify/pkg/cluster"
10+
"github.com/arttor/helmify/pkg/helmify"
1011
"github.com/arttor/helmify/pkg/processor"
1112
"github.com/arttor/helmify/pkg/processor/imagePullSecrets"
12-
13-
"github.com/arttor/helmify/pkg/helmify"
13+
"github.com/arttor/helmify/pkg/processor/probes"
1414
yamlformat "github.com/arttor/helmify/pkg/yaml"
1515
"github.com/iancoleman/strcase"
1616
"github.com/pkg/errors"
@@ -47,7 +47,7 @@ const selectorTempl = `%[1]s
4747
{{- include "%[2]s.selectorLabels" . | nindent 6 }}
4848
%[3]s`
4949

50-
const envValue = "{{ .Values.%[1]s.%[2]s.%[3]s }}"
50+
const envValue = "{{ .Values.%[1]s.%[2]s.%[3]s.%[4]s }}"
5151

5252
// New creates processor for k8s Deployment resource.
5353
func New() helmify.Processor {
@@ -130,28 +130,32 @@ func (d deployment) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstr
130130
depl.Spec.Template.Spec.Volumes[i].PersistentVolumeClaim.ClaimName = tempPVCName
131131
}
132132

133+
// remove from spec things that will be processed separately
134+
cleanSpec := cleanSpec(*depl.Spec.Template.Spec.DeepCopy())
135+
133136
// replace container resources with template to values.
134-
specMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&depl.Spec.Template.Spec)
137+
specMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&cleanSpec)
135138
if err != nil {
136139
return true, nil, err
137140
}
138141
containers, _, err := unstructured.NestedSlice(specMap, "containers")
139142
if err != nil {
140143
return true, nil, err
141144
}
145+
142146
for i := range containers {
143147
containerName := strcase.ToLowerCamel((containers[i].(map[string]interface{})["name"]).(string))
144148
res, exists, err := unstructured.NestedMap(values, nameCamel, containerName, "resources")
145149
if err != nil {
146150
return true, nil, err
147151
}
148-
if !exists || len(res) == 0 {
149-
continue
150-
}
151-
err = unstructured.SetNestedField(containers[i].(map[string]interface{}), fmt.Sprintf(`{{- toYaml .Values.%s.%s.resources | nindent 10 }}`, nameCamel, containerName), "resources")
152-
if err != nil {
153-
return true, nil, err
152+
if exists && len(res) > 0 {
153+
err = unstructured.SetNestedField(containers[i].(map[string]interface{}), fmt.Sprintf(`{{- toYaml .Values.%s.%s.resources | nindent 10 }}`, nameCamel, containerName), "resources")
154+
if err != nil {
155+
return true, nil, err
156+
}
154157
}
158+
155159
}
156160
err = unstructured.SetNestedSlice(specMap, containers, "containers")
157161
if err != nil {
@@ -162,12 +166,21 @@ func (d deployment) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstr
162166
imagePullSecrets.ProcessSpecMap(specMap, &values)
163167
}
164168

169+
if appMeta.Config().Probes {
170+
err = probes.ProcessSpecMap(nameCamel, specMap, &values, depl.Spec.Template.Spec)
171+
if err != nil {
172+
return true, nil, err
173+
}
174+
}
175+
165176
spec, err := yamlformat.Marshal(specMap, 6)
166177
if err != nil {
167178
return true, nil, err
168179
}
169-
spec = strings.ReplaceAll(spec, "'", "")
170180

181+
spec = strings.ReplaceAll(spec, "'", "")
182+
spec = strings.ReplaceAll(spec, "|\n ", "")
183+
spec = strings.ReplaceAll(spec, "|-\n ", "")
171184
return true, &result{
172185
values: values,
173186
data: struct {
@@ -188,6 +201,15 @@ func (d deployment) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstr
188201
}, nil
189202
}
190203

204+
func cleanSpec(spec corev1.PodSpec) corev1.PodSpec {
205+
206+
for i := 0; i < len(spec.Containers); i++ {
207+
spec.Containers[i].LivenessProbe = nil
208+
spec.Containers[i].ReadinessProbe = nil
209+
}
210+
return spec
211+
}
212+
191213
func processReplicas(name string, deployment *appsv1.Deployment, values *helmify.Values) (string, error) {
192214
if deployment.Spec.Replicas == nil {
193215
return "", nil
@@ -208,6 +230,7 @@ func processPodSpec(name string, appMeta helmify.AppMetadata, pod *corev1.PodSpe
208230
values := helmify.Values{}
209231
for i, c := range pod.Containers {
210232
processed, err := processPodContainer(name, appMeta, c, &values)
233+
211234
if err != nil {
212235
return nil, err
213236
}
@@ -260,13 +283,16 @@ func processPodContainer(name string, appMeta helmify.AppMetadata, c corev1.Cont
260283
if e.ConfigMapRef != nil {
261284
e.ConfigMapRef.Name = appMeta.TemplatedName(e.ConfigMapRef.Name)
262285
}
286+
263287
}
288+
264289
c.Env = append(c.Env, corev1.EnvVar{
265290
Name: cluster.DomainEnv,
266291
Value: fmt.Sprintf("{{ .Values.%s }}", cluster.DomainKey),
267292
})
268293
for k, v := range c.Resources.Requests {
269294
err = unstructured.SetNestedField(*values, v.ToUnstructured(), name, containerName, "resources", "requests", k.String())
295+
270296
if err != nil {
271297
return c, errors.Wrap(err, "unable to set container resources value")
272298
}
@@ -277,7 +303,8 @@ func processPodContainer(name string, appMeta helmify.AppMetadata, c corev1.Cont
277303
return c, errors.Wrap(err, "unable to set container resources value")
278304
}
279305
}
280-
return c, nil
306+
307+
return c, err
281308
}
282309

283310
func processEnv(name string, appMeta helmify.AppMetadata, c corev1.Container, values *helmify.Values) (corev1.Container, error) {
@@ -293,7 +320,7 @@ func processEnv(name string, appMeta helmify.AppMetadata, c corev1.Container, va
293320
if err != nil {
294321
return c, errors.Wrap(err, "unable to set deployment value field")
295322
}
296-
c.Env[i].Value = fmt.Sprintf(envValue, name, containerName, strcase.ToLowerCamel(strings.ToLower(c.Env[i].Name)))
323+
c.Env[i].Value = fmt.Sprintf(envValue, name, containerName, "env", strcase.ToLowerCamel(strings.ToLower(c.Env[i].Name)))
297324
}
298325
}
299326
return c, nil

0 commit comments

Comments
 (0)