Home > Net >  Not getting the right value that was specified in the values.yaml file
Not getting the right value that was specified in the values.yaml file

Time:01-05

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

  • Related