Search code examples
kubernetes-helmgo-templates

Helm _helpers.yaml template with bool returning %!S(Bool=True) instead of string


I have the following Helm template definition:

{{- define "api.test-drive" -}}
{{- if not .Values.global.testDrive }}
{{- printf "%s" .Values.default.TEST_DRIVE | quote -}}
{{- else -}}
{{- printf "%s" .Values.global.testDrive | title | quote -}}
{{- end -}}
{{- end -}}

With the following in a configmap template:

TEST_DRIVE: {{ include "api.test-drive" . }}

And a global value of global.testDrive: true. However, when Helm executes this an inserts into the configmap, it is storing it as:

TEST_DRIVE:
----
%!S(Bool=True)

Shouldn't the printf be casting global.testDrive from a bool true to a string then applying the title and quote function? It is not clear what is happening here.


Solution

  • The Go text/template printf template function passes through directly to fmt.Printf(), but the fmt package defines its format strings a little bit differently from C's printf(3) function. In particular, the %s format modifier is only defined for string-type arguments, and you've passed it a bool-type argument; the %!s(...) output means there was an error processing a %s argument (see Format errors).

    If you want to use printf here, %v will convert an arbitrary value to a string with a default syntax

    {{- printf "%v" .Values.global.testDrive | title | quote -}}
    {{/*        ^^                                          */}}
    

    Helm includes a generic toString helper which might be more convenient here.

    {{- .Values.global.testDrive | toString | title | quote -}}
    

    (...but under the hood in most cases toString does the equivalent of printf "%v".)