diff --git a/pkg/resourceinterpreter/defaultinterpreter/healthy.go b/pkg/resourceinterpreter/defaultinterpreter/healthy.go index 6c0220807..42c781e95 100644 --- a/pkg/resourceinterpreter/defaultinterpreter/healthy.go +++ b/pkg/resourceinterpreter/defaultinterpreter/healthy.go @@ -23,6 +23,7 @@ func getAllDefaultHealthInterpreter() map[schema.GroupVersionKind]healthInterpre s[corev1.SchemeGroupVersion.WithKind(util.ServiceKind)] = interpretServiceHealth s[networkingv1.SchemeGroupVersion.WithKind(util.IngressKind)] = interpretIngressHealth s[corev1.SchemeGroupVersion.WithKind(util.PersistentVolumeClaimKind)] = interpretPersistentVolumeClaimHealth + s[corev1.SchemeGroupVersion.WithKind(util.PodKind)] = interpretPodHealth s[policyv1.SchemeGroupVersion.WithKind(util.PodDisruptionBudgetKind)] = interpretPodDisruptionBudgetHealth return s } @@ -147,6 +148,25 @@ func interpretPersistentVolumeClaimHealth(object *unstructured.Unstructured) (bo return pvc.Status.Phase == corev1.ClaimBound, nil } +func interpretPodHealth(object *unstructured.Unstructured) (bool, error) { + pod := &corev1.Pod{} + err := helper.ConvertToTypedObject(object, pod) + if err != nil { + return false, err + } + + if pod.Status.Phase == corev1.PodSucceeded { + return true, nil + } + + _, condition := helper.GetPodCondition(&pod.Status, corev1.PodReady) + if pod.Status.Phase == corev1.PodRunning && condition != nil && condition.Status == corev1.ConditionTrue { + return true, nil + } + + return false, nil +} + func interpretPodDisruptionBudgetHealth(object *unstructured.Unstructured) (bool, error) { pdb := &policyv1.PodDisruptionBudget{} err := helper.ConvertToTypedObject(object, pdb) diff --git a/pkg/resourceinterpreter/defaultinterpreter/healthy_test.go b/pkg/resourceinterpreter/defaultinterpreter/healthy_test.go index 0283808eb..cf03a9079 100644 --- a/pkg/resourceinterpreter/defaultinterpreter/healthy_test.go +++ b/pkg/resourceinterpreter/defaultinterpreter/healthy_test.go @@ -569,6 +569,123 @@ func Test_interpretPersistentVolumeClaimHealth(t *testing.T) { } } +func Test_interpretPodHealth(t *testing.T) { + tests := []struct { + name string + object *unstructured.Unstructured + want bool + wantErr bool + }{ + { + name: "service type pod healthy", + object: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "v1", + "kind": "Pod", + "metadata": map[string]interface{}{ + "name": "fake-pod", + }, + "status": map[string]interface{}{ + "conditions": []map[string]string{ + { + "type": "Ready", + "status": "True", + }, + }, + "phase": "Running", + }, + }, + }, + want: true, + wantErr: false, + }, + { + name: "job type pod healthy", + object: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "v1", + "kind": "Pod", + "metadata": map[string]interface{}{ + "name": "fake-pod", + }, + "status": map[string]interface{}{ + "phase": "Succeeded", + }, + }, + }, + want: true, + wantErr: false, + }, + { + name: "pod condition ready false", + object: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "v1", + "kind": "Pod", + "metadata": map[string]interface{}{ + "name": "fake-pod", + }, + "status": map[string]interface{}{ + "conditions": []map[string]string{ + { + "type": "Ready", + "status": "Unknown", + }, + }, + "phase": "Running", + }, + }, + }, + want: false, + wantErr: false, + }, + { + name: "pod phase not running and not succeeded", + object: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "v1", + "kind": "Pod", + "metadata": map[string]interface{}{ + "name": "fake-pod", + }, + "status": map[string]interface{}{ + "phase": "Failed", + }, + }, + }, + want: false, + wantErr: false, + }, + { + name: "condition or phase nil", + object: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "v1", + "kind": "Pod", + "metadata": map[string]interface{}{ + "name": "fake-pod", + }, + }, + }, + want: false, + wantErr: false, + }, + } + for i := range tests { + tt := tests[i] + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + got, err := interpretPodHealth(tt.object) + if (err != nil) != tt.wantErr { + t.Errorf("interpretPodHealth() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("interpretPodHealth() = %v, want %v", got, tt.want) + } + }) + } +} func Test_interpretPodDisruptionBudgetHealth(t *testing.T) { tests := []struct { name string