diff --git a/api/v1alpha1/extendeddaemonset_types.go b/api/v1alpha1/extendeddaemonset_types.go index 43f97c5a..bddddac5 100644 --- a/api/v1alpha1/extendeddaemonset_types.go +++ b/api/v1alpha1/extendeddaemonset_types.go @@ -151,6 +151,14 @@ const ( ExtendedDaemonSetStatusReasonErrImagePull ExtendedDaemonSetStatusReason = "ErrImagePull" // ExtendedDaemonSetStatusReasonImagePullBackOff represent ImagePullBackOff as the reason for the ExtendedDaemonSet status state. ExtendedDaemonSetStatusReasonImagePullBackOff ExtendedDaemonSetStatusReason = "ImagePullBackOff" + // ExtendedDaemonSetStatusReasonImageInspectError represent ImageInspectError as the reason for the ExtendedDaemonSet status state. + ExtendedDaemonSetStatusReasonImageInspectError ExtendedDaemonSetStatusReason = "ImageInspectError" + // ExtendedDaemonSetStatusReasonErrImageNeverPull represent ErrImageNeverPull as the reason for the ExtendedDaemonSet status state. + ExtendedDaemonSetStatusReasonErrImageNeverPull ExtendedDaemonSetStatusReason = "ErrImageNeverPull" + // ExtendedDaemonSetStatusReasonRegistryUnavailable represent RegistryUnavailable as the reason for the ExtendedDaemonSet status state. + ExtendedDaemonSetStatusReasonRegistryUnavailable ExtendedDaemonSetStatusReason = "RegistryUnavailable" + // ExtendedDaemonSetStatusReasonInvalidImageName represent InvalidImageName as the reason for the ExtendedDaemonSet status state. + ExtendedDaemonSetStatusReasonInvalidImageName ExtendedDaemonSetStatusReason = "InvalidImageName" // ExtendedDaemonSetStatusReasonCreateContainerConfigError represent CreateContainerConfigError as the reason for the ExtendedDaemonSet status state. ExtendedDaemonSetStatusReasonCreateContainerConfigError ExtendedDaemonSetStatusReason = "CreateContainerConfigError" // ExtendedDaemonSetStatusReasonCreateContainerError represent CreateContainerError as the reason for the ExtendedDaemonSet status state. @@ -159,6 +167,8 @@ const ( ExtendedDaemonSetStatusReasonPreStartHookError ExtendedDaemonSetStatusReason = "PreStartHookError" // ExtendedDaemonSetStatusReasonPostStartHookError represent PostStartHookError as the reason for the ExtendedDaemonSet status state. ExtendedDaemonSetStatusReasonPostStartHookError ExtendedDaemonSetStatusReason = "PostStartHookError" + // ExtendedDaemonSetStatusReasonPreCreateHookError represent PreCreateHookError as the reason for the ExtendedDaemonSet status state. + ExtendedDaemonSetStatusReasonPreCreateHookError ExtendedDaemonSetStatusReason = "PreCreateHookError" // ExtendedDaemonSetStatusReasonStartError represent StartError as the reason for the ExtendedDaemonSet status state. ExtendedDaemonSetStatusReasonStartError ExtendedDaemonSetStatusReason = "StartError" // ExtendedDaemonSetStatusReasonUnknown represents an Unknown reason for the status state. diff --git a/pkg/controller/utils/pod/pod.go b/pkg/controller/utils/pod/pod.go index f73ca543..b22e5579 100644 --- a/pkg/controller/utils/pod/pod.go +++ b/pkg/controller/utils/pod/pod.go @@ -142,7 +142,9 @@ func HighestRestartCount(pod *v1.Pod) (int, datadoghqv1alpha1.ExtendedDaemonSetS restartCount = s.RestartCount reason = datadoghqv1alpha1.ExtendedDaemonSetStatusReasonUnknown if s.LastTerminationState != (v1.ContainerState{}) && *s.LastTerminationState.Terminated != (v1.ContainerStateTerminated{}) { - reason = datadoghqv1alpha1.ExtendedDaemonSetStatusReason(s.LastTerminationState.Terminated.Reason) + if s.LastTerminationState.Terminated.Reason != "" { // The Reason field is optional and can be empty + reason = datadoghqv1alpha1.ExtendedDaemonSetStatusReason(s.LastTerminationState.Terminated.Reason) + } } } } @@ -160,7 +162,10 @@ func MostRecentRestart(pod *v1.Pod) (time.Time, datadoghqv1alpha1.ExtendedDaemon if s.RestartCount != 0 && s.LastTerminationState != (v1.ContainerState{}) && s.LastTerminationState.Terminated != (&v1.ContainerStateTerminated{}) { if s.LastTerminationState.Terminated.FinishedAt.After(restartTime) { restartTime = s.LastTerminationState.Terminated.FinishedAt.Time - reason = datadoghqv1alpha1.ExtendedDaemonSetStatusReason(s.LastTerminationState.Terminated.Reason) + reason = datadoghqv1alpha1.ExtendedDaemonSetStatusReasonUnknown + if s.LastTerminationState.Terminated.Reason != "" { // The Reason field is optional and can be empty + reason = datadoghqv1alpha1.ExtendedDaemonSetStatusReason(s.LastTerminationState.Terminated.Reason) + } } } } @@ -168,24 +173,25 @@ func MostRecentRestart(pod *v1.Pod) (time.Time, datadoghqv1alpha1.ExtendedDaemon return restartTime, reason } -var cannotStartReasons = []string{ - "ErrImagePull", - "ImagePullBackOff", - "CreateContainerConfigError", - "CreateContainerError", - "PreStartHookError", - "PostStartHookError", +var cannotStartReasons = map[string]struct{}{ + "ErrImagePull": {}, + "ImagePullBackOff": {}, + "ImageInspectError": {}, + "ErrImageNeverPull": {}, + "RegistryUnavailable": {}, + "InvalidImageName": {}, + "CreateContainerConfigError": {}, + "CreateContainerError": {}, + "PreStartHookError": {}, + "PostStartHookError": {}, + "PreCreateHookError": {}, } // IsCannotStartReason returns true for a reason that is considered an abnormal cannot start condition. func IsCannotStartReason(reason string) bool { - for _, cannot := range cannotStartReasons { - if cannot == reason { - return true - } - } + _, found := cannotStartReasons[reason] - return false + return found } // CannotStart returns true if the Pod is currently experiencing abnormal start condition. @@ -208,10 +214,15 @@ func convertReasonToEDSStatusReason(reason string) datadoghqv1alpha1.ExtendedDae datadoghqv1alpha1.ExtendedDaemonSetStatusSlowStartTimeoutExceeded, datadoghqv1alpha1.ExtendedDaemonSetStatusReasonErrImagePull, datadoghqv1alpha1.ExtendedDaemonSetStatusReasonImagePullBackOff, + datadoghqv1alpha1.ExtendedDaemonSetStatusReasonImageInspectError, + datadoghqv1alpha1.ExtendedDaemonSetStatusReasonErrImageNeverPull, + datadoghqv1alpha1.ExtendedDaemonSetStatusReasonRegistryUnavailable, + datadoghqv1alpha1.ExtendedDaemonSetStatusReasonInvalidImageName, datadoghqv1alpha1.ExtendedDaemonSetStatusReasonCreateContainerConfigError, datadoghqv1alpha1.ExtendedDaemonSetStatusReasonCreateContainerError, datadoghqv1alpha1.ExtendedDaemonSetStatusReasonPreStartHookError, datadoghqv1alpha1.ExtendedDaemonSetStatusReasonPostStartHookError, + datadoghqv1alpha1.ExtendedDaemonSetStatusReasonPreCreateHookError, datadoghqv1alpha1.ExtendedDaemonSetStatusReasonStartError, datadoghqv1alpha1.ExtendedDaemonSetStatusReasonUnknown: return t diff --git a/pkg/controller/utils/pod/pod_test.go b/pkg/controller/utils/pod/pod_test.go index 32858196..3cfb5f76 100644 --- a/pkg/controller/utils/pod/pod_test.go +++ b/pkg/controller/utils/pod/pod_test.go @@ -217,7 +217,7 @@ func TestIsPodReady(t *testing.T) { } func TestIsCannotStartReason(t *testing.T) { - for _, reason := range cannotStartReasons { + for reason := range cannotStartReasons { cannotStart := IsCannotStartReason(reason) assert.True(t, cannotStart) } @@ -479,6 +479,24 @@ func Test_HighestRestartCount(t *testing.T) { wantRestartCount: 10, wantReason: datadoghqv1alpha1.ExtendedDaemonSetStatusReasonCLB, }, + { + name: "restarts with empty reason", + pod: ctrltest.NewPod("bar", "pod1", "node1", &ctrltest.NewPodOptions{ + ContainerStatuses: []v1.ContainerStatus{ + { + RestartCount: 10, + LastTerminationState: v1.ContainerState{ + Terminated: &v1.ContainerStateTerminated{ + Reason: "", + }, + }, + }, + }, + }, + ), + wantRestartCount: 10, + wantReason: datadoghqv1alpha1.ExtendedDaemonSetStatusReasonUnknown, + }, } for _, tt := range tests { @@ -538,6 +556,25 @@ func Test_MostRecentRestart(t *testing.T) { wantTime: time.Time{}, wantReason: "", }, + { + name: "restarts with empty reason", + pod: ctrltest.NewPod("bar", "pod1", "node1", &ctrltest.NewPodOptions{ + ContainerStatuses: []v1.ContainerStatus{ + { + RestartCount: 10, + LastTerminationState: v1.ContainerState{ + Terminated: &v1.ContainerStateTerminated{ + Reason: "", + FinishedAt: metav1.NewTime(now.Add(-time.Hour)), + }, + }, + }, + }, + }, + ), + wantTime: now.Add(-time.Hour), + wantReason: datadoghqv1alpha1.ExtendedDaemonSetStatusReasonUnknown, + }, } for _, tt := range tests {