argoproj / argo-cd

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

go template in argocd app of apps #7367

Closed dmitry-mightydevops closed 5 months ago

dmitry-mightydevops commented 2 years ago

Summary

I'm using argocd 2.1.2 via helm chart.

So i have a root app looking into git@github.com:org/gitops.git

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: root
  namespace: argo-cd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  destination:
    server: https://kubernetes.default.svc
    namespace: argo-cd
  project: default
  source:
    path: staging/argocd/apps/
    repoURL: git@github.com:org/gitops.git
    targetRevision: main
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

inside staging/argocd/apps I have prometheus app, based on community chart, where I define custom alertmanager slack notification templates as shown below

staging/argocd/apps/prometheus.yaml

        alertmanagerFiles:          
          notifications.tmpl: |

            {{ define "__alert_silence_link" -}}
               {{ .ExternalURL }}/#/silences/new?filter=%7B
               {{- range .CommonLabels.SortedPairs -}}
                   {{- if ne .Name "alertname" -}}
                       {{- .Name }}%3D"{{- .Value -}}"%2C%20
                   {{- end -}}
               {{- end -}}
               alertname%3D"{{- .CommonLabels.alertname -}}"%7D
            {{- end }}

            {{ define "__alert_severity" -}}
            {{- if eq .CommonLabels.severity "critical" -}}
            *Severity:* `Critical` {{ if eq .Status "firing" }}:fire:{{- else -}}:ok:{{- end -}}
            {{- else if eq .CommonLabels.severity "warning" -}}
            *Severity:* `Warning`
            {{- else if eq .CommonLabels.severity "info" -}}
            *Severity:* `Info`
            {{- else -}}
            *Severity:* :question: {{ .CommonLabels.severity }}
            {{- end }}
            {{- end }}

            {{ define "__alert_client_details" -}}
               *Env:*     {{ .CommonLabels.env }}
               *Client:*  {{ .CommonLabels.client }}
               *Cluster:* {{ .CommonLabels.cluster }}
            {{- end }}

            {{ define "slack.title" -}}
               [{{ .Status | toUpper -}}
               {{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{- end -}}
               ] {{ .CommonLabels.cluster }} - {{ .CommonLabels.alertname }}
            {{- end }}

            {{ define "slack.text" -}}
               {{ .CommonLabels.opsteam }}
               {{ template "__alert_severity" . }}
               {{ template "__alert_client_details" . }}
               {{- if (index .Alerts 0).Annotations.summary }}
               {{- "\n" -}}
               *Summary:* {{ (index .Alerts 0).Annotations.summary }}
               {{- end }}

               {{ range .Alerts }}      
               {{- if .Annotations.description }}                   
               {{ .Annotations.description }}{{- "\n" -}}
               {{- end }}
               {{- if .Annotations.message }}
               {{ .Annotations.message }}{{- "\n" -}}
               {{- end }}
               {{- end }}

            {{- end }}

            {{ define "slack.color" -}}
               {{ if eq .Status "firing" -}}
                   {{ if eq .CommonLabels.severity "warning" -}}
                       warning
                   {{- else if eq .CommonLabels.severity "critical" -}}
                       danger
                   {{- else -}}
                       #439FE0
                   {{- end -}}
               {{ else -}}
               good
               {{- end }}
            {{- end }}

            {{ define "slack.pretext" -}}
               {{ .CommonAnnotations.summary }}
            {{- end }}

            {{ define "slack.footer" -}}
               {{ .CommonLabels.cluster }}               
            {{- end }}

I can apply this app via kubectl without any issues

✗  k apply -f staging/argocd/apps/templates/prometheus.yaml
application.argoproj.io/prometheus unchanged

However if I submit into git and then call for root sync I get this Error: parse error at (root/templates/prometheus.yaml:127): function "toUpper" not defined

Target:             main
Path:               staging/argocd/apps/
SyncWindow:         Sync Allowed
Sync Policy:        Automated (Prune)
Sync Status:        Unknown
Health Status:      Healthy

Operation:          Sync
Sync Revision:      
Phase:              Error
Start:              2021-10-04 16:11:51 -0700 PDT
Finished:           2021-10-04 16:11:51 -0700 PDT
Duration:           0s
Message:            ComparisonError: rpc error: code = Unknown desc = Manifest generation error (cached): `helm template . --name-template root --namespace argo-cd --kube-version 1.21 --api-versions acme.cert-manager.io/v1 --api-versions acme.cert-manager.io/v1alpha2 --api-versions acme.cert-manager.io/v1alpha3 --api-versions acme.cert-manager.io/v1beta1 --api-versions admissionregistration.k8s.io/v1 --api-versions admissionregistration.k8s.io/v1beta1 --api-versions apiextensions.k8s.io/v1 --api-versions apiextensions.k8s.io/v1beta1 --api-versions apiregistration.k8s.io/v1 --api-versions apiregistration.k8s.io/v1beta1 --api-versions apps/v1 --api-versions argoproj.io/v1alpha1 --api-versions authentication.k8s.io/v1 --api-versions authentication.k8s.io/v1beta1 --api-versions authorization.k8s.io/v1 --api-versions authorization.k8s.io/v1beta1 --api-versions autoscaling/v1 --api-versions autoscaling/v2beta1 --api-versions autoscaling/v2beta2 --api-versions batch/v1 --api-versions batch/v1beta1 --api-versions cert-manager.io/v1 --api-versions cert-manager.io/v1alpha2 --api-versions cert-manager.io/v1alpha3 --api-versions cert-manager.io/v1beta1 --api-versions certificates.k8s.io/v1 --api-versions certificates.k8s.io/v1beta1 --api-versions coordination.k8s.io/v1 --api-versions coordination.k8s.io/v1beta1 --api-versions crd.k8s.amazonaws.com/v1alpha1 --api-versions dashboard.tekton.dev/v1alpha1 --api-versions discovery.k8s.io/v1 --api-versions discovery.k8s.io/v1beta1 --api-versions events.k8s.io/v1 --api-versions events.k8s.io/v1beta1 --api-versions extensions/v1beta1 --api-versions flowcontrol.apiserver.k8s.io/v1beta1 --api-versions metrics.k8s.io/v1beta1 --api-versions networking.k8s.io/v1 --api-versions networking.k8s.io/v1beta1 --api-versions node.k8s.io/v1 --api-versions node.k8s.io/v1beta1 --api-versions policy/v1 --api-versions policy/v1beta1 --api-versions rbac.authorization.k8s.io/v1 --api-versions rbac.authorization.k8s.io/v1beta1 --api-versions scheduling.k8s.io/v1 --api-versions scheduling.k8s.io/v1beta1 --api-versions storage.k8s.io/v1 --api-versions storage.k8s.io/v1beta1 --api-versions tekton.dev/v1alpha1 --api-versions tekton.dev/v1beta1 --api-versions triggers.tekton.dev/v1alpha1 --api-versions triggers.tekton.dev/v1beta1 --api-versions v1 --api-versions velero.io/v1 --api-versions vpcresources.k8s.aws/v1beta1 --include-crds` failed exit status 1: Error: parse error at (root/templates/prometheus.yaml:127): function "toUpper" not defined

Motivation

Support go templates inside yaml files.

mikebryant commented 2 years ago

I wonder if it's auto-detecting it as a helm-chart-in-a-repo?

What happens if you try?:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: root
  namespace: argo-cd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  destination:
    server: https://kubernetes.default.svc
    namespace: argo-cd
  project: default
  source:
    directory:
      recurse: true
    path: staging/argocd/apps/
    repoURL: git@github.com:org/gitops.git
    targetRevision: main
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

(The directory section under source)

nmajin commented 2 years ago

I believe I may be running into a similar situation and I think ArgoCD is in fact expecting a Helm chart values variable to be coming through instead of go-template variable...

I am trying to use an existing secret and pass that into the body of this API call:

...
      body: |
       {"username": "{{ .auth.username }}", "password": "{{ .auth.password }}"}
      secrets:
      - name: auth
        secretRef:
          name: external-secrets-test-secret

However, ArgoCD is complaining the following:

rpc error: code = Unknown desc = Manifest generation error (cached): `helm template...--values ../../<app in git>/values.yaml 
...
at <.auth.username>: nil pointer evaluating interface {}.username Use --debug flag to render out invalid YAML

So I am going to assume we can't use go-templates in ArgoCD then?

blakepettersson commented 1 year ago

You can use Go Templates in ApplicationSets since 2.5.x.