From a320f73ba4e8bd3e306f4c40d33f72a8710ca5b5 Mon Sep 17 00:00:00 2001 From: cef Date: Fri, 18 Oct 2024 16:41:59 -0500 Subject: [PATCH] feat(app): add ignore-healthcheck annotation Signed-off-by: cef --- common/common.go | 4 +++ controller/health.go | 4 +++ controller/health_test.go | 9 +++++ .../job-failed-ignore-healthcheck.yaml | 36 +++++++++++++++++++ docs/operator-manual/health.md | 13 +++++++ 5 files changed, 66 insertions(+) create mode 100644 controller/testdata/job-failed-ignore-healthcheck.yaml diff --git a/common/common.go b/common/common.go index d2e47aa5b1607..eea862644d166 100644 --- a/common/common.go +++ b/common/common.go @@ -185,6 +185,10 @@ const ( // AnnotationCompareOptions is a comma-separated list of options for comparison AnnotationCompareOptions = "argocd.argoproj.io/compare-options" + // AnnotationIgnoreHealthCheck when set on an Application's immediate child indicates that its health check + // can be disregarded. + AnnotationIgnoreHealthCheck = "argocd.argoproj.io/ignore-healthcheck" + // AnnotationKeyManagedBy is annotation name which indicates that k8s resource is managed by an application. AnnotationKeyManagedBy = "managed-by" // AnnotationValueManagedByArgoCD is a 'managed-by' annotation value for resources managed by Argo CD diff --git a/controller/health.go b/controller/health.go index f713a574f57d3..2081ad8071627 100644 --- a/controller/health.go +++ b/controller/health.go @@ -10,6 +10,7 @@ import ( log "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/runtime/schema" + "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/argo-cd/v2/pkg/apis/application" appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "github.com/argoproj/argo-cd/v2/util/lua" @@ -24,6 +25,9 @@ func setApplicationHealth(resources []managedResource, statuses []appv1.Resource if res.Target != nil && hookutil.Skip(res.Target) { continue } + if res.Target != nil && res.Target.GetAnnotations() != nil && res.Target.GetAnnotations()[common.AnnotationIgnoreHealthCheck] == "true" { + continue + } if res.Live != nil && (hookutil.IsHook(res.Live) || ignore.Ignore(res.Live)) { continue diff --git a/controller/health_test.go b/controller/health_test.go index efaf4b2a8fc80..8fe848ce5c398 100644 --- a/controller/health_test.go +++ b/controller/health_test.go @@ -65,6 +65,15 @@ func TestSetApplicationHealth(t *testing.T) { healthStatus, err = setApplicationHealth(resources, resourceStatuses, nil, app, true) require.NoError(t, err) assert.Equal(t, health.HealthStatusHealthy, healthStatus.Status) + + // now we set the `argocd.argoproj.io/ignore-healthcheck: "true"` annotation on the job's target. + // The app is considered healthy + failedJob.SetAnnotations(nil) + failedJobIgnoreHealthcheck := resourceFromFile("./testdata/job-failed-ignore-healthcheck.yaml") + resources[1].Target = &failedJobIgnoreHealthcheck + healthStatus, err = setApplicationHealth(resources, resourceStatuses, nil, app, true) + require.NoError(t, err) + assert.Equal(t, health.HealthStatusHealthy, healthStatus.Status) } func TestSetApplicationHealth_ResourceHealthNotPersisted(t *testing.T) { diff --git a/controller/testdata/job-failed-ignore-healthcheck.yaml b/controller/testdata/job-failed-ignore-healthcheck.yaml new file mode 100644 index 0000000000000..62a952203bd12 --- /dev/null +++ b/controller/testdata/job-failed-ignore-healthcheck.yaml @@ -0,0 +1,36 @@ +apiVersion: batch/v1 +kind: Job +metadata: + annotations: + argocd.argoproj.io/ignore-healthcheck: "true" + labels: + job-name: fail + name: fail + namespace: argoci-workflows + selfLink: /apis/batch/v1/namespaces/argoci-workflows/jobs/fail +spec: + backoffLimit: 0 + completions: 1 + parallelism: 1 + template: + metadata: + creationTimestamp: null + labels: + job-name: fail + spec: + containers: + - command: + - sh + - -c + - exit 1 + image: alpine:latest + imagePullPolicy: Always + name: fail + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Never + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 diff --git a/docs/operator-manual/health.md b/docs/operator-manual/health.md index ad23dfa295d11..20d03b9318d25 100644 --- a/docs/operator-manual/health.md +++ b/docs/operator-manual/health.md @@ -227,3 +227,16 @@ App (healthy) └── CustomResource (healthy) <- This resource's health check needs to be fixed to mark the App as unhealthy └── CustomChildResource (unhealthy) ``` +## Ignoring Child Resource Health Check in Applications + +To ignore the health check of an immediate child resource within an Application, set the annotation `argocd.argoproj.io/ignore-healthcheck` to `true`. For example: + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + argocd.argoproj.io/ignore-healthcheck: "true" +``` + +By doing this, the health status of the Deployment will not affect the health of its parent Application. \ No newline at end of file