argoproj / argo-cd

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

`argocd app diff` does not appear to recognize the migration of a app from yaml to jsonnet #17499

Open scubbo opened 6 months ago

scubbo commented 6 months ago

Checklist:

Describe the bug

For an intra-repo app-of-apps (i.e. a top-level manifest which declares a spec.source.path as a directory containing other Application definitions) argocd app diff --local correctly identifies when a .yaml file is changed, but perceives a (no-op) migration from a .yaml file to a .jsonnet file as the removal of the (sub-)application from local specification.

To Reproduce

  1. Create app-of-apps as in this commit (replication on your own cluster will have to change the source to your own forked repo):
# main-manifest.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: argocd-jsonnet-app-diff-demo
  namespace: argo # Note non-standard installation namespace, which might catch you out when replicating.
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  project: default

  source:
    repoURL: https://gitea.scubbo.org/scubbo/argocd-jsonnet-app-diff-demo.git
    targetRevision: HEAD
    path: app-of-apps

  destination:
    server: "https://kubernetes.default.svc"
    namespace: default

  syncPolicy:
    automated:
      prune: true
    syncOptions:
    - CreateNamespace=true

# app-of-apps/guestbook.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: helm-guestbook
  namespace: argo
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  destination:
    namespace: helm-guestbook
    server: https://kubernetes.default.svc
  project: default
  source:
    path: helm-guestbook
    repoURL: https://github.com/argoproj/argocd-example-apps
    targetRevision: HEAD
  syncPolicy:
    syncOptions:
      - CreateNamespace=true
  1. Confirm app is deployed as expected:
$ argocd app list | grep -e 'jsonnet' -e 'guestbook'
argo/argocd-jsonnet-app-diff-demo   https://kubernetes.default.svc  default            default  Synced     Healthy  <none>      <none>           https://gitea.scubbo.org/scubbo/argocd-jsonnet-app-diff-demo  app-of-apps/                        HEAD
argo/helm-guestbook                 https://kubernetes.default.svc  helm-guestbook     default  Synced     Healthy  <none>      <none>           https://github.com/argoproj/argocd-example-apps               helm-guestbook                      HEAD
  1. Confirm that app diff --local shows no diff when applied to the top-level app:
$ argocd app diff --local $PWD argocd-jsonnet-app-diff-demo --server-side-generate
[no output]
  1. Confirm that app diff --local does identify a trivial change to a local file:
# Edit `app-of-apps/guestbook.yaml` to contain...
...
metadata:
  labels:
    this-is: an-arbitrary-label
...

$ argocd app diff --local $PWD argocd-jsonnet-app-diff-demo --server-side-generate
===== argoproj.io/Application argo/helm-guestbook ======
11a12
>     this-is: an-arbitrary-label
  1. Convert the yaml definition of the subapp to a jsonnet definition (note this is illustrated with a commit here, but you should make this change locally, without pushing it to your Git repo, as the objective here is to test the ability for argocd app diff to recognize a no-op local reformatting when the deployed Application has not been changed):
# Delete app-of-apps/guestbook.yaml, and replace with app-of-apps/guestbook.jsonnet

{
    apiVersion: "argoproj.io/v1alpha1",
    kind: "Application",
    metadata: {
        name: "helm-guestbook",
        namespace: "argo",
        finalizers: [
            "resources-finalizer.argocd.argoproj.io"
        ]
    },
    spec: {
        destination: {
            namespace: "helm-guestbook",
            server: "https://kubernetes.default.svc"
        },
        project: "default",
        source: {
            path: "helm-guestbook",
            repoURL: "https://github.com/argoproj/argocd-example-apps",
            targetRevision: "HEAD"
        },
        syncPolicy: {
            syncOptions: [
                "CreateNamespace=true"
            ]
        }
    }
}

Expected behavior

$ argocd app diff --local $PWD argocd-jsonnet-app-diff-demo --server-side-generate should show a no-op, as the local jsonnet definition of the sub-app helm-guestbook matches the deployed Application

Actual Behaviour

app diff indicates that helm-guestbook is a deployed Application which is entirely unrepresented in the local files.

Screenshots

image

(The console output goes on, but you get the idea)

Version

argocd: v2.10.2+fcf5d8c.dirty
  BuildDate: 2024-03-02T00:44:35Z
  GitCommit: fcf5d8c2381b68ab1621b90be63913b12cca2eb7
  GitTreeState: dirty
  GoVersion: go1.22.0
  Compiler: gc
  Platform: darwin/amd64
argocd-server: v2.10.2+fcf5d8c.dirty
  BuildDate: 2024-03-02T00:44:35Z
  GitCommit: fcf5d8c2381b68ab1621b90be63913b12cca2eb7
  GitTreeState: dirty
  GoVersion: go1.22.0
  Compiler: gc
  Platform: darwin/amd64
  Kustomize Version: could not get kustomize version: exec: "kustomize": executable file not found in $PATH
  Helm Version: v3.13.1+g3547a4b
  Kubectl Version: v0.26.11
  Jsonnet Version: v0.20.0

Logs

N/A

Motivation

The reason I'm doing this in the first place is - I have a bunch of very repetitiously-defined Applications that I would like to convert to a jsonnet representation so that I can extract all the boilerplate to jsonnet functions and just specify the parameters that vary - but I want to validate that the jsonnet representation is a no-op diff before I deploy it.

scubbo commented 6 months ago

D'oh - I found the issue:

$ argocd app diff --help | grep 'local-include'
      --local-include stringArray   Used with --server-side-generate, specify patterns of filenames to send. Matching is based on filename and not path. (default [*.yaml,*.yml,*.json])

When I ran $ argocd app diff --local $PWD argocd-jsonnet-app-diff-demo --server-side-generate --local-include '*.yaml' --local-include '*.jsonnet', the behaviour was as-expected.

Keeping this open in case this is still considered a bug - I would expect the defaults for argocd app diff to match the default behaviour of Argo itself, i.e. to handle *.jsonnet files without any special flags being passed - but I do agree that this is working as documented and could justifiably be closed.