Secret value is returning NIL
When i run the command below to check the values in the secret
kubectl get secret cred2 -n service-b -o jsonpath='{.data.*}' | base64 -d
It returns a Nil value. How do i get the value that was passed on the values.yaml file?
{"auths":{"%!s(<nil>)":{"username":"%!s(<nil>)","password":"%!s(<nil>)","email":"%!s(<nil>)","auth":"JSFzKDxuaWw KTolIXMoPG5pbD4p"}}}%`
Sample Code used to generate the secret
{{ range $index, $namespace := (lookup "v1" "Namespace" "" "").items }}
{{ range $.Values.imageCredentials }}
apiVersion: v1
kind: Secret
metadata:
name: {{ .name }}
namespace: {{ $namespace.metadata.name }}
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: {{ template "imagePullSecret" $ }}
{{ end }}
{{ end }}
values.yaml
imageCredentials:
- name: cred1
registry: quay.io
username: someone
password: sillyness
email: [email protected]
- name: cred2
registry: quay.io
username: someone
password: sillyness
email: [email protected]
_helpers
{{- define "imagePullSecret" }}
{{- printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":\"%s\",\"email\":\"%s\",\"auth\":\"%s\"}}}" .registry .username .password .email (printf "%s:%s" .username .password | b64enc) | b64enc }}
{{- end }}
CodePudding user response:
You should think of template
(and the Helm-specific include
) like function calls that take a single parameter. Here you're passing that parameter as $
, a special variable that refers to the top-level object. You probably want .
, which within a range
loop refers to the current item.
{{ range $.Values.imageCredentials }}
data:
.dockerconfigjson: {{ template "imagePullSecret" . }}
{{/* ^ not `$` */}}
{{ end }}
You might be confusing this case with the similar Create kubernetes docker-registry secret from yaml file for each lookup namespaces?. In that question, the template is trying to refer to .Values.imageCredentials
. This expression can be decomposed as: within .
(the template parameter), find the field Values
, and within that find the field imageCredentials
. In that question the template parameter must be the top-level Helm object so that it can dereference .Values
. But in your example here, you loop over a list in the top-level template, and need to pass the individual values into the supporting template.
{{/* Your question: template accepts a sub-item of the values; pass
`.` or another derived expression */}}
{{- define "imagePullSecret" -}}
{{ printf ... .registry .email ... }}
{{- end -}}
{{/* Other question: template accepts the top-level Helm object; pass
`$`, a saved reference to the top-level object, or you can use
`.` outside a `range` or `with` block that redefines it */}}
{{- define "imagePullSecret" -}}
{{- with .Values.imageCredentials }}...{{- end }}
{{- end -}}
CodePudding user response:
It's because the $
passed into your template causes evaluation to be a different variable context than what you expected; it's the root of the variables (that's why in your 2nd range
you have $.Values
to escape back out of the 1st range
context over the Namespaces). When using template
like that, you'll almost always want the variable context provided to be .
in order to say "use the variable context I'm sitting in" as the principal of least surprise. For this specific case, you could also create a named variable for that 2nd range
to use ({{ range $cred := range $.Values.imageCredentials }}
) in order to make it extra explicit, depending on your team's coding style and familiarity with golang templates
Be aware that you're also missing the ---
to separate those kind: Secret
documents from one another.
{{ range $index, $namespace := (lookup "v1" "Namespace" "" "").items }}
{{ range $.Values.imageCredentials }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ .name }}
namespace: {{ $namespace.metadata.name }}
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: {{ template "imagePullSecret" . }}
{{ end }}
{{ end }}
running helm template .
generates:
apiVersion: v1
kind: Secret
metadata:
name: cred1
namespace: alpha
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: eyJhdXRocyI6eyJxdWF5LmlvIjp7InVzZXJuYW1lIjoic29tZW9uZSIsInBhc3N3b3JkIjoic2lsbHluZXNzIiwiZW1haWwiOiJzb21lb25lQGhvc3QuY29tIiwiYXV0aCI6ImMyOXRaVzl1WlRwemFXeHNlVzVsYzNNPSJ9fX0=
which decodes as
{
"auths": {
"quay.io": {
"username": "someone",
"password": "sillyness",
"email": "[email protected]",
"auth": "c29tZW9uZTpzaWxseW5lc3M="
}
}
}
and that interior auth
key similarly: someone:sillyness