task icon indicating copy to clipboard operation
task copied to clipboard

Interpolation of variables into complex strings does not work

Open achetronic opened this issue 2 years ago • 0 comments

I was creating an internal task to create generic Kubernetes secrets on-demand.

Imagine the following:


  global:inject-external-secrets-token:
    desc: Inject a token into Kubernetes, ready for External Secrets to read variables from Gitlab (task pepe TOKEN_NAME=cluster-01)
    requires:
      vars: [ TOKEN_NAME ]
    cmds:
      - task: kubernetes:create-generic-secret
        vars:
          GITLAB_ACCESS_TOKEN:
            sh: cat {{ .GITLAB_ACCESS_TOKENS_TEMPORARY_DIR }}/{{ .TOKEN_NAME }}.json | jq '.token'

          # Main variables (these are probably required)
          NAME: "test"
          NAMESPACE: "default"
          CONTENT: | 
            token={{ .GITLAB_ACCESS_TOKEN }}

The issue I'm facing is about expanding variables when using long lined strings in YAML. The following does not work:

CONTENT: | 
  token={{ .GITLAB_ACCESS_TOKEN }}

while the following does:

CONTENT: "{{ .GITLAB_ACCESS_TOKEN }}"

To deal with it, I have done an extended task that does exactly this, more or less. It's not perfect but t can be useful for users dealing with this until this is fixed in the main project:

  # This is a special task to create generic secrets on Kubernetes. It receives a variable called 'CONTENT'
  # which is a line-separated list of key=value to put into the secret. As Task can not expand variables in that way
  # I made the same using Golang template, so if some value matches the name of a defined variable, it's value will
  # be replaced with the value from the variable.
  #
  #  vars:
  #    TEST: test_value
  #    CONTENT: |
  #      token=TEST             -----> token=test_value
  #
  create-generic-secret:
    desc: Create a generic secret on your Kubernetes cluster
    summary: |
      Create a generic secret on your Kubernetes cluster
      
      It will delete existing secret before creating the new one.
      Please make sure you don't need the old one before starting.
    prompt: This will remove the previous existing secret if found... Do you want to continue?
    required:
      vars: [ NAME, NAMESPACE, CONTENT ]
    cmds:
      - kubectl delete secret {{ .NAME }} --namespace {{ .NAMESPACE | default "default" }}
      - |
          kubectl create secret generic {{ .NAME }} --namespace {{ .NAMESPACE | default "default" }}
          {{- $this := . -}}
          {{/* Each line should be a literal */}}
          {{- $lines := .CONTENT | splitLines -}}
          {{- range $i, $line := $lines -}}
        
            {{/* Drop lines not matching the pattern */}}
            {{- if not (regexMatch `(.*?)=(.*?)` $line) -}}
            {{- continue -}}
            {{- end -}}
        
            {{/* Replace vars on matching lines when possible */}}
            {{- $literalKeyValue := $line | split "=" -}}
        
            {{- $key := $literalKeyValue._0 -}}
            {{- $value := default $literalKeyValue._1 (get $this $literalKeyValue._1) -}}
            
            {{- printf " --from-literal %s=%s " $key $value -}} 
          {{- end -}}

  • Task version: v3.30.1 (h1:HdfCTAJDHoWL3+3RyY+o+0IK1O5xQaSBrZIq2SKOQ84=)
  • Operating system: Ubuntu 23.04
  • Experiments enabled: false

Can you take a look? :)

achetronic avatar Sep 25 '23 19:09 achetronic