ArgoCD Application cannot Remove AutoSync Option via Sync of App-of-apps
- Dominant language
- Go
- Stars
- 24.2k
- Forks
- 7.8k
- Avg merge
- 1d 6h
- Merged PRs (30d)
- 239
Description
Checklist:
* [x] I've searched in the docs and FAQ for my answer: https://bit.ly/argocd-faq.
* [x] I've included steps to reproduce the bug.
* [x] I've pasted the output of `argocd version`.
**Describe the bug**
In ArgoCD's Application, if the desired manifests of application's sync policy is `null` (no auto-sync), and the policy is later on added an auto-sync option, argo-cd will not be able to find out the diff and will not be able to revert `syncPolicy` back to `null` in the subsequent sync.
**To Reproduce**
1. Create an application with app-of-apps, e.g. :
Parent App:
```
project: my-proj
source:
repoURL: 'my-repo-utl'
path: argo-app
targetRevision: master
helm:
valueFiles:
- deploy/values-dev.yaml
destination:
server: 'https://kubernetes.default.svc'
namespace: infra-argocd
syncPolicy:
automated:
prune: true
selfHeal: true
```
As long as the child application is generated as follows with an empty sync policy:
Child Application:
```
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
labels:
argocd.argoproj.io/instance: agent-child-app
name: test-argo-child-app
namespace: infra-argocd
spec:
destination:
name: my-cluster
namespace: my-namespace
project: my-proj
source:
helm:
valueFiles:
- my-helm-files.yaml
path: child-charts/
repoURL: 'my-child-repo.url'
targetRevision: HEAD
syncPolicy: null
```
And after sync child app, use a kubectl patch to patch child app with a sync policy:
```
kubectl -n infra-argocd patch applications.argoproj.io test-argo-child-app --type=json --patch='[
{
"op": "add",
"path": "/spec/syncPolicy",
"value": {
"automated": {
"prune": true,
"selfHeal": true
}
}
}
]'
```
The child application will have auto-sync enabled now, but when viewing from ArgoCD's UI, there's no Diff from Child Application's desired manifests & live manifests, and when trying to sync from Parent App, the child app's sync policy will not be reverted.
**Expected behavior**
Parent App should be able to change child App's `syncPolicy` back to `null` after sync, and diff should be detected.
**Screenshots**
Live Manifests: (there's auto-update strategy)
Desired Manifests:
Diff is Empty:
**Version**
Components Version:
```
{
"Version": "v2.10.0+cb5f76c.dirty",
"BuildDate": "2024-02-16T19:38:16Z",
"GitCommit": "cb5f76cc4eca82cd02c837b16de5ca33f4972e4d",
"GitTreeState": "dirty",
"GoVersion": "go1.21.6",
"Compiler": "gc",
"Platform": "linux/amd64",
"KustomizeVersion": "v4.4.1 2021-11-11T23:36:27Z",
"HelmVersion": "v3.7.1+g1d11fcb",
"KubectlVersion": "v0.26.11",
"JsonnetVersion": "v0.20.0"
}
```
**Additional Notes**
From the code in ArgoCD, the behavior is due to a ThreeWayMerge ignoring the `null` fields in syncPolicy. But this also results in the parent app cannot revert back the child app's `syncPolicy` once changed externally (not via gitops). And for my understanding, setting `syncPolicy` to `null` means "I want sync policy to be disabled", and here it turned out to be "sync policy is unspecified". If we can have a boolean option that explicitly specify whether we want `auto-sync` to be on/off, this could be resolved
Contributor guide
Research direction
The report provides an app-of-apps reproduction and identifies ThreeWayMerge handling of null syncPolicy fields as the suspected area. Start by reproducing the parent and child Application sequence, then inspect the ThreeWayMerge path used for Application sync and diff calculation. Done means the desired null policy produces a diff and syncing the parent removes the child application's externally added auto-sync policy.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, kubernetes
- Domain
- ci-cd, devops
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 28/100