Skip to content

Trailing newlines in literal breaks correct escaping of commas #752

@metrictwo

Description

@metrictwo

Current Behavior

We run ArgoCD and have one dynamic parameter used to create cronjobs. ArgoCD Helm parameters are internally translated to `--set <param_key>=<param_value>. While trying to switch to the wrapper script, I found some incorrect escaping of commas. Given the following (greatly simplified) template:

{{- $cronjobs := fromYaml ($.Values.cronjobs | default "{}") -}}
{{- range $cronjob := $cronjobs.cronjobs -}}
---
apiVersion: batch/v1
kind: CronJob
metadata:
  name: {{ $cronjob.name }}
spec:
  schedule: {{ $cronjob.schedule | quote }}
{{- end }}

The helm-secrets wrapper double-escapes commas when a trailing newline is present, as there is when a multi-line parameter is used in ArgoCD:

$ HELM_SECRETS_WRAPPER_ENABLED=true helm template . --set "cronjobs=cronjobs:
  - name: test
    schedule: 7\,19\,31 * * * *
"
# Source: front/templates/cronjobs.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: test
spec:
  schedule: "7\\,19\\,31 * * * *"

Expected Behavior

Here's the normal helm output:

$ HELM_SECRETS_WRAPPER_ENABLED=false helm template . --set "cronjobs=cronjobs:
  - name: test
    schedule: 7\,19\,31 * * * *
"
---
# Source: front/templates/cronjobs.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: test
spec:
  schedule: "7,19,31 * * * *"

Same result with the wrapper when no trailing newline is present:

$ HELM_SECRETS_WRAPPER_ENABLED=true helm template . --set "cronjobs=cronjobs:
  - name: test
    schedule: 7\,19\,31 * * * *"
# Source: front/templates/cronjobs.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: test
spec:
  schedule: "7,19,31 * * * *"

Steps To Reproduce

See chart/command above.

Environment

  • Helm Version:3.19.4
  • Helm Secrets Version: 4.6.10
  • ArgoCD Version: 3.3.6
  • OS: Linux (container)
  • Shell: sh/bash

Anything else?

With some local debugging, I've tracked the issue to helm.sh:

                if ! decrypted_literal=$(backend_decrypt_literal "${literal}"); then
                    fatal 'Unable to decrypt literal value %s' "${literal}"
                fi

                if [ "${decrypted_literal}" = "${literal}" ]; then
                    decrypted_literals="${decrypted_literals}${opt_prefix}${decrypted_literal},"
                else
                    decrypted_literals="${decrypted_literals}${opt_prefix}$(printf '%s' "${decrypted_literal}" | sed -e 's/\\/\\\\/g' | sed -e 's/,/\\,/g'),"
                fi

In the very first line, decrypted_literal receives the result of a command expansion, which is meant to be a no-op, but shell command expansion always removes trailing newlines. As a result, if [ "${decrypted_literal}" = "${literal}" ]; then fails and triggers the (here unnecessary) sed substitutions at the end of the block.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions