diff --git a/event_reporter/reporter/application_errors_parser.go b/event_reporter/reporter/application_errors_parser.go index 9b2ccaf22e4fd..5c52d1a5cfde8 100644 --- a/event_reporter/reporter/application_errors_parser.go +++ b/event_reporter/reporter/application_errors_parser.go @@ -135,31 +135,44 @@ func parseAggregativeHealthErrors(rs *appv1.ResourceStatus, apptree *appv1.Appli childNodes := n.GetAllChildNodes(apptree, "") for _, cn := range childNodes { - if cn.Health != nil && cn.Health.Status == health.HealthStatusDegraded { - newErr := events.ObjectError{ - Type: "health", - Level: "error", - Message: cn.Health.Message, - LastSeen: *cn.CreatedAt, - } - - if addReference { - newErr.SourceReference = &events.ErrorSourceReference{ - Group: rs.Group, - Version: rs.Version, - Kind: rs.Kind, - Namespace: rs.Namespace, - Name: rs.Name, - } - } + if newErr := getNodeHealthError(cn, rs, addReference); newErr != nil { + errs = append(errs, newErr) + } + } - errs = append(errs, &newErr) + if len(errs) == 0 { + if newErr := getNodeHealthError(*n, rs, addReference); newErr != nil { + errs = append(errs, newErr) } } return errs } +func getNodeHealthError(node appv1.ResourceNode, managedResource *appv1.ResourceStatus, addReference bool) *events.ObjectError { + if node.Health == nil || node.Health.Status != health.HealthStatusDegraded { + return nil + } + + newErr := &events.ObjectError{ + Type: "health", + Level: "error", + Message: node.Health.Message, + LastSeen: *node.CreatedAt, + } + + if addReference { + newErr.SourceReference = &events.ErrorSourceReference{ + Group: managedResource.Group, + Version: managedResource.Version, + Kind: managedResource.Kind, + Namespace: managedResource.Namespace, + Name: managedResource.Name, + } + } + return newErr +} + func parseAggregativeResourcesSyncErrors(resourceResults appv1.ResourceResults) []*events.ObjectError { var errs []*events.ObjectError diff --git a/event_reporter/reporter/applications_errors_parser_test.go b/event_reporter/reporter/applications_errors_parser_test.go index bb05f67e04fcc..60a820f0fba05 100644 --- a/event_reporter/reporter/applications_errors_parser_test.go +++ b/event_reporter/reporter/applications_errors_parser_test.go @@ -336,4 +336,81 @@ func TestParseAggregativeHealthErrors(t *testing.T) { assert.NotNil(t, errs[0].SourceReference) assert.Equal(t, deployRef.Name, errs[0].SourceReference.Name) }) + + t.Run("should build error from root node if it's degraded while no one of child in degraded health state", func(t *testing.T) { + rsName := "test-deployment" + ns := "test" + errMessage := "backoff pulling image test/test:0.1" + replicaSetRef := v1alpha1.ResourceRef{ + Group: "g", + Version: "v", + Kind: "ReplicaSet", + Name: rsName + "1", + Namespace: ns, + } + + deploymentRef := v1alpha1.ResourceRef{ + Group: "g", + Version: "v", + Kind: "Deployment", + Name: rsName, + Namespace: ns, + } + + appTree := v1alpha1.ApplicationTree{ + Nodes: []v1alpha1.ResourceNode{ + { // Pod + ResourceRef: v1alpha1.ResourceRef{ + Group: "g", + Version: "v", + Kind: "Pod", + Name: rsName + "1-3n235j5", + Namespace: ns, + }, + Health: &v1alpha1.HealthStatus{ + Status: health.HealthStatusProgressing, + Message: "some error of pod", + }, + ParentRefs: []v1alpha1.ResourceRef{replicaSetRef}, + CreatedAt: &metav1.Time{ + Time: time.Now(), + }, + }, + { // ReplicaSet + ResourceRef: replicaSetRef, + Health: &v1alpha1.HealthStatus{ + Status: health.HealthStatusProgressing, + Message: "", + }, + ParentRefs: []v1alpha1.ResourceRef{deploymentRef}, + CreatedAt: &metav1.Time{ + Time: time.Now(), + }, + }, + { // Deployment + ResourceRef: deploymentRef, + Health: &v1alpha1.HealthStatus{ + Status: health.HealthStatusDegraded, + Message: errMessage, + }, + ParentRefs: []v1alpha1.ResourceRef{}, + CreatedAt: &metav1.Time{ + Time: time.Now(), + }, + }, + }, + } + + errs := parseAggregativeHealthErrors(&v1alpha1.ResourceStatus{ + Group: deploymentRef.Group, + Version: deploymentRef.Version, + Kind: deploymentRef.Kind, + Name: deploymentRef.Name, + Namespace: deploymentRef.Namespace, + }, &appTree, true) + assert.Len(t, errs, 1) + assert.Equal(t, errMessage, errs[0].Message) + assert.NotNil(t, errs[0].SourceReference) + assert.Equal(t, deploymentRef.Name, errs[0].SourceReference.Name) + }) }