twpayne / chezmoi

Manage your dotfiles across multiple diverse machines, securely.
https://www.chezmoi.io/
MIT License
13.36k stars 493 forks source link

Conditionals in config section of .chezmoi.yaml.tmpl throwing mapping values error #3266

Closed arrrgi closed 1 year ago

arrrgi commented 1 year ago

What exactly are you trying to do?

During chezmoi init I am prompting for details to populate into the scriptEnv and hcpVaultSecrets config arrays.

The chezmoi init command returns:

chezmoi: /Users/rgillson/.local/share/chezmoi/home/.chezmoi.yaml.tmpl: yaml: line 10: mapping values are not allowed in this context

I am having difficulty determining what is causing the errors and how I can achieve the outcome to conditionally set a number of chezmoi configuration values. A reproduction is available here: https://github.com/arrrgi/dotfiles/blob/77a5e27ba7ebfb4d3ea6f8ed43996cf5c60eb971/home/.chezmoi.yaml.tmpl

What have you tried so far?

This snippet results in the first error detailed above:

diff:
  pager: delta
scriptEnv:
{{ if eq .chezmoi.os "darwin" -}}
  {{ if eq .chezmoi.arch "arm64" -}}
  BREW_PATH: "/opt/homebrew/bin/brew"
  {{- else -}}
  BREW_PATH: "/usr/local/bin/brew"
  {{- end }}
{{- end }}
{{ if or $secrets.apikeys $secrets.sshkeys $secrets.storagekeys -}}
  {{- $_ := set $hcp "clientID" (promptStringOnce $hcp "clientID" "What is your Service Principal ID") -}}
  {{- $_ := set $hcp "clientSecret" (promptStringOnce $hcp "clientSecret" "What is your Service Principal Secret") -}}
  HCP_CLIENT_ID: {{ $hcp.clientID }}
  HCP_CLIENT_SECRET: {{ $hcp.clientSecret }}
encryption: age
age:
  identity: "{{ $.chezmoi.homeDir }}/.config/age/key.txt"
  recipient: "age..............."
hcpVaultSecrets:
  {{- $_ := set $hcp "orgID" (promptStringOnce $hcp "orgID" "What is your Vault Organisation ID") -}}
  {{- $_ := set $hcp "projectID" (promptStringOnce $hcp "projectID" "What is your Vault Project ID") -}}
  organizationId: {{ $hcp.orgID }}
  projectId: {{ $hcp.projectID }}
  applicationName: chezmoi
{{- end }}

I have also tried re-ordering and writing the OR condition for both conditional scenarios and this throws a different error:

chezmoi: /Users/rgillson/.local/share/chezmoi/home/.chezmoi.yaml.tmpl: yaml: line 4: did not find expected key

As an example:

diff:
  pager: delta
{{ if or $secrets.apikeys $secrets.sshkeys $secrets.storagekeys -}}
encryption: age
age:
  identity: "{{ $.chezmoi.homeDir }}/.config/age/key.txt"
  recipient: "age..............."
{{- end }}
scriptEnv:
{{ if eq .chezmoi.os "darwin" -}}
  {{ if eq .chezmoi.arch "arm64" -}}
  BREW_PATH: "/opt/homebrew/bin/brew"
  {{- else -}}
  BREW_PATH: "/usr/local/bin/brew"
  {{- end }}
{{- end }}
{{ if or $secrets.apikeys $secrets.sshkeys $secrets.storagekeys -}}
  {{- $_ := set $hcp "clientID" (promptStringOnce $hcp "clientID" "What is your Service Principal ID") -}}
  {{- $_ := set $hcp "clientSecret" (promptStringOnce $hcp "clientSecret" "What is your Service Principal Secret") -}}
  HCP_CLIENT_ID: {{ $hcp.clientID | quote }}
  HCP_CLIENT_SECRET: {{ $hcp.clientSecret | quote }}
hcpVaultSecrets:
  {{- $_ := set $hcp "orgID" (promptStringOnce $hcp "orgID" "What is your Vault Organisation ID") -}}
  {{- $_ := set $hcp "projectID" (promptStringOnce $hcp "projectID" "What is your Vault Project ID") -}}
  organizationId: {{ $hcp.orgID | quote }}
  projectId: {{ $hcp.projectID | quote }}
  applicationName: chezmoi
{{- end }}

Where else have you checked for solutions?

Output of any commands you've tried with --verbose flag

$ chezmoi --verbose init --data=false
chezmoi: /Users/rgillson/.local/share/chezmoi/home/.chezmoi.yaml.tmpl: yaml: line 10: mapping values are not allowed in this context

Output of chezmoi doctor

```console RESULT CHECK MESSAGE ok version v2.40.0, commit 6a8ca1634654734bb33a036ffb9c21e6b9f4d28d, built at 2023-09-19T09:56:08Z, built by goreleaser ok latest-version v2.40.0 ok os-arch darwin/arm64 ok uname Darwin elm-hwd-mni01p 22.6.0 Darwin Kernel Version 22.6.0: Wed Jul 5 22:22:52 PDT 2023; root:xnu-8796.141.3~6/RELEASE_ARM64_T8103 arm64 ok go-version go1.21.1 (gc) ok executable ~/.local/bin/chezmoi ok upgrade-method replace-executable ok config-file ~/.config/chezmoi/chezmoi.yaml, last modified 2023-09-29T21:12:33+10:00 warning source-dir ~/.local/share/chezmoi is a git working tree (dirty) warning suspicious-entries ~/.local/share/chezmoi/scratch/.chezmoiexternal copy.yaml warning working-tree ~/.local/share/chezmoi is a git working tree (dirty) ok dest-dir ~ is a directory ok umask 022 ok cd-command found /opt/homebrew/bin/zsh ok cd-args /opt/homebrew/bin/zsh info diff-command not set ok edit-command found /opt/homebrew/bin/nvim ok edit-args /opt/homebrew/bin/nvim ok git-command found /opt/homebrew/bin/git, version 2.42.0 ok merge-command found /usr/bin/vimdiff ok shell-command found /opt/homebrew/bin/zsh ok shell-args /opt/homebrew/bin/zsh ok age-command found /opt/homebrew/bin/age, version 1.1.1 info gpg-command gpg not found in $PATH info pinentry-command not set ok 1password-command found /opt/homebrew/bin/op, version 2.21.0 info bitwarden-command bw not found in $PATH info bitwarden-secrets-command bws not found in $PATH info dashlane-command dcli not found in $PATH info doppler-command doppler not found in $PATH info gopass-command gopass not found in $PATH info keepassxc-command keepassxc-cli not found in $PATH info keepassxc-db not set info keeper-command keeper not found in $PATH info lastpass-command lpass not found in $PATH info pass-command pass not found in $PATH info passhole-command ph not found in $PATH info rbw-command rbw not found in $PATH info vault-command vault not found in $PATH ok vlt-command found /opt/homebrew/bin/vlt, version 0.2.2 info secret-command not set ```

Additional context

Add any other context about the problem here.

arrrgi commented 1 year ago

Just a further comment to give context to what I'm trying to achieve:

  1. Setting scriptEnv with environment variables for Homebrew so that they are accessible in run_before scripts
  2. Setting scriptEnv config with environment variables for vlt by prompting for values when an earlier conditional is true so as not to store creds in code
  3. Setting the hcpVaultSecrets config values for vlt with the same conditional
  4. I'm trying to avoid creating a dependency on the vlt login and vlt config init commands during scripts (and in general any other user inputs in scripts) by having these values already set
twpayne commented 1 year ago

There is likely a syntax error in the YAML generated by your config file template.

Check that the output of

chezmoi execute-template --init < ~/.local/share/chezmoi/home/.chezmoi.yaml.tmpl

is valid YAML.

arrrgi commented 1 year ago

Can see that some of the inputs/keys are being concatenated together, or indented incorrectly. ie

diff:
  pager: delta
scriptEnv:
BREW_PATH: "/opt/homebrew/bin/brew"
HCP_CLIENT_ID: What is your Service Principal ID
  HCP_CLIENT_SECRET: What is your Service Principal Secret
encryption: age
age:
  identity: "/Users/rgillson/.config/age/key.txt"
  recipient: "age........"
hcpVaultSecrets:organizationId: What is your Vault Organisation ID
  projectId: What is your Vault Project ID
  applicationName: chezmoi
data:
  target:
    darwin: true
    debian: false
    devcontainer: false
    ubuntu: false
    wsl: false
  function:
    hybrid: false
    personal: true
    work: false
  access:
    controlled: true
    restricted: false
  privacy:
    private: true
    public: false
  state:
    ephemeral: false
    persistent: true
  secrets:
    apikeys: true
    sshkeys: false
    storagekeys: true
  git:
    email: "What is your Git associated email address"
    gh_username: "What is your GitHub username"
    name: "What is your full name"
arrrgi commented 1 year ago

I can see it needs the whitespace handling to be fixed, will update and close the ticket if this resolves the issue.

arrrgi commented 1 year ago

Closed. Needed to trim whitespace before the template functions. Thanks for the pointer again @twpayne 🙂