github.com/argoproj/argo-cd/v3@v3.2.1/controller/health.go (about) 1 package controller 2 3 import ( 4 "fmt" 5 6 "github.com/argoproj/gitops-engine/pkg/health" 7 hookutil "github.com/argoproj/gitops-engine/pkg/sync/hook" 8 "github.com/argoproj/gitops-engine/pkg/sync/ignore" 9 kubeutil "github.com/argoproj/gitops-engine/pkg/utils/kube" 10 log "github.com/sirupsen/logrus" 11 "k8s.io/apimachinery/pkg/runtime/schema" 12 13 "github.com/argoproj/argo-cd/v3/common" 14 "github.com/argoproj/argo-cd/v3/pkg/apis/application" 15 appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" 16 applog "github.com/argoproj/argo-cd/v3/util/app/log" 17 "github.com/argoproj/argo-cd/v3/util/lua" 18 ) 19 20 // setApplicationHealth updates the health statuses of all resources performed in the comparison 21 func setApplicationHealth(resources []managedResource, statuses []appv1.ResourceStatus, resourceOverrides map[string]appv1.ResourceOverride, app *appv1.Application, persistResourceHealth bool) (health.HealthStatusCode, error) { 22 var savedErr error 23 var errCount uint 24 25 appHealthStatus := health.HealthStatusHealthy 26 for i, res := range resources { 27 if res.Target != nil && hookutil.Skip(res.Target) { 28 continue 29 } 30 if res.Live != nil && res.Live.GetAnnotations() != nil && res.Live.GetAnnotations()[common.AnnotationIgnoreHealthCheck] == "true" { 31 continue 32 } 33 if res.Live != nil && (hookutil.IsHook(res.Live) || ignore.Ignore(res.Live)) { 34 continue 35 } 36 37 var healthStatus *health.HealthStatus 38 var err error 39 healthOverrides := lua.ResourceHealthOverrides(resourceOverrides) 40 gvk := schema.GroupVersionKind{Group: res.Group, Version: res.Version, Kind: res.Kind} 41 if res.Live == nil { 42 healthStatus = &health.HealthStatus{Status: health.HealthStatusMissing} 43 } else { 44 // App the manages itself should not affect own health 45 if isSelfReferencedApp(app, kubeutil.GetObjectRef(res.Live)) { 46 continue 47 } 48 healthStatus, err = health.GetResourceHealth(res.Live, healthOverrides) 49 if err != nil && savedErr == nil { 50 errCount++ 51 savedErr = fmt.Errorf("failed to get resource health for %q with name %q in namespace %q: %w", res.Live.GetKind(), res.Live.GetName(), res.Live.GetNamespace(), err) 52 // also log so we don't lose the message 53 log.WithFields(applog.GetAppLogFields(app)).Warn(savedErr) 54 } 55 } 56 57 if healthStatus == nil { 58 continue 59 } 60 61 if persistResourceHealth { 62 resHealth := appv1.HealthStatus{Status: healthStatus.Status, Message: healthStatus.Message} 63 statuses[i].Health = &resHealth 64 } else { 65 statuses[i].Health = nil 66 } 67 68 // Is health status is missing but resource has not built-in/custom health check then it should not affect parent app health 69 if _, hasOverride := healthOverrides[lua.GetConfigMapKey(gvk)]; healthStatus.Status == health.HealthStatusMissing && !hasOverride && health.GetHealthCheckFunc(gvk) == nil { 70 continue 71 } 72 73 // Missing or Unknown health status of child Argo CD app should not affect parent 74 if res.Kind == application.ApplicationKind && res.Group == application.Group && (healthStatus.Status == health.HealthStatusMissing || healthStatus.Status == health.HealthStatusUnknown) { 75 continue 76 } 77 78 if health.IsWorse(appHealthStatus, healthStatus.Status) { 79 appHealthStatus = healthStatus.Status 80 } 81 } 82 if persistResourceHealth { 83 app.Status.ResourceHealthSource = appv1.ResourceHealthLocationInline 84 } else { 85 app.Status.ResourceHealthSource = appv1.ResourceHealthLocationAppTree 86 } 87 if savedErr != nil && errCount > 1 { 88 savedErr = fmt.Errorf("see application-controller logs for %d other errors; most recent error was: %w", errCount-1, savedErr) 89 } 90 return appHealthStatus, savedErr 91 }