argoproj / argo-cd

Declarative Continuous Deployment for Kubernetes
https://argo-cd.readthedocs.io
Apache License 2.0
18.04k stars 5.51k forks source link

Go templated appsets mutating nested parameters #15444

Open brucec5 opened 1 year ago

brucec5 commented 1 year ago

Checklist:

Describe the bug

When using go templating, the matrix generator seems to create aliased maps. This is a problem when using the matrix generator alongside a merge generator, since if one of the matching parameter sets modifies a map in the base config it will end up getting updated for all other clusters. I'm sorry if I'm bad at explaining this.

To Reproduce

go-template appset ```yaml apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: nested-config-test-appset-go-templating spec: generators: - merge: mergeKeys: [name] generators: - matrix: # Set base config for all clusters generators: - git: repoURL: https://example.com/my-applications revision: HEAD files: - path: "nested-config-test/config.yaml" - clusters: selector: matchLabels: argocd.argoproj.io/secret-type: cluster production: "false" - git: # Apply per-cluster overrides on top of the base config repoURL: https://example.com/my-applications revision: HEAD files: - path: "nested-config-test/config/*.yaml" goTemplate: true goTemplateOptions: ["missingkey=error"] template: metadata: name: 'nested-config-test-appset-go-{{ .name }}' spec: project: example source: repoURL: https://example.com/test-chart path: . targetRevision: '{{ .revision }}' helm: releaseName: '{{ .releaseName }}' valueFiles: - values.yaml parameters: - name: nestedConfig.enabled value: '{{ .nestedConfig.enabled }}' destination: name: '{{ .name }}' namespace: '{{ .namespace }}' ```
traditional appset ```yaml apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: nested-config-test-appset spec: generators: - merge: mergeKeys: [name] generators: - matrix: # Set base config for all clusters generators: - git: repoURL: https://example.com/my-applications revision: HEAD files: - path: "nested-config-test/config.yaml" - clusters: selector: matchLabels: argocd.argoproj.io/secret-type: cluster production: "false" - git: # Apply per-cluster overrides on top of the base config repoURL: https://example.com/my-applications revision: HEAD files: - path: "nested-config-test/config/*.yaml" template: metadata: name: 'nested-config-test-appset-{{ name }}' spec: project: example source: repoURL: https://example.com/test-chart path: . targetRevision: '{{ revision }}' helm: releaseName: '{{ releaseName }}' valueFiles: - values.yaml parameters: - name: nestedConfig.enabled value: '{{ nestedConfig.enabled }}' destination: name: '{{ name }}' namespace: '{{ namespace }}' ```
nested-config-test/config.yaml ```yaml revision: 1.2.3 namespace: test-ns nestedConfig: enabled: true ```
nested-config-test/config/qa.yaml ```yaml name: qa nestedConfig: enabled: false ```

Expected behavior

I'd expect all clusters except for the qa cluster have the nestedConfig.enabled helm parameter set to true. This was the case for the traditional templating. However, with Go templating nestedConfig.enabled ends up getting set to false everywhere. A workaround is to just not nest configuration provided by the git files generator, but this still feels like a bug that should be fixed.

Screenshots

Version

argocd: v2.8.3+77556d9
  BuildDate: 2023-09-07T16:05:43Z
  GitCommit: 77556d9e64304c27c718bb0794676713628e435e
  GitTreeState: clean
  GoVersion: go1.20.6
  Compiler: gc
  Platform: linux/amd64
FATA[0000] Argo CD server address unspecified
AtzeDeVries commented 1 year ago

is this not a know restriction with goTemplate: true ?

https://argo-cd.readthedocs.io/en/stable/operator-manual/applicationset/Generators-Merge/#restrictions number 4

brucec5 commented 1 year ago

I interpreted that as specifically referring to using a nested key as the merge key in the merge generator. In my case, I'm merging on name, so that should be allowed.