From 78644c97b4dbbe721995dd3911f80cd9727a9da4 Mon Sep 17 00:00:00 2001 From: kahoulei Date: Tue, 21 May 2024 14:35:34 -0700 Subject: [PATCH 01/21] feat: Add ignore-resources-tracking annotation to ignore resources update Signed-off-by: kahoulei --- controller/cache/cache.go | 17 ++++++++++++++++- controller/cache/info.go | 5 +++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/controller/cache/cache.go b/controller/cache/cache.go index ddfe2b17fdc31..88112463fdaef 100644 --- a/controller/cache/cache.go +++ b/controller/cache/cache.go @@ -9,6 +9,7 @@ import ( "net/url" "os/exec" "reflect" + "strconv" "strings" "sync" "syscall" @@ -67,6 +68,9 @@ const ( // EnvClusterCacheRetryUseBackoff is the env variable to control whether to use a backoff strategy with the retry during cluster cache sync EnvClusterCacheRetryUseBackoff = "ARGOCD_CLUSTER_CACHE_RETRY_USE_BACKOFF" + + // AnnotationIgnoreResourcesTracking is a Kubernetes annotation for a Kubernetes resource to ignore any resources tracking + AnnotationIgnoreResourcesTracking = "argocd.argoproj.io/ignore-resources-tracking" ) // GitOps engine cluster cache tuning options @@ -161,6 +165,9 @@ type ResourceInfo struct { NodeInfo *NodeInfo manifestHash string + + // annotations stores all the ObjectRef annotations + annotations map[string]string } func NewLiveStateCache( @@ -342,6 +349,14 @@ func skipAppRequeuing(key kube.ResourceKey) bool { } func skipResourceUpdate(oldInfo, newInfo *ResourceInfo) bool { + if val, ok := newInfo.annotations[AnnotationIgnoreResourcesTracking]; ok { + // ignore the error and fall through the further checking + skip, _ := strconv.ParseBool(val) + if skip { + return true + } + } + if oldInfo == nil || newInfo == nil { return false } @@ -549,7 +564,7 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e "name": ref.Name, "api-version": ref.APIVersion, "kind": ref.Kind, - }).Debug("Ignoring change of object because none of the watched resource fields have changed") + }).Debugf("Ignoring change of object because none of the watched resource fields have changed or annotation %v is set to true", AnnotationIgnoreResourcesTracking) } return } diff --git a/controller/cache/info.go b/controller/cache/info.go index 0734e2d118678..4969a2d28f673 100644 --- a/controller/cache/info.go +++ b/controller/cache/info.go @@ -45,6 +45,11 @@ func populateNodeInfo(un *unstructured.Unstructured, res *ResourceInfo, customLa } res.NetworkingInfo.ExternalURLs = append(res.NetworkingInfo.ExternalURLs, v) } + + if res.annotations == nil { + res.annotations = make(map[string]string) + } + res.annotations[k] = v } switch gvk.Group { From a22404e5193daf3e01c59c2db6b613bc8d0a5328 Mon Sep 17 00:00:00 2001 From: kahoulei Date: Wed, 22 May 2024 08:02:25 -0700 Subject: [PATCH 02/21] add doc Signed-off-by: kahoulei --- docs/operator-manual/reconcile.md | 50 +++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/docs/operator-manual/reconcile.md b/docs/operator-manual/reconcile.md index a956cd9cf7b28..312ba7e573576 100644 --- a/docs/operator-manual/reconcile.md +++ b/docs/operator-manual/reconcile.md @@ -111,3 +111,53 @@ data: # actually changing in content. - .status.conditions[].lastTransitionTime ``` + +## Completely ignore resources update + +There is an use case that you would like to completely ignore the resources at all. This mostly happens when some dependent +resources are created by another resource (e.g. a Job and a Pod are created by a CronJob and you want to ignore the Job +and the Pod). + +For this use case, the above configurations will not help because argocd will still reconcile any newly created objects. + +To completely ignore a newly created object, you need to add annotation `argocd.argoproj.io/ignore-resources-tracking=true` +to the target resource manifest. + +## Example + +### CronJob + +``` +apiVersion: batch/v1 +kind: CronJob +metadata: + name: hello + namespace: test-cronjob +spec: + schedule: "* * * * *" + jobTemplate: + metadata: + annotations: + argocd.argoproj.io/ignore-resources-tracking: "true" + spec: + template: + metadata: + annotations: + argocd.argoproj.io/ignore-resources-tracking: "true" + spec: + containers: + - name: hello + image: busybox:1.28 + imagePullPolicy: IfNotPresent + command: + - /bin/sh + - -c + - date; echo Hello from the Kubernetes cluster + restartPolicy: OnFailure +``` + +And you should see the following debug message (if enabled) in the `application-controller` log: + +``` +Ignoring change of object because none of the watched resource fields have changed or annotation argocd.argoproj.io/ignore-resources-tracking is set to true +``` From 5157dce2548288b5bbf8d046e03073443c576c12 Mon Sep 17 00:00:00 2001 From: kahoulei Date: Wed, 22 May 2024 10:57:15 -0700 Subject: [PATCH 03/21] update annotation doc Signed-off-by: kahoulei --- docs/user-guide/annotations-and-labels.md | 31 ++++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/docs/user-guide/annotations-and-labels.md b/docs/user-guide/annotations-and-labels.md index 032824c8708f3..50cc023bb02f4 100644 --- a/docs/user-guide/annotations-and-labels.md +++ b/docs/user-guide/annotations-and-labels.md @@ -2,21 +2,22 @@ ## Annotations -| Annotation key | Target resource(es) | Possible values | Description | -|--------------------------------------------|---------------------|---------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| argocd.argoproj.io/application-set-refresh | ApplicationSet | `"true"` | Added when an ApplicationSet is requested to be refreshed by a webhook. The ApplicationSet controller will remove this annotation at the end of reconciliation. | -| argocd.argoproj.io/compare-options | any | [see compare options docs](compare-options.md) | Configures how an app's current state is compared to its desired state. | -| argocd.argoproj.io/hook | any | [see resource hooks docs](resource_hooks.md) | Used to configure [resource hooks](resource_hooks.md). | -| argocd.argoproj.io/hook-delete-policy | any | [see resource hooks docs](resource_hooks.md#hook-deletion-policies) | Used to set a [resource hook's deletion policy](resource_hooks.md#hook-deletion-policies). | -| argocd.argoproj.io/manifest-generate-paths | Application | [see scaling docs](../operator-manual/high_availability.md#webhook-and-manifest-paths-annotation) | Used to avoid unnecessary Application refreshes, especially in mono-repos. | -| argocd.argoproj.io/refresh | Application | `normal`, `hard` | Indicates that app needs to be refreshed. Removed by application controller after app is refreshed. Value `"hard"` means manifest cache and target cluster state cache should be invalidated before refresh. | -| argocd.argoproj.io/skip-reconcile | Application | `"true"` | Indicates to the Argo CD application controller that the Application should not be reconciled. See the [skip reconcile documentation](skip_reconcile.md) for use cases. | -| argocd.argoproj.io/sync-options | any | [see sync options docs](sync-options.md) | Provides a variety of settings to determine how an Application's resources are synced. | -| argocd.argoproj.io/sync-wave | any | [see sync waves docs](sync-waves.md) | | -| argocd.argoproj.io/tracking-id | any | any | Used by Argo CD to track resources it manages. See [resource tracking docs](resource_tracking.md) for details. | -| link.argocd.argoproj.io/{some link name} | any | An http(s) URL | Adds a link to the Argo CD UI for the resource. See [external URL docs](external-url.md) for details. | -| pref.argocd.argoproj.io/default-pod-sort | Application | [see UI customization docs](../operator-manual/ui-customization.md) | Sets the Application's default grouping mechanism. | -| pref.argocd.argoproj.io/default-view | Application | [see UI customization docs](../operator-manual/ui-customization.md) | Sets the Application's default view mode (e.g. "tree" or "list") | +| Annotation key | Target resource(es) | Possible values | Description | +|----------------------------------------------|---------------------|---------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| argocd.argoproj.io/application-set-refresh | ApplicationSet | `"true"` | Added when an ApplicationSet is requested to be refreshed by a webhook. The ApplicationSet controller will remove this annotation at the end of reconciliation. | +| argocd.argoproj.io/compare-options | any | [see compare options docs](compare-options.md) | Configures how an app's current state is compared to its desired state. | +| argocd.argoproj.io/hook | any | [see resource hooks docs](resource_hooks.md) | Used to configure [resource hooks](resource_hooks.md). | +| argocd.argoproj.io/hook-delete-policy | any | [see resource hooks docs](resource_hooks.md#hook-deletion-policies) | Used to set a [resource hook's deletion policy](resource_hooks.md#hook-deletion-policies). | +| argocd.argoproj.io/manifest-generate-paths | Application | [see scaling docs](../operator-manual/high_availability.md#webhook-and-manifest-paths-annotation) | Used to avoid unnecessary Application refreshes, especially in mono-repos. | +| argocd.argoproj.io/refresh | Application | `normal`, `hard` | Indicates that app needs to be refreshed. Removed by application controller after app is refreshed. Value `"hard"` means manifest cache and target cluster state cache should be invalidated before refresh. | +| argocd.argoproj.io/skip-reconcile | Application | `"true"` | Indicates to the Argo CD application controller that the Application should not be reconciled. See the [skip reconcile documentation](skip_reconcile.md) for use cases. | +| argocd.argoproj.io/sync-options | any | [see sync options docs](sync-options.md) | Provides a variety of settings to determine how an Application's resources are synced. | +| argocd.argoproj.io/sync-wave | any | [see sync waves docs](sync-waves.md) | | +| argocd.argoproj.io/tracking-id | any | any | Used by Argo CD to track resources it manages. See [resource tracking docs](resource_tracking.md) for details. | +| argocd.argoproj.io/ignore-resources-tracking | any | `"true"` | Used by Argo CD to ignore tracking resources. See [reconcile docs](..%2Foperator-manual%2Freconcile.md)reconcile_docs for details. | +| link.argocd.argoproj.io/{some link name} | any | An http(s) URL | Adds a link to the Argo CD UI for the resource. See [external URL docs](external-url.md) for details. | +| pref.argocd.argoproj.io/default-pod-sort | Application | [see UI customization docs](../operator-manual/ui-customization.md) | Sets the Application's default grouping mechanism. | +| pref.argocd.argoproj.io/default-view | Application | [see UI customization docs](../operator-manual/ui-customization.md) | Sets the Application's default view mode (e.g. "tree" or "list") | ## Labels From 782621ec4dc1b74888511977aa009d29d01125eb Mon Sep 17 00:00:00 2001 From: kahoulei Date: Wed, 5 Jun 2024 10:19:28 -0700 Subject: [PATCH 04/21] refactor annotation usage base on comment feedback Signed-off-by: kahoulei --- controller/cache/cache.go | 19 +++++--------- controller/cache/info.go | 9 ++++--- docs/operator-manual/reconcile.md | 8 +++--- docs/user-guide/annotations-and-labels.md | 32 +++++++++++------------ 4 files changed, 33 insertions(+), 35 deletions(-) diff --git a/controller/cache/cache.go b/controller/cache/cache.go index 88112463fdaef..a12a28c0c9452 100644 --- a/controller/cache/cache.go +++ b/controller/cache/cache.go @@ -9,7 +9,6 @@ import ( "net/url" "os/exec" "reflect" - "strconv" "strings" "sync" "syscall" @@ -69,8 +68,8 @@ const ( // EnvClusterCacheRetryUseBackoff is the env variable to control whether to use a backoff strategy with the retry during cluster cache sync EnvClusterCacheRetryUseBackoff = "ARGOCD_CLUSTER_CACHE_RETRY_USE_BACKOFF" - // AnnotationIgnoreResourcesTracking is a Kubernetes annotation for a Kubernetes resource to ignore any resources tracking - AnnotationIgnoreResourcesTracking = "argocd.argoproj.io/ignore-resources-tracking" + // AnnotationIgnoreResourcesUpdate is a Kubernetes annotation for a Kubernetes resource to ignore any resources update + AnnotationIgnoreResourcesUpdate = "argocd.argoproj.io/ignore-resources-update" ) // GitOps engine cluster cache tuning options @@ -166,8 +165,8 @@ type ResourceInfo struct { manifestHash string - // annotations stores all the ObjectRef annotations - annotations map[string]string + // boolean to store the value of argocd.argoproj.io/ignore-resources-update annotation + ignoreResourcesUpdate bool } func NewLiveStateCache( @@ -349,12 +348,8 @@ func skipAppRequeuing(key kube.ResourceKey) bool { } func skipResourceUpdate(oldInfo, newInfo *ResourceInfo) bool { - if val, ok := newInfo.annotations[AnnotationIgnoreResourcesTracking]; ok { - // ignore the error and fall through the further checking - skip, _ := strconv.ParseBool(val) - if skip { - return true - } + if newInfo.ignoreResourcesUpdate && oldInfo.Health.Status == newInfo.Health.Status { + return true } if oldInfo == nil || newInfo == nil { @@ -564,7 +559,7 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e "name": ref.Name, "api-version": ref.APIVersion, "kind": ref.Kind, - }).Debugf("Ignoring change of object because none of the watched resource fields have changed or annotation %v is set to true", AnnotationIgnoreResourcesTracking) + }).Debugf("Ignoring change of object because none of the watched resource fields have changed") } return } diff --git a/controller/cache/info.go b/controller/cache/info.go index 4969a2d28f673..c7820cbd6f899 100644 --- a/controller/cache/info.go +++ b/controller/cache/info.go @@ -46,10 +46,13 @@ func populateNodeInfo(un *unstructured.Unstructured, res *ResourceInfo, customLa res.NetworkingInfo.ExternalURLs = append(res.NetworkingInfo.ExternalURLs, v) } - if res.annotations == nil { - res.annotations = make(map[string]string) + if k == AnnotationIgnoreResourcesUpdate { + value, err := strconv.ParseBool(v) + if err != nil { + value = false + } + res.ignoreResourcesUpdate = value } - res.annotations[k] = v } switch gvk.Group { diff --git a/docs/operator-manual/reconcile.md b/docs/operator-manual/reconcile.md index 312ba7e573576..482332e3465b3 100644 --- a/docs/operator-manual/reconcile.md +++ b/docs/operator-manual/reconcile.md @@ -120,7 +120,7 @@ and the Pod). For this use case, the above configurations will not help because argocd will still reconcile any newly created objects. -To completely ignore a newly created object, you need to add annotation `argocd.argoproj.io/ignore-resources-tracking=true` +To completely ignore a newly created object, you need to add annotation `argocd.argoproj.io/ignore-resources-update=true` to the target resource manifest. ## Example @@ -138,12 +138,12 @@ spec: jobTemplate: metadata: annotations: - argocd.argoproj.io/ignore-resources-tracking: "true" + argocd.argoproj.io/ignore-resources-update: "true" spec: template: metadata: annotations: - argocd.argoproj.io/ignore-resources-tracking: "true" + argocd.argoproj.io/ignore-resources-update: "true" spec: containers: - name: hello @@ -159,5 +159,5 @@ spec: And you should see the following debug message (if enabled) in the `application-controller` log: ``` -Ignoring change of object because none of the watched resource fields have changed or annotation argocd.argoproj.io/ignore-resources-tracking is set to true +Ignoring change of object because none of the watched resource fields have changed or annotation argocd.argoproj.io/ignore-resources-update is set to true ``` diff --git a/docs/user-guide/annotations-and-labels.md b/docs/user-guide/annotations-and-labels.md index 50cc023bb02f4..184c9af853cfb 100644 --- a/docs/user-guide/annotations-and-labels.md +++ b/docs/user-guide/annotations-and-labels.md @@ -2,22 +2,22 @@ ## Annotations -| Annotation key | Target resource(es) | Possible values | Description | -|----------------------------------------------|---------------------|---------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| argocd.argoproj.io/application-set-refresh | ApplicationSet | `"true"` | Added when an ApplicationSet is requested to be refreshed by a webhook. The ApplicationSet controller will remove this annotation at the end of reconciliation. | -| argocd.argoproj.io/compare-options | any | [see compare options docs](compare-options.md) | Configures how an app's current state is compared to its desired state. | -| argocd.argoproj.io/hook | any | [see resource hooks docs](resource_hooks.md) | Used to configure [resource hooks](resource_hooks.md). | -| argocd.argoproj.io/hook-delete-policy | any | [see resource hooks docs](resource_hooks.md#hook-deletion-policies) | Used to set a [resource hook's deletion policy](resource_hooks.md#hook-deletion-policies). | -| argocd.argoproj.io/manifest-generate-paths | Application | [see scaling docs](../operator-manual/high_availability.md#webhook-and-manifest-paths-annotation) | Used to avoid unnecessary Application refreshes, especially in mono-repos. | -| argocd.argoproj.io/refresh | Application | `normal`, `hard` | Indicates that app needs to be refreshed. Removed by application controller after app is refreshed. Value `"hard"` means manifest cache and target cluster state cache should be invalidated before refresh. | -| argocd.argoproj.io/skip-reconcile | Application | `"true"` | Indicates to the Argo CD application controller that the Application should not be reconciled. See the [skip reconcile documentation](skip_reconcile.md) for use cases. | -| argocd.argoproj.io/sync-options | any | [see sync options docs](sync-options.md) | Provides a variety of settings to determine how an Application's resources are synced. | -| argocd.argoproj.io/sync-wave | any | [see sync waves docs](sync-waves.md) | | -| argocd.argoproj.io/tracking-id | any | any | Used by Argo CD to track resources it manages. See [resource tracking docs](resource_tracking.md) for details. | -| argocd.argoproj.io/ignore-resources-tracking | any | `"true"` | Used by Argo CD to ignore tracking resources. See [reconcile docs](..%2Foperator-manual%2Freconcile.md)reconcile_docs for details. | -| link.argocd.argoproj.io/{some link name} | any | An http(s) URL | Adds a link to the Argo CD UI for the resource. See [external URL docs](external-url.md) for details. | -| pref.argocd.argoproj.io/default-pod-sort | Application | [see UI customization docs](../operator-manual/ui-customization.md) | Sets the Application's default grouping mechanism. | -| pref.argocd.argoproj.io/default-view | Application | [see UI customization docs](../operator-manual/ui-customization.md) | Sets the Application's default view mode (e.g. "tree" or "list") | +| Annotation key | Target resource(es) | Possible values | Description | +|--------------------------------------------|---------------------|---------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| argocd.argoproj.io/application-set-refresh | ApplicationSet | `"true"` | Added when an ApplicationSet is requested to be refreshed by a webhook. The ApplicationSet controller will remove this annotation at the end of reconciliation. | +| argocd.argoproj.io/compare-options | any | [see compare options docs](compare-options.md) | Configures how an app's current state is compared to its desired state. | +| argocd.argoproj.io/hook | any | [see resource hooks docs](resource_hooks.md) | Used to configure [resource hooks](resource_hooks.md). | +| argocd.argoproj.io/hook-delete-policy | any | [see resource hooks docs](resource_hooks.md#hook-deletion-policies) | Used to set a [resource hook's deletion policy](resource_hooks.md#hook-deletion-policies). | +| argocd.argoproj.io/manifest-generate-paths | Application | [see scaling docs](../operator-manual/high_availability.md#webhook-and-manifest-paths-annotation) | Used to avoid unnecessary Application refreshes, especially in mono-repos. | +| argocd.argoproj.io/refresh | Application | `normal`, `hard` | Indicates that app needs to be refreshed. Removed by application controller after app is refreshed. Value `"hard"` means manifest cache and target cluster state cache should be invalidated before refresh. | +| argocd.argoproj.io/skip-reconcile | Application | `"true"` | Indicates to the Argo CD application controller that the Application should not be reconciled. See the [skip reconcile documentation](skip_reconcile.md) for use cases. | +| argocd.argoproj.io/sync-options | any | [see sync options docs](sync-options.md) | Provides a variety of settings to determine how an Application's resources are synced. | +| argocd.argoproj.io/sync-wave | any | [see sync waves docs](sync-waves.md) | | +| argocd.argoproj.io/tracking-id | any | any | Used by Argo CD to track resources it manages. See [resource tracking docs](resource_tracking.md) for details. | +| argocd.argoproj.io/ignore-resources-update | any | `"true"` | Used by Argo CD to ignore tracking resources. See [reconcile docs](..%2Foperator-manual%2Freconcile.md)reconcile_docs for details. | +| link.argocd.argoproj.io/{some link name} | any | An http(s) URL | Adds a link to the Argo CD UI for the resource. See [external URL docs](external-url.md) for details. | +| pref.argocd.argoproj.io/default-pod-sort | Application | [see UI customization docs](../operator-manual/ui-customization.md) | Sets the Application's default grouping mechanism. | +| pref.argocd.argoproj.io/default-view | Application | [see UI customization docs](../operator-manual/ui-customization.md) | Sets the Application's default view mode (e.g. "tree" or "list") | ## Labels From 62dc5dcb693d8068ddd754b04eb4ac60b381abe1 Mon Sep 17 00:00:00 2001 From: kahoulei Date: Wed, 5 Jun 2024 10:52:32 -0700 Subject: [PATCH 05/21] update annotation Signed-off-by: kahoulei --- controller/cache/cache.go | 12 ++++++------ controller/cache/info.go | 7 +++++-- docs/operator-manual/reconcile.md | 8 ++++---- docs/user-guide/annotations-and-labels.md | 2 +- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/controller/cache/cache.go b/controller/cache/cache.go index a12a28c0c9452..e7ccb84834793 100644 --- a/controller/cache/cache.go +++ b/controller/cache/cache.go @@ -68,8 +68,8 @@ const ( // EnvClusterCacheRetryUseBackoff is the env variable to control whether to use a backoff strategy with the retry during cluster cache sync EnvClusterCacheRetryUseBackoff = "ARGOCD_CLUSTER_CACHE_RETRY_USE_BACKOFF" - // AnnotationIgnoreResourcesUpdate is a Kubernetes annotation for a Kubernetes resource to ignore any resources update - AnnotationIgnoreResourcesUpdate = "argocd.argoproj.io/ignore-resources-update" + // AnnotationApplyResourcesUpdate when set to false to a resource, argocd will not proceed any update onto that resource. + AnnotationApplyResourcesUpdate = "argocd.argoproj.io/apply-resources-update" ) // GitOps engine cluster cache tuning options @@ -165,8 +165,8 @@ type ResourceInfo struct { manifestHash string - // boolean to store the value of argocd.argoproj.io/ignore-resources-update annotation - ignoreResourcesUpdate bool + // boolean to store the value of argocd.argoproj.io/apply-resources-update annotation + applyResourcesUpdate bool } func NewLiveStateCache( @@ -348,7 +348,7 @@ func skipAppRequeuing(key kube.ResourceKey) bool { } func skipResourceUpdate(oldInfo, newInfo *ResourceInfo) bool { - if newInfo.ignoreResourcesUpdate && oldInfo.Health.Status == newInfo.Health.Status { + if !newInfo.applyResourcesUpdate && oldInfo.Health.Status == newInfo.Health.Status { return true } @@ -512,7 +512,7 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e gvk := un.GroupVersionKind() - if cacheSettings.ignoreResourceUpdatesEnabled && shouldHashManifest(appName, gvk) { + if (cacheSettings.ignoreResourceUpdatesEnabled || res.applyResourcesUpdate) && shouldHashManifest(appName, gvk) { hash, err := generateManifestHash(un, nil, cacheSettings.resourceOverrides, c.ignoreNormalizerOpts) if err != nil { log.Errorf("Failed to generate manifest hash: %v", err) diff --git a/controller/cache/info.go b/controller/cache/info.go index c7820cbd6f899..f1cf612054d8c 100644 --- a/controller/cache/info.go +++ b/controller/cache/info.go @@ -38,6 +38,9 @@ func populateNodeInfo(un *unstructured.Unstructured, res *ResourceInfo, customLa } } + // always apply resources update by default + res.applyResourcesUpdate = true + for k, v := range un.GetAnnotations() { if strings.HasPrefix(k, common.AnnotationKeyLinkPrefix) { if res.NetworkingInfo == nil { @@ -46,12 +49,12 @@ func populateNodeInfo(un *unstructured.Unstructured, res *ResourceInfo, customLa res.NetworkingInfo.ExternalURLs = append(res.NetworkingInfo.ExternalURLs, v) } - if k == AnnotationIgnoreResourcesUpdate { + if k == AnnotationApplyResourcesUpdate { value, err := strconv.ParseBool(v) if err != nil { value = false } - res.ignoreResourcesUpdate = value + res.applyResourcesUpdate = value } } diff --git a/docs/operator-manual/reconcile.md b/docs/operator-manual/reconcile.md index 482332e3465b3..fcc4332691694 100644 --- a/docs/operator-manual/reconcile.md +++ b/docs/operator-manual/reconcile.md @@ -120,7 +120,7 @@ and the Pod). For this use case, the above configurations will not help because argocd will still reconcile any newly created objects. -To completely ignore a newly created object, you need to add annotation `argocd.argoproj.io/ignore-resources-update=true` +To completely ignore a newly created object, you need to add annotation `argocd.argoproj.io/apply-resources-update=false` to the target resource manifest. ## Example @@ -138,12 +138,12 @@ spec: jobTemplate: metadata: annotations: - argocd.argoproj.io/ignore-resources-update: "true" + argocd.argoproj.io/apply-resources-update: "false" spec: template: metadata: annotations: - argocd.argoproj.io/ignore-resources-update: "true" + argocd.argoproj.io/apply-resources-update: "false" spec: containers: - name: hello @@ -159,5 +159,5 @@ spec: And you should see the following debug message (if enabled) in the `application-controller` log: ``` -Ignoring change of object because none of the watched resource fields have changed or annotation argocd.argoproj.io/ignore-resources-update is set to true +Ignoring change of object because none of the watched resource fields have changed or annotation argocd.argoproj.io/apply-resources-update is set to false ``` diff --git a/docs/user-guide/annotations-and-labels.md b/docs/user-guide/annotations-and-labels.md index 184c9af853cfb..f8dab547a0371 100644 --- a/docs/user-guide/annotations-and-labels.md +++ b/docs/user-guide/annotations-and-labels.md @@ -14,7 +14,7 @@ | argocd.argoproj.io/sync-options | any | [see sync options docs](sync-options.md) | Provides a variety of settings to determine how an Application's resources are synced. | | argocd.argoproj.io/sync-wave | any | [see sync waves docs](sync-waves.md) | | | argocd.argoproj.io/tracking-id | any | any | Used by Argo CD to track resources it manages. See [resource tracking docs](resource_tracking.md) for details. | -| argocd.argoproj.io/ignore-resources-update | any | `"true"` | Used by Argo CD to ignore tracking resources. See [reconcile docs](..%2Foperator-manual%2Freconcile.md)reconcile_docs for details. | +| argocd.argoproj.io/apply-resources-update | any | `"true"`, `false` | Used by Argo CD to ignore tracking resources. See [reconcile docs](..%2Foperator-manual%2Freconcile.md)reconcile_docs for details. | | link.argocd.argoproj.io/{some link name} | any | An http(s) URL | Adds a link to the Argo CD UI for the resource. See [external URL docs](external-url.md) for details. | | pref.argocd.argoproj.io/default-pod-sort | Application | [see UI customization docs](../operator-manual/ui-customization.md) | Sets the Application's default grouping mechanism. | | pref.argocd.argoproj.io/default-view | Application | [see UI customization docs](../operator-manual/ui-customization.md) | Sets the Application's default view mode (e.g. "tree" or "list") | From e0acf88b77390a735c273c32145288da91fe83d0 Mon Sep 17 00:00:00 2001 From: kahoulei Date: Wed, 5 Jun 2024 14:31:29 -0700 Subject: [PATCH 06/21] do not store boolean in resourceInfo Signed-off-by: kahoulei --- controller/cache/cache.go | 30 ++++++++++++++++++------------ controller/cache/info.go | 11 ----------- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/controller/cache/cache.go b/controller/cache/cache.go index e7ccb84834793..a029870693c28 100644 --- a/controller/cache/cache.go +++ b/controller/cache/cache.go @@ -9,6 +9,7 @@ import ( "net/url" "os/exec" "reflect" + "strconv" "strings" "sync" "syscall" @@ -164,9 +165,6 @@ type ResourceInfo struct { NodeInfo *NodeInfo manifestHash string - - // boolean to store the value of argocd.argoproj.io/apply-resources-update annotation - applyResourcesUpdate bool } func NewLiveStateCache( @@ -348,28 +346,36 @@ func skipAppRequeuing(key kube.ResourceKey) bool { } func skipResourceUpdate(oldInfo, newInfo *ResourceInfo) bool { - if !newInfo.applyResourcesUpdate && oldInfo.Health.Status == newInfo.Health.Status { - return true - } - if oldInfo == nil || newInfo == nil { return false } isSameHealthStatus := (oldInfo.Health == nil && newInfo.Health == nil) || oldInfo.Health != nil && newInfo.Health != nil && oldInfo.Health.Status == newInfo.Health.Status - isSameManifest := oldInfo.manifestHash != "" && newInfo.manifestHash != "" && oldInfo.manifestHash == newInfo.manifestHash + isSameManifest := oldInfo.manifestHash == newInfo.manifestHash return isSameHealthStatus && isSameManifest } // shouldHashManifest validates if the API resource needs to be hashed. // If there's an app name from resource tracking, or if this is itself an app, we should generate a hash. // Otherwise, the hashing should be skipped to save CPU time. -func shouldHashManifest(appName string, gvk schema.GroupVersionKind) bool { - // Only hash if the resource belongs to an app. +func shouldHashManifest(appName string, gvk schema.GroupVersionKind, un *unstructured.Unstructured) bool { + // Do not generate hash if argocd.argoproj.io/apply-resources-update is false + // Otherwise: + // Only hash if the resource belongs to an app // Best - Only hash for resources that are part of an app or their dependencies // (current) - Only hash for resources that are part of an app + all apps that might be from an ApplicationSet // Orphan - If orphan is enabled, hash should be made on all resource of that namespace and a config to disable it // Worst - Hash all resources watched by Argo - return appName != "" || (gvk.Group == application.Group && gvk.Kind == application.ApplicationKind) + applyResourcesUpdate := true + val, ok := un.GetAnnotations()[AnnotationApplyResourcesUpdate] + if ok { + ret, err := strconv.ParseBool(val) + if err != nil { + applyResourcesUpdate = true + } + applyResourcesUpdate = ret + } + + return applyResourcesUpdate && (appName != "" || (gvk.Group == application.Group && gvk.Kind == application.ApplicationKind)) } // isRetryableError is a helper method to see whether an error @@ -512,7 +518,7 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e gvk := un.GroupVersionKind() - if (cacheSettings.ignoreResourceUpdatesEnabled || res.applyResourcesUpdate) && shouldHashManifest(appName, gvk) { + if cacheSettings.ignoreResourceUpdatesEnabled && shouldHashManifest(appName, gvk, un) { hash, err := generateManifestHash(un, nil, cacheSettings.resourceOverrides, c.ignoreNormalizerOpts) if err != nil { log.Errorf("Failed to generate manifest hash: %v", err) diff --git a/controller/cache/info.go b/controller/cache/info.go index f1cf612054d8c..0734e2d118678 100644 --- a/controller/cache/info.go +++ b/controller/cache/info.go @@ -38,9 +38,6 @@ func populateNodeInfo(un *unstructured.Unstructured, res *ResourceInfo, customLa } } - // always apply resources update by default - res.applyResourcesUpdate = true - for k, v := range un.GetAnnotations() { if strings.HasPrefix(k, common.AnnotationKeyLinkPrefix) { if res.NetworkingInfo == nil { @@ -48,14 +45,6 @@ func populateNodeInfo(un *unstructured.Unstructured, res *ResourceInfo, customLa } res.NetworkingInfo.ExternalURLs = append(res.NetworkingInfo.ExternalURLs, v) } - - if k == AnnotationApplyResourcesUpdate { - value, err := strconv.ParseBool(v) - if err != nil { - value = false - } - res.applyResourcesUpdate = value - } } switch gvk.Group { From ba861c11ec91826291ccd8051de6fd6e728a8ab4 Mon Sep 17 00:00:00 2001 From: kahoulei Date: Wed, 5 Jun 2024 14:32:38 -0700 Subject: [PATCH 07/21] typo Signed-off-by: kahoulei --- controller/cache/cache.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controller/cache/cache.go b/controller/cache/cache.go index a029870693c28..37fdd6c2d3c68 100644 --- a/controller/cache/cache.go +++ b/controller/cache/cache.go @@ -565,7 +565,7 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e "name": ref.Name, "api-version": ref.APIVersion, "kind": ref.Kind, - }).Debugf("Ignoring change of object because none of the watched resource fields have changed") + }).Debug("Ignoring change of object because none of the watched resource fields have changed") } return } From a0fe22a60815869aea071e42a4191e74740658ff Mon Sep 17 00:00:00 2001 From: kahoulei Date: Wed, 5 Jun 2024 16:46:32 -0700 Subject: [PATCH 08/21] update logic Signed-off-by: kahoulei --- controller/cache/cache.go | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/controller/cache/cache.go b/controller/cache/cache.go index 37fdd6c2d3c68..41956c086ac23 100644 --- a/controller/cache/cache.go +++ b/controller/cache/cache.go @@ -358,24 +358,29 @@ func skipResourceUpdate(oldInfo, newInfo *ResourceInfo) bool { // If there's an app name from resource tracking, or if this is itself an app, we should generate a hash. // Otherwise, the hashing should be skipped to save CPU time. func shouldHashManifest(appName string, gvk schema.GroupVersionKind, un *unstructured.Unstructured) bool { - // Do not generate hash if argocd.argoproj.io/apply-resources-update is false - // Otherwise: - // Only hash if the resource belongs to an app + // Only hash if the resource belongs to an app OR argocd.argoproj.io/apply-resources-update is present and set to true // Best - Only hash for resources that are part of an app or their dependencies // (current) - Only hash for resources that are part of an app + all apps that might be from an ApplicationSet // Orphan - If orphan is enabled, hash should be made on all resource of that namespace and a config to disable it // Worst - Hash all resources watched by Argo - applyResourcesUpdate := true - val, ok := un.GetAnnotations()[AnnotationApplyResourcesUpdate] - if ok { - ret, err := strconv.ParseBool(val) - if err != nil { - applyResourcesUpdate = true + belong := appName != "" || (gvk.Group == application.Group && gvk.Kind == application.ApplicationKind) + + // If the resource does not belong the app, we will look up argocd.argoproj.io/apply-resources-update and decide + // whether we generate hash or not. + if !belong { + applyResourcesUpdate := false + val, ok := un.GetAnnotations()[AnnotationApplyResourcesUpdate] + if ok { + ret, err := strconv.ParseBool(val) + if err != nil { + applyResourcesUpdate = false + } + applyResourcesUpdate = ret } - applyResourcesUpdate = ret + return applyResourcesUpdate } - return applyResourcesUpdate && (appName != "" || (gvk.Group == application.Group && gvk.Kind == application.ApplicationKind)) + return belong } // isRetryableError is a helper method to see whether an error From 7128bb0bdc863d2126538e749f31a97f6ebc3942 Mon Sep 17 00:00:00 2001 From: kahoulei Date: Wed, 5 Jun 2024 19:53:27 -0700 Subject: [PATCH 09/21] refactor Signed-off-by: kahoulei --- controller/cache/cache.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/controller/cache/cache.go b/controller/cache/cache.go index 41956c086ac23..0392dbd9cb8b4 100644 --- a/controller/cache/cache.go +++ b/controller/cache/cache.go @@ -368,16 +368,14 @@ func shouldHashManifest(appName string, gvk schema.GroupVersionKind, un *unstruc // If the resource does not belong the app, we will look up argocd.argoproj.io/apply-resources-update and decide // whether we generate hash or not. if !belong { - applyResourcesUpdate := false - val, ok := un.GetAnnotations()[AnnotationApplyResourcesUpdate] - if ok { - ret, err := strconv.ParseBool(val) + if val, ok := un.GetAnnotations()[AnnotationApplyResourcesUpdate]; ok { + applyResourcesUpdate, err := strconv.ParseBool(val) if err != nil { applyResourcesUpdate = false } - applyResourcesUpdate = ret + return applyResourcesUpdate } - return applyResourcesUpdate + return false } return belong From 5f70557d2c7cbc362cf7b668abe55d775fb3707f Mon Sep 17 00:00:00 2001 From: kahoulei Date: Wed, 5 Jun 2024 19:55:41 -0700 Subject: [PATCH 10/21] add comment Signed-off-by: kahoulei --- controller/cache/cache.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/controller/cache/cache.go b/controller/cache/cache.go index 0392dbd9cb8b4..9a163b686db75 100644 --- a/controller/cache/cache.go +++ b/controller/cache/cache.go @@ -367,6 +367,8 @@ func shouldHashManifest(appName string, gvk schema.GroupVersionKind, un *unstruc // If the resource does not belong the app, we will look up argocd.argoproj.io/apply-resources-update and decide // whether we generate hash or not. + // If argocd.argoproj.io/apply-resources-update is presented and is true, return true + // Else return false if !belong { if val, ok := un.GetAnnotations()[AnnotationApplyResourcesUpdate]; ok { applyResourcesUpdate, err := strconv.ParseBool(val) From d9f7dfaeb5e0bb2c26ba119475e11e168d88045e Mon Sep 17 00:00:00 2001 From: kahoulei Date: Thu, 6 Jun 2024 12:18:41 -0700 Subject: [PATCH 11/21] add tests Signed-off-by: kahoulei --- controller/cache/cache_test.go | 81 +++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/controller/cache/cache_test.go b/controller/cache/cache_test.go index 584f311f2ee30..0d32efc1029bf 100644 --- a/controller/cache/cache_test.go +++ b/controller/cache/cache_test.go @@ -3,6 +3,8 @@ package cache import ( "context" "errors" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "net" "net/url" "sync" @@ -553,7 +555,7 @@ func TestSkipResourceUpdate(t *testing.T) { assert.False(t, skipResourceUpdate(info, nil)) }) t.Run("No hash", func(t *testing.T) { - assert.False(t, skipResourceUpdate(&ResourceInfo{}, &ResourceInfo{})) + assert.True(t, skipResourceUpdate(&ResourceInfo{}, &ResourceInfo{})) }) t.Run("Same hash", func(t *testing.T) { assert.True(t, skipResourceUpdate(&ResourceInfo{ @@ -652,3 +654,80 @@ func TestSkipResourceUpdate(t *testing.T) { })) }) } + +func TestShouldHashManifest(t *testing.T) { + tests := []struct { + name string + appName string + gvk schema.GroupVersionKind + un *unstructured.Unstructured + annotations map[string]string + want bool + }{ + { + name: "appName not empty gvk matches", + appName: "MyApp", + gvk: schema.GroupVersionKind{Group: application.Group, Kind: application.ApplicationKind}, + un: &unstructured.Unstructured{}, + want: true, + }, + { + name: "appName empty", + appName: "", + gvk: schema.GroupVersionKind{Group: application.Group, Kind: application.ApplicationKind}, + un: &unstructured.Unstructured{}, + want: true, + }, + { + name: "appName empty group not match", + appName: "", + gvk: schema.GroupVersionKind{Group: "group1", Kind: application.ApplicationKind}, + un: &unstructured.Unstructured{}, + want: false, + }, + { + name: "appName empty kind not match", + appName: "", + gvk: schema.GroupVersionKind{Group: application.Group, Kind: "kind1"}, + un: &unstructured.Unstructured{}, + want: false, + }, + { + name: "argocd.argoproj.io/apply-resources-update=true", + appName: "", + gvk: schema.GroupVersionKind{Group: application.Group, Kind: "kind1"}, + un: &unstructured.Unstructured{}, + annotations: map[string]string{"argocd.argoproj.io/apply-resources-update": "true"}, + want: true, + }, + { + name: "argocd.argoproj.io/apply-resources-update=invalid", + appName: "", + gvk: schema.GroupVersionKind{Group: application.Group, Kind: "kind1"}, + un: &unstructured.Unstructured{}, + annotations: map[string]string{"argocd.argoproj.io/apply-resources-update": "invalid"}, + want: false, + }, + { + name: "argocd.argoproj.io/apply-resources-update=false", + appName: "", + gvk: schema.GroupVersionKind{Group: application.Group, Kind: "kind1"}, + un: &unstructured.Unstructured{}, + annotations: map[string]string{"argocd.argoproj.io/apply-resources-update": "false"}, + want: false, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if test.annotations != nil { + test.un.SetAnnotations(test.annotations) + } + got := shouldHashManifest(test.appName, test.gvk, test.un) + if test.want != got { + t.Fatalf("test=%v want %v got %v", test.name, test.want, got) + } + }) + } + +} From 140c3d8f8d0c9939049ca1632ea0946722e8818e Mon Sep 17 00:00:00 2001 From: kahoulei Date: Thu, 6 Jun 2024 12:23:35 -0700 Subject: [PATCH 12/21] update doc Signed-off-by: kahoulei --- docs/operator-manual/reconcile.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/operator-manual/reconcile.md b/docs/operator-manual/reconcile.md index fcc4332691694..85e1dc0341199 100644 --- a/docs/operator-manual/reconcile.md +++ b/docs/operator-manual/reconcile.md @@ -114,7 +114,7 @@ data: ## Completely ignore resources update -There is an use case that you would like to completely ignore the resources at all. This mostly happens when some dependent +There is a use case that you would like to completely ignore the resources at all. This mostly happens when some dependent resources are created by another resource (e.g. a Job and a Pod are created by a CronJob and you want to ignore the Job and the Pod). @@ -159,5 +159,8 @@ spec: And you should see the following debug message (if enabled) in the `application-controller` log: ``` -Ignoring change of object because none of the watched resource fields have changed or annotation argocd.argoproj.io/apply-resources-update is set to false +Ignoring change of object because none of the watched resource fields have changed ``` + +Note: If you add annotation to any resource with `argocd.argoproj.io/apply-resources-update=true`, argocd controller +will refresh that resource regardless if it belongs to the application or not. \ No newline at end of file From b1fe0b9ad571c7ee4bd803dc49b6040f481f2e23 Mon Sep 17 00:00:00 2001 From: kahoulei Date: Mon, 10 Jun 2024 09:30:42 -0700 Subject: [PATCH 13/21] update code base on comment feedback Signed-off-by: kahoulei --- controller/cache/cache.go | 12 +++++------ controller/cache/cache_test.go | 2 +- docs/operator-manual/reconcile.md | 35 +++++++++++++++++-------------- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/controller/cache/cache.go b/controller/cache/cache.go index 6c26239ea359d..e6c9fdfba5652 100644 --- a/controller/cache/cache.go +++ b/controller/cache/cache.go @@ -71,7 +71,7 @@ const ( // EnvClusterCacheRetryUseBackoff is the env variable to control whether to use a backoff strategy with the retry during cluster cache sync EnvClusterCacheRetryUseBackoff = "ARGOCD_CLUSTER_CACHE_RETRY_USE_BACKOFF" - // AnnotationApplyResourcesUpdate when set to false to a resource, argocd will not proceed any update onto that resource. + // AnnotationApplyResourcesUpdate when set to true on a resource, argocd will ignore the resource changes based on ignoreResourceUpdates configuration. AnnotationApplyResourcesUpdate = "argocd.argoproj.io/apply-resources-update" ) @@ -352,7 +352,7 @@ func skipResourceUpdate(oldInfo, newInfo *ResourceInfo) bool { return false } isSameHealthStatus := (oldInfo.Health == nil && newInfo.Health == nil) || oldInfo.Health != nil && newInfo.Health != nil && oldInfo.Health.Status == newInfo.Health.Status - isSameManifest := oldInfo.manifestHash == newInfo.manifestHash + isSameManifest := oldInfo.manifestHash != "" && newInfo.manifestHash != "" && oldInfo.manifestHash == newInfo.manifestHash return isSameHealthStatus && isSameManifest } @@ -365,13 +365,13 @@ func shouldHashManifest(appName string, gvk schema.GroupVersionKind, un *unstruc // (current) - Only hash for resources that are part of an app + all apps that might be from an ApplicationSet // Orphan - If orphan is enabled, hash should be made on all resource of that namespace and a config to disable it // Worst - Hash all resources watched by Argo - belong := appName != "" || (gvk.Group == application.Group && gvk.Kind == application.ApplicationKind) + isTrackedResources := appName != "" || (gvk.Group == application.Group && gvk.Kind == application.ApplicationKind) - // If the resource does not belong the app, we will look up argocd.argoproj.io/apply-resources-update and decide + // If the resource is not a tracked resource, we will look up argocd.argoproj.io/apply-resources-update and decide // whether we generate hash or not. // If argocd.argoproj.io/apply-resources-update is presented and is true, return true // Else return false - if !belong { + if !isTrackedResources { if val, ok := un.GetAnnotations()[AnnotationApplyResourcesUpdate]; ok { applyResourcesUpdate, err := strconv.ParseBool(val) if err != nil { @@ -382,7 +382,7 @@ func shouldHashManifest(appName string, gvk schema.GroupVersionKind, un *unstruc return false } - return belong + return isTrackedResources } // isRetryableError is a helper method to see whether an error diff --git a/controller/cache/cache_test.go b/controller/cache/cache_test.go index 0d32efc1029bf..438c686680c4a 100644 --- a/controller/cache/cache_test.go +++ b/controller/cache/cache_test.go @@ -555,7 +555,7 @@ func TestSkipResourceUpdate(t *testing.T) { assert.False(t, skipResourceUpdate(info, nil)) }) t.Run("No hash", func(t *testing.T) { - assert.True(t, skipResourceUpdate(&ResourceInfo{}, &ResourceInfo{})) + assert.False(t, skipResourceUpdate(&ResourceInfo{}, &ResourceInfo{})) }) t.Run("Same hash", func(t *testing.T) { assert.True(t, skipResourceUpdate(&ResourceInfo{ diff --git a/docs/operator-manual/reconcile.md b/docs/operator-manual/reconcile.md index 85e1dc0341199..1db8795892b47 100644 --- a/docs/operator-manual/reconcile.md +++ b/docs/operator-manual/reconcile.md @@ -112,22 +112,19 @@ data: - .status.conditions[].lastTransitionTime ``` -## Completely ignore resources update +## Tracking Dependent Resources -There is a use case that you would like to completely ignore the resources at all. This mostly happens when some dependent -resources are created by another resource (e.g. a Job and a Pod are created by a CronJob and you want to ignore the Job -and the Pod). +Dependent resources by default are not being tracked. Therefore, we cannot generate any hash of those objects and utilize +the `ignoreResourceUpdates` configuration. -For this use case, the above configurations will not help because argocd will still reconcile any newly created objects. - -To completely ignore a newly created object, you need to add annotation `argocd.argoproj.io/apply-resources-update=false` -to the target resource manifest. +If you want to track the dependent object and apply the `ignoreResourceUpdates` configuration, you can add +`argocd.argoproj.io/apply-resources-update=true` annotation in the dependent resources manifest: ## Example ### CronJob -``` +```yaml apiVersion: batch/v1 kind: CronJob metadata: @@ -138,12 +135,12 @@ spec: jobTemplate: metadata: annotations: - argocd.argoproj.io/apply-resources-update: "false" + argocd.argoproj.io/apply-resources-update: "true" spec: template: metadata: annotations: - argocd.argoproj.io/apply-resources-update: "false" + argocd.argoproj.io/apply-resources-update: "true" spec: containers: - name: hello @@ -156,11 +153,17 @@ spec: restartPolicy: OnFailure ``` -And you should see the following debug message (if enabled) in the `application-controller` log: +Then you can update `argocd-cm` configMap to ignore the dependent resources: -``` -Ignoring change of object because none of the watched resource fields have changed +`argocd-cm`: +```yaml +resource.customizations.ignoreResourceUpdates.batch_Job: | + jsonPointers: + - /status +resource.customizations.ignoreResourceUpdates.Pod: | + jsonPointers: + - /status ``` -Note: If you add annotation to any resource with `argocd.argoproj.io/apply-resources-update=true`, argocd controller -will refresh that resource regardless if it belongs to the application or not. \ No newline at end of file +Note: If you set `argocd.argoproj.io/apply-resources-update: "false"`, no hash will be generated and `ignoreResourceUpdates` +cannot be applied on those resources. \ No newline at end of file From e51e61a875c3847e4190397a641d1b8663097b4f Mon Sep 17 00:00:00 2001 From: kahoulei Date: Mon, 10 Jun 2024 09:32:49 -0700 Subject: [PATCH 14/21] update annotation doc Signed-off-by: kahoulei --- docs/user-guide/annotations-and-labels.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user-guide/annotations-and-labels.md b/docs/user-guide/annotations-and-labels.md index f8dab547a0371..f1321e0af5ffd 100644 --- a/docs/user-guide/annotations-and-labels.md +++ b/docs/user-guide/annotations-and-labels.md @@ -14,7 +14,7 @@ | argocd.argoproj.io/sync-options | any | [see sync options docs](sync-options.md) | Provides a variety of settings to determine how an Application's resources are synced. | | argocd.argoproj.io/sync-wave | any | [see sync waves docs](sync-waves.md) | | | argocd.argoproj.io/tracking-id | any | any | Used by Argo CD to track resources it manages. See [resource tracking docs](resource_tracking.md) for details. | -| argocd.argoproj.io/apply-resources-update | any | `"true"`, `false` | Used by Argo CD to ignore tracking resources. See [reconcile docs](..%2Foperator-manual%2Freconcile.md)reconcile_docs for details. | +| argocd.argoproj.io/apply-resources-update | any | `"true"`, `false` | Used by Argo CD to ignore resource updates. See [reconcile docs](..%2Foperator-manual%2Freconcile.md)reconcile_docs for details. | | link.argocd.argoproj.io/{some link name} | any | An http(s) URL | Adds a link to the Argo CD UI for the resource. See [external URL docs](external-url.md) for details. | | pref.argocd.argoproj.io/default-pod-sort | Application | [see UI customization docs](../operator-manual/ui-customization.md) | Sets the Application's default grouping mechanism. | | pref.argocd.argoproj.io/default-view | Application | [see UI customization docs](../operator-manual/ui-customization.md) | Sets the Application's default view mode (e.g. "tree" or "list") | From 0cc128730b09b6ee48bb76f49d59e8345b4185da Mon Sep 17 00:00:00 2001 From: kahoulei Date: Mon, 10 Jun 2024 11:50:13 -0700 Subject: [PATCH 15/21] fix goimport Signed-off-by: kahoulei --- controller/cache/cache_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/controller/cache/cache_test.go b/controller/cache/cache_test.go index 68f6dd89155f5..adf317e473213 100644 --- a/controller/cache/cache_test.go +++ b/controller/cache/cache_test.go @@ -3,14 +3,15 @@ package cache import ( "context" "errors" - "github.com/argoproj/argo-cd/v2/pkg/apis/application" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "net" "net/url" "sync" "testing" "time" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "github.com/stretchr/testify/assert" v1 "k8s.io/api/core/v1" apierr "k8s.io/apimachinery/pkg/api/errors" From 0d947820de0c027adee00b0d15ea21925c29f343 Mon Sep 17 00:00:00 2001 From: kahoulei Date: Mon, 10 Jun 2024 13:42:15 -0700 Subject: [PATCH 16/21] fix golint Signed-off-by: kahoulei --- controller/cache/cache_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controller/cache/cache_test.go b/controller/cache/cache_test.go index adf317e473213..17ab09f738822 100644 --- a/controller/cache/cache_test.go +++ b/controller/cache/cache_test.go @@ -9,7 +9,6 @@ import ( "testing" "time" - "github.com/argoproj/argo-cd/v2/pkg/apis/application" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "github.com/stretchr/testify/assert" @@ -28,6 +27,7 @@ import ( "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/argo-cd/v2/controller/metrics" "github.com/argoproj/argo-cd/v2/controller/sharding" + "github.com/argoproj/argo-cd/v2/pkg/apis/application" appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" dbmocks "github.com/argoproj/argo-cd/v2/util/db/mocks" argosettings "github.com/argoproj/argo-cd/v2/util/settings" From 9da4335505eb5b999d3325d1f972c3a6d882ad79 Mon Sep 17 00:00:00 2001 From: kahoulei Date: Mon, 10 Jun 2024 17:27:28 -0700 Subject: [PATCH 17/21] update comments Signed-off-by: kahoulei --- controller/cache/cache.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/controller/cache/cache.go b/controller/cache/cache.go index e6c9fdfba5652..6a493189d48d4 100644 --- a/controller/cache/cache.go +++ b/controller/cache/cache.go @@ -71,7 +71,9 @@ const ( // EnvClusterCacheRetryUseBackoff is the env variable to control whether to use a backoff strategy with the retry during cluster cache sync EnvClusterCacheRetryUseBackoff = "ARGOCD_CLUSTER_CACHE_RETRY_USE_BACKOFF" - // AnnotationApplyResourcesUpdate when set to true on a resource, argocd will ignore the resource changes based on ignoreResourceUpdates configuration. + // AnnotationApplyResourcesUpdate when set to true on a resource that is not tracked under an app, argocd will generate a + // hash and apply `ignoreResourceUpdate` configuration on it. If the annotation is set to false (or not presented) on a resource + // that is not tracked under an app, ignoreResourceUpdates configuration will not be applied. AnnotationApplyResourcesUpdate = "argocd.argoproj.io/apply-resources-update" ) From 06589c539bc2debf67c6ae914fe5dbee8e43220a Mon Sep 17 00:00:00 2001 From: kahoulei Date: Mon, 17 Jun 2024 08:44:01 -0700 Subject: [PATCH 18/21] update docs Signed-off-by: kahoulei --- controller/cache/cache.go | 11 +++++------ docs/operator-manual/reconcile.md | 14 +++++--------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/controller/cache/cache.go b/controller/cache/cache.go index 6a493189d48d4..288be9a78a8aa 100644 --- a/controller/cache/cache.go +++ b/controller/cache/cache.go @@ -71,9 +71,8 @@ const ( // EnvClusterCacheRetryUseBackoff is the env variable to control whether to use a backoff strategy with the retry during cluster cache sync EnvClusterCacheRetryUseBackoff = "ARGOCD_CLUSTER_CACHE_RETRY_USE_BACKOFF" - // AnnotationApplyResourcesUpdate when set to true on a resource that is not tracked under an app, argocd will generate a - // hash and apply `ignoreResourceUpdate` configuration on it. If the annotation is set to false (or not presented) on a resource - // that is not tracked under an app, ignoreResourceUpdates configuration will not be applied. + // AnnotationApplyResourcesUpdate when set to true on an untracked resource, + // argo will apply `ignoreResourceUpdates` configuration on it. AnnotationApplyResourcesUpdate = "argocd.argoproj.io/apply-resources-update" ) @@ -367,13 +366,13 @@ func shouldHashManifest(appName string, gvk schema.GroupVersionKind, un *unstruc // (current) - Only hash for resources that are part of an app + all apps that might be from an ApplicationSet // Orphan - If orphan is enabled, hash should be made on all resource of that namespace and a config to disable it // Worst - Hash all resources watched by Argo - isTrackedResources := appName != "" || (gvk.Group == application.Group && gvk.Kind == application.ApplicationKind) + isTrackedResource := appName != "" || (gvk.Group == application.Group && gvk.Kind == application.ApplicationKind) // If the resource is not a tracked resource, we will look up argocd.argoproj.io/apply-resources-update and decide // whether we generate hash or not. // If argocd.argoproj.io/apply-resources-update is presented and is true, return true // Else return false - if !isTrackedResources { + if !isTrackedResource { if val, ok := un.GetAnnotations()[AnnotationApplyResourcesUpdate]; ok { applyResourcesUpdate, err := strconv.ParseBool(val) if err != nil { @@ -384,7 +383,7 @@ func shouldHashManifest(appName string, gvk schema.GroupVersionKind, un *unstruc return false } - return isTrackedResources + return isTrackedResource } // isRetryableError is a helper method to see whether an error diff --git a/docs/operator-manual/reconcile.md b/docs/operator-manual/reconcile.md index 1db8795892b47..bb693c6242413 100644 --- a/docs/operator-manual/reconcile.md +++ b/docs/operator-manual/reconcile.md @@ -112,13 +112,12 @@ data: - .status.conditions[].lastTransitionTime ``` -## Tracking Dependent Resources +## Ignoring updates for untracked resources -Dependent resources by default are not being tracked. Therefore, we cannot generate any hash of those objects and utilize -the `ignoreResourceUpdates` configuration. +ArgoCD will only apply `ignoreResourceUpdates` configuration to tracked resources of an application. This means dependant resources, such as a `ReplicaSet` and `Pod` created by a `Deployment`, will not ignore any updates and trigger a reconcile of the application for any changes. -If you want to track the dependent object and apply the `ignoreResourceUpdates` configuration, you can add -`argocd.argoproj.io/apply-resources-update=true` annotation in the dependent resources manifest: +If you want to apply the `ignoreResourceUpdates` configuration to an untracked resource, you can add the +`argocd.argoproj.io/ignore-resource-updates=true` annotation in the dependent resources manifest. ## Example @@ -153,7 +152,7 @@ spec: restartPolicy: OnFailure ``` -Then you can update `argocd-cm` configMap to ignore the dependent resources: +The resource updates will be ignored based on your the `ignoreResourceUpdates` configuration in the `argocd-cm` configMap: `argocd-cm`: ```yaml @@ -164,6 +163,3 @@ resource.customizations.ignoreResourceUpdates.Pod: | jsonPointers: - /status ``` - -Note: If you set `argocd.argoproj.io/apply-resources-update: "false"`, no hash will be generated and `ignoreResourceUpdates` -cannot be applied on those resources. \ No newline at end of file From c29e0fbdfa181ade9fab404db133cfc99bf76eb3 Mon Sep 17 00:00:00 2001 From: kahoulei Date: Mon, 17 Jun 2024 15:40:31 -0700 Subject: [PATCH 19/21] update annotation name Signed-off-by: kahoulei --- controller/cache/cache.go | 12 ++++++------ controller/cache/cache_test.go | 12 ++++++------ docs/operator-manual/reconcile.md | 7 ++++--- docs/user-guide/annotations-and-labels.md | 2 +- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/controller/cache/cache.go b/controller/cache/cache.go index 288be9a78a8aa..2eb1d0ec8ab9c 100644 --- a/controller/cache/cache.go +++ b/controller/cache/cache.go @@ -71,9 +71,9 @@ const ( // EnvClusterCacheRetryUseBackoff is the env variable to control whether to use a backoff strategy with the retry during cluster cache sync EnvClusterCacheRetryUseBackoff = "ARGOCD_CLUSTER_CACHE_RETRY_USE_BACKOFF" - // AnnotationApplyResourcesUpdate when set to true on an untracked resource, + // AnnotationIgnoreResourcesUpdate when set to true on an untracked resource, // argo will apply `ignoreResourceUpdates` configuration on it. - AnnotationApplyResourcesUpdate = "argocd.argoproj.io/apply-resources-update" + AnnotationIgnoreResourcesUpdate = "argocd.argoproj.io/ignore-resources-update" ) // GitOps engine cluster cache tuning options @@ -361,19 +361,19 @@ func skipResourceUpdate(oldInfo, newInfo *ResourceInfo) bool { // If there's an app name from resource tracking, or if this is itself an app, we should generate a hash. // Otherwise, the hashing should be skipped to save CPU time. func shouldHashManifest(appName string, gvk schema.GroupVersionKind, un *unstructured.Unstructured) bool { - // Only hash if the resource belongs to an app OR argocd.argoproj.io/apply-resources-update is present and set to true + // Only hash if the resource belongs to an app OR argocd.argoproj.io/ignore-resources-update is present and set to true // Best - Only hash for resources that are part of an app or their dependencies // (current) - Only hash for resources that are part of an app + all apps that might be from an ApplicationSet // Orphan - If orphan is enabled, hash should be made on all resource of that namespace and a config to disable it // Worst - Hash all resources watched by Argo isTrackedResource := appName != "" || (gvk.Group == application.Group && gvk.Kind == application.ApplicationKind) - // If the resource is not a tracked resource, we will look up argocd.argoproj.io/apply-resources-update and decide + // If the resource is not a tracked resource, we will look up argocd.argoproj.io/ignore-resources-update and decide // whether we generate hash or not. - // If argocd.argoproj.io/apply-resources-update is presented and is true, return true + // If argocd.argoproj.io/ignore-resources-update is presented and is true, return true // Else return false if !isTrackedResource { - if val, ok := un.GetAnnotations()[AnnotationApplyResourcesUpdate]; ok { + if val, ok := un.GetAnnotations()[AnnotationIgnoreResourcesUpdate]; ok { applyResourcesUpdate, err := strconv.ParseBool(val) if err != nil { applyResourcesUpdate = false diff --git a/controller/cache/cache_test.go b/controller/cache/cache_test.go index 17ab09f738822..0ff73a0a306b4 100644 --- a/controller/cache/cache_test.go +++ b/controller/cache/cache_test.go @@ -694,27 +694,27 @@ func TestShouldHashManifest(t *testing.T) { want: false, }, { - name: "argocd.argoproj.io/apply-resources-update=true", + name: "argocd.argoproj.io/ignore-resources-update=true", appName: "", gvk: schema.GroupVersionKind{Group: application.Group, Kind: "kind1"}, un: &unstructured.Unstructured{}, - annotations: map[string]string{"argocd.argoproj.io/apply-resources-update": "true"}, + annotations: map[string]string{"argocd.argoproj.io/ignore-resources-update": "true"}, want: true, }, { - name: "argocd.argoproj.io/apply-resources-update=invalid", + name: "argocd.argoproj.io/ignore-resources-update=invalid", appName: "", gvk: schema.GroupVersionKind{Group: application.Group, Kind: "kind1"}, un: &unstructured.Unstructured{}, - annotations: map[string]string{"argocd.argoproj.io/apply-resources-update": "invalid"}, + annotations: map[string]string{"argocd.argoproj.io/ignore-resources-update": "invalid"}, want: false, }, { - name: "argocd.argoproj.io/apply-resources-update=false", + name: "argocd.argoproj.io/ignore-resources-update=false", appName: "", gvk: schema.GroupVersionKind{Group: application.Group, Kind: "kind1"}, un: &unstructured.Unstructured{}, - annotations: map[string]string{"argocd.argoproj.io/apply-resources-update": "false"}, + annotations: map[string]string{"argocd.argoproj.io/ignore-resources-update": "false"}, want: false, }, } diff --git a/docs/operator-manual/reconcile.md b/docs/operator-manual/reconcile.md index bb693c6242413..4f7a001fa4dca 100644 --- a/docs/operator-manual/reconcile.md +++ b/docs/operator-manual/reconcile.md @@ -4,7 +4,8 @@ By default, an Argo CD Application is refreshed every time a resource that belon Kubernetes controllers often update the resources they watch periodically, causing continuous reconcile operation on the Application and a high CPU usage on the `argocd-application-controller`. Argo CD allows you to optionally ignore resource updates on specific fields -for [tracked resources](../user-guide/resource_tracking.md). +for [tracked resources](../user-guide/resource_tracking.md). +For untracked resources, you can [use the argocd.argoproj.io/ignore-resource-updates annotations](#ignoring-updates-for-untracked-resources) When a resource update is ignored, if the resource's [health status](./health.md) does not change, the Application that this resource belongs to will not be reconciled. @@ -134,12 +135,12 @@ spec: jobTemplate: metadata: annotations: - argocd.argoproj.io/apply-resources-update: "true" + argocd.argoproj.io/ignore-resources-update: "true" spec: template: metadata: annotations: - argocd.argoproj.io/apply-resources-update: "true" + argocd.argoproj.io/ignore-resources-update: "true" spec: containers: - name: hello diff --git a/docs/user-guide/annotations-and-labels.md b/docs/user-guide/annotations-and-labels.md index f1321e0af5ffd..ad61cf7f5fbe7 100644 --- a/docs/user-guide/annotations-and-labels.md +++ b/docs/user-guide/annotations-and-labels.md @@ -14,7 +14,7 @@ | argocd.argoproj.io/sync-options | any | [see sync options docs](sync-options.md) | Provides a variety of settings to determine how an Application's resources are synced. | | argocd.argoproj.io/sync-wave | any | [see sync waves docs](sync-waves.md) | | | argocd.argoproj.io/tracking-id | any | any | Used by Argo CD to track resources it manages. See [resource tracking docs](resource_tracking.md) for details. | -| argocd.argoproj.io/apply-resources-update | any | `"true"`, `false` | Used by Argo CD to ignore resource updates. See [reconcile docs](..%2Foperator-manual%2Freconcile.md)reconcile_docs for details. | +| argocd.argoproj.io/ignore-resources-update | any | `"true"`, `false` | Used by Argo CD to ignore resource updates. See [reconcile docs](..%2Foperator-manual%2Freconcile.md)reconcile_docs for details. | | link.argocd.argoproj.io/{some link name} | any | An http(s) URL | Adds a link to the Argo CD UI for the resource. See [external URL docs](external-url.md) for details. | | pref.argocd.argoproj.io/default-pod-sort | Application | [see UI customization docs](../operator-manual/ui-customization.md) | Sets the Application's default grouping mechanism. | | pref.argocd.argoproj.io/default-view | Application | [see UI customization docs](../operator-manual/ui-customization.md) | Sets the Application's default view mode (e.g. "tree" or "list") | From e4b3837e8e1c3b624ced1e8fff7917232cb26dd2 Mon Sep 17 00:00:00 2001 From: kahoulei Date: Tue, 18 Jun 2024 07:30:25 -0700 Subject: [PATCH 20/21] rename annotation Signed-off-by: kahoulei --- controller/cache/cache.go | 12 ++++++------ controller/cache/cache_test.go | 12 ++++++------ docs/operator-manual/reconcile.md | 4 ++-- docs/user-guide/annotations-and-labels.md | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/controller/cache/cache.go b/controller/cache/cache.go index 2eb1d0ec8ab9c..21436d23030ff 100644 --- a/controller/cache/cache.go +++ b/controller/cache/cache.go @@ -71,9 +71,9 @@ const ( // EnvClusterCacheRetryUseBackoff is the env variable to control whether to use a backoff strategy with the retry during cluster cache sync EnvClusterCacheRetryUseBackoff = "ARGOCD_CLUSTER_CACHE_RETRY_USE_BACKOFF" - // AnnotationIgnoreResourcesUpdate when set to true on an untracked resource, + // AnnotationIgnoreResourceUpdates when set to true on an untracked resource, // argo will apply `ignoreResourceUpdates` configuration on it. - AnnotationIgnoreResourcesUpdate = "argocd.argoproj.io/ignore-resources-update" + AnnotationIgnoreResourceUpdates = "argocd.argoproj.io/ignore-resource-updates" ) // GitOps engine cluster cache tuning options @@ -361,19 +361,19 @@ func skipResourceUpdate(oldInfo, newInfo *ResourceInfo) bool { // If there's an app name from resource tracking, or if this is itself an app, we should generate a hash. // Otherwise, the hashing should be skipped to save CPU time. func shouldHashManifest(appName string, gvk schema.GroupVersionKind, un *unstructured.Unstructured) bool { - // Only hash if the resource belongs to an app OR argocd.argoproj.io/ignore-resources-update is present and set to true + // Only hash if the resource belongs to an app OR argocd.argoproj.io/ignore-resource-updates is present and set to true // Best - Only hash for resources that are part of an app or their dependencies // (current) - Only hash for resources that are part of an app + all apps that might be from an ApplicationSet // Orphan - If orphan is enabled, hash should be made on all resource of that namespace and a config to disable it // Worst - Hash all resources watched by Argo isTrackedResource := appName != "" || (gvk.Group == application.Group && gvk.Kind == application.ApplicationKind) - // If the resource is not a tracked resource, we will look up argocd.argoproj.io/ignore-resources-update and decide + // If the resource is not a tracked resource, we will look up argocd.argoproj.io/ignore-resource-updates and decide // whether we generate hash or not. - // If argocd.argoproj.io/ignore-resources-update is presented and is true, return true + // If argocd.argoproj.io/ignore-resource-updates is presented and is true, return true // Else return false if !isTrackedResource { - if val, ok := un.GetAnnotations()[AnnotationIgnoreResourcesUpdate]; ok { + if val, ok := un.GetAnnotations()[AnnotationIgnoreResourceUpdates]; ok { applyResourcesUpdate, err := strconv.ParseBool(val) if err != nil { applyResourcesUpdate = false diff --git a/controller/cache/cache_test.go b/controller/cache/cache_test.go index 0ff73a0a306b4..362bbb22a881c 100644 --- a/controller/cache/cache_test.go +++ b/controller/cache/cache_test.go @@ -694,27 +694,27 @@ func TestShouldHashManifest(t *testing.T) { want: false, }, { - name: "argocd.argoproj.io/ignore-resources-update=true", + name: "argocd.argoproj.io/ignore-resource-updates=true", appName: "", gvk: schema.GroupVersionKind{Group: application.Group, Kind: "kind1"}, un: &unstructured.Unstructured{}, - annotations: map[string]string{"argocd.argoproj.io/ignore-resources-update": "true"}, + annotations: map[string]string{"argocd.argoproj.io/ignore-resource-updates": "true"}, want: true, }, { - name: "argocd.argoproj.io/ignore-resources-update=invalid", + name: "argocd.argoproj.io/ignore-resource-updates=invalid", appName: "", gvk: schema.GroupVersionKind{Group: application.Group, Kind: "kind1"}, un: &unstructured.Unstructured{}, - annotations: map[string]string{"argocd.argoproj.io/ignore-resources-update": "invalid"}, + annotations: map[string]string{"argocd.argoproj.io/ignore-resource-updates": "invalid"}, want: false, }, { - name: "argocd.argoproj.io/ignore-resources-update=false", + name: "argocd.argoproj.io/ignore-resource-updates=false", appName: "", gvk: schema.GroupVersionKind{Group: application.Group, Kind: "kind1"}, un: &unstructured.Unstructured{}, - annotations: map[string]string{"argocd.argoproj.io/ignore-resources-update": "false"}, + annotations: map[string]string{"argocd.argoproj.io/ignore-resource-updates": "false"}, want: false, }, } diff --git a/docs/operator-manual/reconcile.md b/docs/operator-manual/reconcile.md index 4f7a001fa4dca..9b8044e9e0ffd 100644 --- a/docs/operator-manual/reconcile.md +++ b/docs/operator-manual/reconcile.md @@ -135,12 +135,12 @@ spec: jobTemplate: metadata: annotations: - argocd.argoproj.io/ignore-resources-update: "true" + argocd.argoproj.io/ignore-resource-updates: "true" spec: template: metadata: annotations: - argocd.argoproj.io/ignore-resources-update: "true" + argocd.argoproj.io/ignore-resource-updates: "true" spec: containers: - name: hello diff --git a/docs/user-guide/annotations-and-labels.md b/docs/user-guide/annotations-and-labels.md index ad61cf7f5fbe7..2b4e9968dcfb4 100644 --- a/docs/user-guide/annotations-and-labels.md +++ b/docs/user-guide/annotations-and-labels.md @@ -14,7 +14,7 @@ | argocd.argoproj.io/sync-options | any | [see sync options docs](sync-options.md) | Provides a variety of settings to determine how an Application's resources are synced. | | argocd.argoproj.io/sync-wave | any | [see sync waves docs](sync-waves.md) | | | argocd.argoproj.io/tracking-id | any | any | Used by Argo CD to track resources it manages. See [resource tracking docs](resource_tracking.md) for details. | -| argocd.argoproj.io/ignore-resources-update | any | `"true"`, `false` | Used by Argo CD to ignore resource updates. See [reconcile docs](..%2Foperator-manual%2Freconcile.md)reconcile_docs for details. | +| argocd.argoproj.io/ignore-resource-updates | any | `"true"`, `false` | Used by Argo CD to ignore resource updates. See [reconcile docs](..%2Foperator-manual%2Freconcile.md)reconcile_docs for details. | | link.argocd.argoproj.io/{some link name} | any | An http(s) URL | Adds a link to the Argo CD UI for the resource. See [external URL docs](external-url.md) for details. | | pref.argocd.argoproj.io/default-pod-sort | Application | [see UI customization docs](../operator-manual/ui-customization.md) | Sets the Application's default grouping mechanism. | | pref.argocd.argoproj.io/default-view | Application | [see UI customization docs](../operator-manual/ui-customization.md) | Sets the Application's default view mode (e.g. "tree" or "list") | From bec8ffe48df28c0e8b648e26dbdf532f4bdc1c0c Mon Sep 17 00:00:00 2001 From: kahoulei Date: Tue, 18 Jun 2024 08:51:57 -0700 Subject: [PATCH 21/21] lint check Signed-off-by: kahoulei --- controller/cache/cache_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/controller/cache/cache_test.go b/controller/cache/cache_test.go index 362bbb22a881c..63935a1e453f4 100644 --- a/controller/cache/cache_test.go +++ b/controller/cache/cache_test.go @@ -592,7 +592,8 @@ func TestSkipResourceUpdate(t *testing.T) { assert.False(t, skipResourceUpdate(&ResourceInfo{ manifestHash: hash1_x, Health: &health.HealthStatus{ - Status: health.HealthStatusHealthy}, + Status: health.HealthStatusHealthy, + }, }, &ResourceInfo{ manifestHash: hash3_x, Health: nil, @@ -730,5 +731,4 @@ func TestShouldHashManifest(t *testing.T) { } }) } - }