argoproj / argo-cd

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

Not possible to force autosync disabled #13098

Open mrysavy opened 1 year ago

mrysavy commented 1 year ago

Checklist:

Describe the bug

Application resource schema doesn't allow to force autosync disabled using GitOps way and app-of-apps pattern.

I have parent Application (app-of-apps pattern) which contains child Application resources only and which have autoSync with selfHeal enabled. I need this parent Application to force child Applications to have autoSync completely disabled. I need parent Application selfHeal to disable autoSync of child applications again when somebody enables it directly in Kubernetes.

Unfortunately, autosync is disabled only when spec.syncPolicy.automated is not present on resource and I don't know how to write child Application resources in the way that ArgoCD forces it in Kubernetes with field spec.syncPolicy.automated absent.

I've tried to use spec.syncPolicy: {} and spec.syncPolicy.automated: null but none of them works in ArgoCD (it means that in both cases in Git and spec.syncPolicy.automated: {} present in Kubernetes ArgoCD consider as Synced).

To Reproduce

First create parent Application:

cat <<EOF | kubectl create -f-
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: app-of-apps
  namespace: argocd1
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  destination:
    namespace: helm-guestbook-1
    server: https://kubernetes.default.svc
  project: default
  source:
    path: .
    repoURL: https://github.com/mrysavy/argocd-issue-autosync.git
    targetRevision: main
  syncPolicy:
    automated:
      selfHeal: true
      prune: true
EOF

My public GitHub repo contains two child Application resources, one with spec.syncPolicy: {} and the other with spec.syncPolicy.automated: null.

Now both child Applications are OutOfSync because it is specified in git.

$ argocd app list
NAME                      CLUSTER                         NAMESPACE         PROJECT  STATUS     HEALTH   SYNCPOLICY  CONDITIONS  REPO                                                  PATH            TARGET
argocd1/app-of-apps       https://kubernetes.default.svc  helm-guestbook-1  default  Synced     Healthy  Auto-Prune  <none>      https://github.com/mrysavy/argocd-issue-autosync.git  .               main
argocd1/helm-guestbook-1  https://kubernetes.default.svc  helm-guestbook-1  default  OutOfSync  Missing  <none>      <none>      https://github.com/argoproj/argocd-example-apps.git   helm-guestbook  master
argocd1/helm-guestbook-2  https://kubernetes.default.svc  helm-guestbook-2  default  OutOfSync  Missing  <none>      <none>      https://github.com/argoproj/argocd-example-apps.git   helm-guestbook  master

Than enable autoSync on both child Applications:

$ argocd app set --sync-policy auto --sync-option CreateNamespace=true helm-guestbook-1
$ argocd app set --sync-policy auto --sync-option CreateNamespace=true helm-guestbook-2

Now all Applications are Synced:

$ argocd app list
NAME                      CLUSTER                         NAMESPACE         PROJECT  STATUS  HEALTH       SYNCPOLICY  CONDITIONS  REPO                                                  PATH            TARGET
argocd1/app-of-apps       https://kubernetes.default.svc  helm-guestbook-1  default  Synced  Healthy      Auto-Prune  <none>      https://github.com/mrysavy/argocd-issue-autosync.git  .               main
argocd1/helm-guestbook-1  https://kubernetes.default.svc  helm-guestbook-1  default  Synced  Progressing  Auto        <none>      https://github.com/argoproj/argocd-example-apps.git   helm-guestbook  master
argocd1/helm-guestbook-2  https://kubernetes.default.svc  helm-guestbook-2  default  Synced  Progressing  Auto        <none>      https://github.com/argoproj/argocd-example-apps.git   helm-guestbook  master

And the problem is that although automatic synchronization on child Applications is supposed to be turned off, it is turned on, even though parent Application has selfHeal enabled.

SyncPolicy of first application from GIT:

$ argocd app manifests app-of-apps | yq 'select(.metadata.name == "helm-guestbook-1")' | yq '.spec.syncPolicy'
{}

and from Kubernetes cluster:

$ kubectl get application -n argocd1 helm-guestbook-1 -o yaml | yq '.spec.syncPolicy'
automated: {}
syncOptions:
  - CreateNamespace=true

SyncPolicy of second application from GIT:

$ argocd app manifests app-of-apps | yq 'select(.metadata.name == "helm-guestbook-2")' | yq '.spec.syncPolicy'
automated: null

and from Kubernetes cluster:

$ kubectl get application -n argocd1 helm-guestbook-2 -o yaml | yq '.spec.syncPolicy'
automated: {}
syncOptions:
  - CreateNamespace=true

Expected behavior

Expected behavior is to have a possibility to enforce autosync disabled on child Application by parent Application selfHeal. Proposal could be having a flag to disable autosync in automated block, like:

  syncPolicy:
    automated:
      disabled: true           <- new flag proposal
      prune: true
      selfHeal: true

Version

argocd: v2.6.7+5bcd846.dirty
  BuildDate: 2023-03-23T17:25:30Z
  GitCommit: 5bcd846fa16e4b19d8f477de7da50ec0aef320e5
  GitTreeState: dirty
  GoVersion: go1.20.2
  Compiler: gc
  Platform: linux/amd64
argocd-server: v2.6.7+5bcd846
  BuildDate: 2023-03-23T14:57:27Z
  GitCommit: 5bcd846fa16e4b19d8f477de7da50ec0aef320e5
  GitTreeState: clean
  GoVersion: go1.18.10
  Compiler: gc
  Platform: linux/amd64
  Kustomize Version: v4.5.7 2022-08-02T16:35:54Z
  Helm Version: v3.10.3+g835b733
  Kubectl Version: v0.24.2
  Jsonnet Version: v0.19.1
mrysavy commented 1 year ago

Another benefit of special flag (like syncPolicy.automated.disabled) could be possibility (in another case) to temporary disable autoSync+selfHeal of this field by it in managedFields under specific field manager and set this field manager to ignoreDifferences[].managedFieldsManagers.

jannfis commented 1 year ago

As selfHeal is a part of the auto sync feature, I don't think this is a valid bug but should be an enhancement request instead.

I'm also not sure I like the disabled semantics, it feels a little counter-intuitive as compared to having the flag named as enabled. But I see that, without making it a breaking change, there is probably no other possibility to specify a flag that controls the state of auto sync.

mrysavy commented 1 year ago

As selfHeal is a part of the auto sync feature, I don't think this is a valid bug but should be an enhancement request instead.

From my point of view this is a design bug, because ArgoCD as a GitOps tool should allow to manage autosync functionality in a GitOps way like all other functionalitites. But I don't want to start a flame :-)

mrysavy commented 1 year ago

I'm also not sure I like the disabled semantics, it feels a little counter-intuitive as compared to having the flag named as enabled. But I see that, without making it a breaking change, there is probably no other possibility to specify a flag that controls the state of auto sync.

Flag enabled (with true as default for backward compatibility) is also the right solution in my use cases

alexef commented 1 year ago

this relates to https://github.com/argoproj/argo-cd/issues/8686

vovtz commented 11 months ago

Today looked into declaratively generating auto sync from an Application Set, depending on a value from a YAML file (using the Git File Generator). With the limited Go templating options available within an AS, I cannot make that work. If the toggle becomes more ‘natural’, acting on the value of a key called enabled, not on the existence of a key, that might be easier; but there’s still the limitation that a Go template there cannot render a boolean value :(

gergokee commented 9 months ago

This is an important feature which is missing, we bumped into this problem too...

shawnsavour commented 3 months ago

No updates for many years? so sad for that. many problems while templating the argocd

NITHIN-JOHN-GEORGE commented 3 months ago

+1 for this.