2490debffbd774aca868f3a44e9d49cb67877fe2
[oom.git] / kubernetes / common / common / templates / _secret.tpl
1 {{/*
2 # Copyright © 2019 AT&T, Samsung Electronics
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 {{/*
18   For internal use only!
19
20   Generates a secret header with given name and desired labels.
21
22   The template takes two arguments:
23     - .global: environment (.)
24     - .name: name of the secret
25     - .annotations: annotations which should be used
26
27   Example call:
28     {{ include "common.secret._header" (dict "global" . "name" "myFancyName") }}
29 */}}
30 {{- define "common.secret._header" -}}
31 {{- $global := .global }}
32 {{- $name := .name }}
33 apiVersion: v1
34 kind: Secret
35 metadata:
36   name: {{ $name }}
37   namespace: {{ include "common.namespace" $global }}
38   labels:
39     app: {{ include "common.name" $global }}
40     chart: {{ $global.Chart.Name }}-{{ $global.Chart.Version | replace "+" "_" }}
41     release: {{ include "common.release" $global }}
42     heritage: {{ $global.Release.Service }}
43 {{- if .annotations }}
44   annotations: {{- include "common.tplValue" (dict "value" .annotations "context" $global) | nindent 4 }}
45 {{- end }}
46 type: Opaque
47 {{- end -}}
48
49 {{/*
50   For internal use only!
51
52   Pick a value based on "user input" and generation policy.
53
54   The template takes below arguments:
55     - .global: environment (.)
56     - .secretName: name of the secret where the value will be placed
57     - .secretEnv: map of values which configures this secret. This can contain below keys:
58         - value: Value of secret key provided by user (can be a template inside a string)
59         - policy: What to do if value is missing or empty. Possible options are:
60             - generate: Generate a new password deriving it from master password
61             - required: Fail the deployment if value has not been provided
62           Defaults to generate.
63         - name: Name of the key to which this value should be assigned
64 */}}
65 {{- define "common.secret._value" -}}
66   {{- $global := .global }}
67   {{- $name := .secretName }}
68   {{- $secretEnv := .secretEnv }}
69   {{- $value := tpl $secretEnv.value $global }}
70   {{- $policy := default "generate" $secretEnv.policy }}
71
72   {{- if $value }}
73     {{- $value | quote }}
74   {{- else if eq $policy "generate" }}
75     {{- include "common.createPassword" (dict "dot" $global "uid" $name) | quote }}
76   {{- else }}
77     {{- fail (printf "Value for %s secret %s key not provided" $name $secretEnv.name) }}
78   {{- end }}
79 {{- end -}}
80
81 {{/*
82   For internal use only!
83
84   Pick a value based on "user input" and generation policy.
85
86   The template takes below arguments:
87     - .global: environment (.)
88     - .secretName: name of the secret where the value will be placed
89     - .secretEnv: map of values which configures this secret. This can contain below keys:
90         - value: Value of secret key provided by user (can be a template inside a string)
91         - policy: What to do if value is missing or empty. Possible options are:
92             - generate: Generate a new password deriving it from master password
93             - required: Fail the deployment if value has not been provided
94           Defaults to generate.
95         - name: Name of the key to which this value should be assigned
96 */}}
97 {{- define "common.secret._valueFast" -}}
98   {{- $global := .global }}
99   {{- $name := .secretName }}
100   {{- $secretEnv := .secretEnv }}
101   {{- $value := $secretEnv.value }}
102   {{- $policy := default "generate" $secretEnv.policy }}
103
104   {{- if $value }}
105     {{- $value | quote }}
106   {{- else if eq $policy "generate" }}
107     {{- include "common.createPassword" (dict "dot" $global "uid" $name) | quote }}
108   {{- else }}
109     {{- fail (printf "Value for %s secret %s key not provided" $name $secretEnv.name) }}
110   {{- end }}
111 {{- end -}}
112
113
114 {{/*
115   Generate a secret name based on provided name or UID.
116   If UID is provided then the name is generated by appending this UID right after
117   the chart name. If name is provided, it overrides the name generation algorith
118   and is used right away. Both name and uid strings may contain a template to be
119   resolved.
120
121   The template takes below arguments:
122     - .global: environment (.)
123     - .uid: string that uniquely identifies this secret within a helm chart
124     - .name: string that can be used to override default name generation algorithm
125         and provide a custom name for the secret
126 */}}
127 {{- define "common.secret.genName" -}}
128   {{- $global := .global }}
129   {{- $uid := tpl (default "" .uid) $global }}
130   {{- $name := tpl (default "" .name) $global }}
131   {{- $fullname := ne (default "" .chartName) "" | ternary (include "common.fullnameExplicit" (dict "dot" $global "chartName" .chartName)) (include "common.fullname" $global) }}
132   {{- default (printf "%s-%s" $fullname $uid) $name }}
133 {{- end -}}
134
135 {{- define "common.secret.genNameFast" -}}
136   {{- $global := .global }}
137   {{- $uid := (default "" .uid) }}
138   {{- $name := (default "" .name) }}
139   {{- $fullname := ne (default "" .chartName) "" | ternary (include "common.fullnameExplicit" (dict "dot" $global "chartName" .chartName)) (include "common.fullname" $global) }}
140   {{- if eq "test-release" $global.Release.Name -}}
141   {{/* Special case for chart liniting in helm3. DON"T NAME YOUR PRODUCTION RELEASE test-release */}}
142   {{- $uid = lower $uid -}}
143   {{- end -}}
144   {{- default (printf "%s-%s" $fullname $uid) $name }}
145 {{- end -}}
146
147 {{/*
148   Get the real secret name by UID or name, based on the configuration provided by user.
149   User may decide to not create a new secret but reuse existing one for this deployment
150   (aka externalSecret). In this case the real name of secret to be used is different
151   than the one declared in secret definition. This easily retrieve current secret real
152   name based on declared name or UID even if it has been overrided by the user using
153   externalSecret option. You should use this template always when you need to reference
154   a secret created using common.secret template by name.
155
156   The template takes below arguments:
157     - .global: environment (.)
158     - .uid: string that uniquely identifies this secret within a helm chart
159         (can be omitted if name has been provided)
160     - .name: name which was used to declare a secret
161         (can be omitted if uid has been provided)
162 */}}
163 {{- define "common.secret.getSecretName" -}}
164   {{- $global := .global }}
165   {{- $name := tpl (default "" .name) $global }}
166   {{- $uid := tpl (default "" .uid) $global }}
167   {{- $targetName := default (include "common.secret.genName" (dict "global" $global "uid" $uid "name" .name)) $name}}
168   {{- range $secret := $global.Values.secrets }}
169     {{- $currUID := tpl (default "" $secret.uid) $global }}
170     {{- $givenName := tpl (default "" $secret.name) $global }}
171     {{- $currName := default (include "common.secret.genName" (dict "global" $global "uid" $currUID "name" $secret.name)) $givenName }}
172     {{- if or (eq $uid $currUID) (eq $currName $targetName) }}
173       {{- $externalSecret := tpl (default "" $secret.externalSecret) $global }}
174       {{- default $currName $externalSecret }}
175     {{- end }}
176   {{- end }}
177 {{- end -}}
178
179 {{- define "common.secret.getSecretNameFast" -}}
180   {{- $global := .global }}
181   {{- include "common.secret.buildCache" $global }}
182   {{- $secretsCache := $global.Values._secretsCache }}
183   {{- $uid := tpl .uid $global }}
184   {{- $secret := index $secretsCache $uid }}
185   {{- $secret.realName }}
186 {{- end -}}
187
188 {{- define "common.secret.buildCache" -}}
189   {{- $global := . }}
190   {{- if not $global.Values._secretsCache }}
191     {{- $secretCache := dict }}
192     {{- range $secret := .Values.secrets }}
193       {{- $entry := dict }}
194       {{- $uid := tpl (default "" $secret.uid) $global }}
195       {{- $keys := keys $secret }}
196       {{- range $key := (without $keys "annotations" "filePaths" )}}
197         {{- $_ := set $entry $key (tpl (index $secret $key) $global) }}
198       {{- end }}
199       {{- if $secret.annotations }}
200         {{- $_ := set $entry "annotations" $secret.annotations }}
201       {{- end }}
202       {{- if $secret.filePaths }}
203         {{- if kindIs "string" $secret.filePaths }}
204           {{- $evaluated := tpl (default "" $secret.filePaths) $global }}
205           {{- if and $evaluated (ne $evaluated "\"\"") }}
206             {{- $fstr := printf "val:\n%s" ($evaluated | indent 2) }}
207             {{- $flist := (index (tpl $fstr $global | fromYaml) "val") }}
208             {{- $_ := set $entry "filePaths" $flist }}
209           {{- else }}
210             {{- $_ := set $entry "filePaths" (list) }}
211           {{- end }}
212         {{- else }}
213           {{- $_ := set $entry "filePaths" $secret.filePaths }}
214         {{- end }}
215       {{- end }}
216       {{- $realName := default (include "common.secret.genNameFast" (dict "global" $global "uid" $uid "name" $entry.name) ) $entry.externalSecret }}
217       {{- $_ := set $entry "realName" $realName }}
218       {{- $_ := set $secretCache $uid $entry }}
219     {{- end }}
220     {{- $_ := set $global.Values "_secretsCache" $secretCache }}
221   {{- end }}
222 {{- end -}}
223
224 {{/*
225   Convenience template which can be used to easily set the value of environment variable
226   to the value of a key in a secret.
227
228   It takes care of all name mangling, usage of external secrets etc.
229
230   The template takes below arguments:
231     - .global: environment (.)
232     - .uid: string that uniquely identifies this secret within a helm chart
233         (can be omitted if name has been provided)
234     - .name: name which was used to declare a secret
235         (can be omitted if uid has been provided)
236     - .key: Key within this secret which value should be assigned to this variable
237
238   Example usage:
239   env:
240     - name: SECRET_PASSWORD
241       {{- include "common.secret.envFromSecret" (dict "global" . "uid" "secret" "key" "password") | indent 8}}
242 */}}
243 {{- define "common.secret.envFromSecret" -}}
244   {{- $key := .key }}
245 valueFrom:
246   secretKeyRef:
247     name: {{ include "common.secret.getSecretName" . }}
248     key: {{ $key }}
249 {{- end -}}
250
251 {{- define "common.secret.envFromSecretFast" -}}
252   {{- $key := .key }}
253 valueFrom:
254   secretKeyRef:
255     name: {{ include "common.secret.getSecretNameFast" . }}
256     key: {{ $key }}
257 {{- end -}}
258
259 {{/*
260   Define secrets to be used by chart.
261   Every secret has a type which is one of:
262     - generic:
263         Generic secret template that allows to input some raw data (from files).
264         File Input can be passed as list of files (filePaths) or as a single string
265         (filePath)
266     - genericKV:
267         Type of secret which allows you to define a list of key value pairs.
268         The list is assiged to envs value. Every item may define below items:
269           - name:
270               Identifier of this value within secret
271           - value:
272               String that defines a value associated with given key.
273               This can be a simple string or a template.
274           - policy:
275               Defines what to do if value is not provided by the user.
276               Available options are:
277                 - generate:
278                     Generate a value by derriving it from master password
279                 - required:
280                     Fail the deployment
281     - password:
282         Type of secret that holds only the password.
283         Only two items can be defined for this type:
284           - password:
285               Equivalent of value field from genericKV
286           - policy:
287               The same meaning as for genericKV policy field
288     - basicAuth:
289         Type of secret that holds both username and password.
290         Below fields are available:
291           - login:
292               The value for login key.
293               This can be a simple string or a template.
294               Providing a value for login is always required.
295           - password:
296               The value for password key.
297               This can be a simple string or a template.
298           - passwordPolicy:
299               The same meaning as the policy field in genericKV.
300               Only the policy for password can be set.
301
302   Every secret can be identified using:
303     - uid:
304         A string to be appended to the chart fullname to generate a secret name.
305     - name:
306         Overrides default secret name generation and allows to set immutable
307         and globaly unique name
308     - annotations:
309         List of annotations to be used while defining a secret
310
311   To allow sharing a secret between the components and allow to pre-deploy secrets
312   before ONAP deployment it is possible to use already existing secret instead of
313   creating a new one. For this purpose externalSecret field can be used. If value of
314   this field is evaluated to true no new secret is created, only the name of the
315   secret is aliased to the external one.
316
317   Example usage:
318     secrets.yaml:
319       {{ include "common.secret" . }}
320
321     values.yaml:
322       mysqlLogin: "root"
323
324       mysqlExternalSecret: "some-other-secret-name"
325
326       secrets:
327         - uid: "mysql"
328           externalSecret: '{{ tpl .Values.passExternalSecret . }}'
329           type: basicAuth
330           login: '{{ .Values.mysqlLogin }}'
331           mysqlPassword: '{{ .Values.mysqlPassword }}'
332           passwordPolicy: generate
333
334     In the above example new secret is not going to be created.
335     Already existing one (some-other-secret-name) is going to be used.
336     To force creating a new one, just make sure that mysqlExternalSecret
337     is not set.
338
339 */}}
340 {{- define "common.secret" -}}
341   {{- $global := . }}
342   {{- range $secret := .Values.secrets }}
343     {{- $uid := tpl (default "" $secret.uid) $global }}
344     {{- $name := include "common.secret.genName" (dict "global" $global "uid" $uid "name" $secret.name) }}
345     {{- $annotations := default "" $secret.annotations }}
346     {{- $type := default "generic" $secret.type }}
347     {{- $externalSecret := tpl (default "" $secret.externalSecret) $global }}
348     {{- if not $externalSecret }}
349 ---
350       {{ include "common.secret._header" (dict "global" $global "name" $name "annotations" $annotations) }}
351
352       {{- if eq $type "generic" }}
353 data:
354         {{- range $curFilePath := $secret.filePaths }}
355           {{ tpl ($global.Files.Glob $curFilePath).AsSecrets $global | indent 2 }}
356         {{- end }}
357         {{- if $secret.filePath }}
358           {{ tpl ($global.Files.Glob $secret.filePath).AsSecrets $global | indent 2 }}
359         {{- end }}
360       {{- else if eq $type "genericKV" }}
361 stringData:
362         {{- if $secret.envs }}
363           {{- range $secretEnv := $secret.envs }}
364             {{- $valueDesc := (dict "global" $global "secretName" $name "secretEnv" $secretEnv) }}
365     {{ $secretEnv.name }}: {{ include "common.secret._value" $valueDesc }}
366           {{- end }}
367         {{- end }}
368       {{- else if eq $type "password" }}
369         {{- $secretEnv := (dict "policy" (default "generate" $secret.policy) "name" "password" "value" $secret.password) }}
370         {{- $valueDesc := (dict "global" $global "secretName" $name "secretEnv" $secretEnv) }}
371 stringData:
372   password: {{ include "common.secret._value" $valueDesc }}
373       {{- else if eq $type "basicAuth" }}
374 stringData:
375         {{- $secretEnv := (dict "policy" "required" "name" "login" "value" $secret.login) }}
376         {{- $valueDesc := (dict "global" $global "secretName" $name "secretEnv" $secretEnv) }}
377   login: {{ include "common.secret._value" $valueDesc }}
378         {{- $secretEnv := (dict "policy" (default "generate" $secret.passwordPolicy) "name" "password" "value" $secret.password) }}
379         {{- $valueDesc := (dict "global" $global "secretName" $name "secretEnv" $secretEnv) }}
380   password: {{ include "common.secret._value" $valueDesc }}
381       {{- end }}
382     {{- end }}
383   {{- end }}
384 {{- end -}}
385
386 {{/*
387   Define secrets to be used by chart.
388   Every secret has a type which is one of:
389     - generic:
390         Generic secret template that allows to input some raw data (from files).
391         File Input can be passed as list of files (filePaths) or as a single string
392         (filePath)
393     - genericKV:
394         Type of secret which allows you to define a list of key value pairs.
395         The list is assiged to envs value. Every item may define below items:
396           - name:
397               Identifier of this value within secret
398           - value:
399               String that defines a value associated with given key.
400               This can be a simple string or a template.
401           - policy:
402               Defines what to do if value is not provided by the user.
403               Available options are:
404                 - generate:
405                     Generate a value by derriving it from master password
406                 - required:
407                     Fail the deployment
408     - password:
409         Type of secret that holds only the password.
410         Only two items can be defined for this type:
411           - password:
412               Equivalent of value field from genericKV
413           - policy:
414               The same meaning as for genericKV policy field
415     - basicAuth:
416         Type of secret that holds both username and password.
417         Below fields are available:
418           - login:
419               The value for login key.
420               This can be a simple string or a template.
421               Providing a value for login is always required.
422           - password:
423               The value for password key.
424               This can be a simple string or a template.
425           - passwordPolicy:
426               The same meaning as the policy field in genericKV.
427               Only the policy for password can be set.
428
429   Every secret can be identified using:
430     - uid:
431         A string to be appended to the chart fullname to generate a secret name.
432     - name:
433         Overrides default secret name generation and allows to set immutable
434         and globaly unique name
435     - annotations:
436         List of annotations to be used while defining a secret
437
438   To allow sharing a secret between the components and allow to pre-deploy secrets
439   before ONAP deployment it is possible to use already existing secret instead of
440   creating a new one. For this purpose externalSecret field can be used. If value of
441   this field is evaluated to true no new secret is created, only the name of the
442   secret is aliased to the external one.
443
444   Example usage:
445     secrets.yaml:
446       {{ include "common.secretFast" . }}
447
448     values.yaml:
449       mysqlLogin: "root"
450
451       mysqlExternalSecret: "some-other-secret-name"
452
453       secrets:
454         - uid: "mysql"
455           externalSecret: '{{ tpl .Values.passExternalSecret . }}'
456           type: basicAuth
457           login: '{{ .Values.mysqlLogin }}'
458           mysqlPassword: '{{ .Values.mysqlPassword }}'
459           passwordPolicy: generate
460
461     In the above example new secret is not going to be created.
462     Already existing one (some-other-secret-name) is going to be used.
463     To force creating a new one, just make sure that mysqlExternalSecret
464     is not set.
465
466 */}}
467 {{- define "common.secretFast" -}}
468   {{- $global := . }}
469   {{- include "common.secret.buildCache" $global }}
470   {{- range $secret := .Values._secretsCache }}
471     {{- $uid := $secret.uid }}
472     {{- $externalSecret := $secret.externalSecret }}
473     {{- if not $externalSecret }}
474       {{- $name := $secret.realName }}
475       {{- $annotations := default "" $secret.annotations }}
476       {{- $type := default "generic" $secret.type }}
477 ---
478       {{ include "common.secret._header" (dict "global" $global "name" $name "annotations" $annotations) }}
479
480       {{- if eq $type "generic" }}
481 data:
482         {{- range $curFilePath := $secret.filePaths }}
483           {{ tpl ($global.Files.Glob $curFilePath).AsSecrets $global | indent 2 }}
484         {{- end }}
485         {{- if $secret.filePath }}
486           {{ tpl ($global.Files.Glob $secret.filePath).AsSecrets $global | indent 2 }}
487         {{- end }}
488       {{- else if eq $type "genericKV" }}
489 stringData:
490         {{- if $secret.envs }}
491           {{- range $secretEnv := $secret.envs }}
492             {{- $valueDesc := (dict "global" $global "secretName" $name "secretEnv" $secretEnv) }}
493     {{ $secretEnv.name }}: {{ include "common.secret._valueFast" $valueDesc }}
494           {{- end }}
495         {{- end }}
496       {{- else if eq $type "password" }}
497         {{- $secretEnv := (dict "policy" (default "generate" $secret.policy) "name" "password" "value" $secret.password) }}
498         {{- $valueDesc := (dict "global" $global "secretName" $name "secretEnv" $secretEnv) }}
499 stringData:
500   password: {{ include "common.secret._valueFast" $valueDesc }}
501       {{- else if eq $type "basicAuth" }}
502 stringData:
503         {{- $secretEnv := (dict "policy" "required" "name" "login" "value" $secret.login) }}
504         {{- $valueDesc := (dict "global" $global "secretName" $name "secretEnv" $secretEnv) }}
505   login: {{ include "common.secret._valueFast" $valueDesc }}
506         {{- $secretEnv := (dict "policy" (default "generate" $secret.passwordPolicy) "name" "password" "value" $secret.password) }}
507         {{- $valueDesc := (dict "global" $global "secretName" $name "secretEnv" $secretEnv) }}
508   password: {{ include "common.secret._valueFast" $valueDesc }}
509       {{- end }}
510     {{- end }}
511   {{- end }}
512 {{- end -}}