From 404d64f411097aaa80f1ff581b06e03b3d9b27c3 Mon Sep 17 00:00:00 2001 From: Moshe Immermam Date: Sun, 1 Dec 2024 23:42:47 +0200 Subject: [PATCH 1/3] fix: deployment health fixes --- pkg/health/health.go | 1 + pkg/health/health_deployment.go | 44 +++++-- pkg/health/health_test.go | 30 +---- .../Deployment}/deployment-failed.yaml | 5 + .../Deployment}/deployment-progressing.yaml | 8 +- .../deployment-rollout-failed-unhealthy.yaml | 3 + .../Deployment}/deployment-starting.yaml | 3 + .../Kubernetes/Deployment/restart.yaml | 124 ++++++++++++++++++ pkg/health/testdata/deployment-degraded.yaml | 5 +- 9 files changed, 179 insertions(+), 44 deletions(-) rename pkg/health/testdata/{ => Kubernetes/Deployment}/deployment-failed.yaml (88%) rename pkg/health/testdata/{ => Kubernetes/Deployment}/deployment-progressing.yaml (75%) rename pkg/health/testdata/{ => Kubernetes/Deployment}/deployment-rollout-failed-unhealthy.yaml (94%) rename pkg/health/testdata/{ => Kubernetes/Deployment}/deployment-starting.yaml (95%) create mode 100644 pkg/health/testdata/Kubernetes/Deployment/restart.yaml diff --git a/pkg/health/health.go b/pkg/health/health.go index 7c4326e..e0cc658 100644 --- a/pkg/health/health.go +++ b/pkg/health/health.go @@ -106,6 +106,7 @@ const ( HealthStatusRestart HealthStatusCode = "Restarting" HealthStatusStarting HealthStatusCode = "Starting" HealthStatusFailed HealthStatusCode = "Failed" + HealthStatusFailedCreate HealthStatusCode = "Failed Create" HealthStatusUnschedulable HealthStatusCode = "Unschedulable" HealthStatusUpgradeFailed HealthStatusCode = "UpgradeFailed" HealthStatusOOMKilled HealthStatusCode = "OOMKilled" diff --git a/pkg/health/health_deployment.go b/pkg/health/health_deployment.go index 69cae8f..b007104 100644 --- a/pkg/health/health_deployment.go +++ b/pkg/health/health_deployment.go @@ -54,12 +54,28 @@ func getReplicaHealth(s ReplicaStatus) *HealthStatus { gs := GetGenericStatus(s.Object) + available := gs.FindCondition("Available") + isAvailable := s.Ready > 0 + if available.Status != "" { + isAvailable = available.Status == "True" + } + progressing := gs.FindCondition("Progressing") + + failure := gs.FindCondition("ReplicaFailure") + if failure.Status == "True" { + hs.Status = HealthStatusFailedCreate + hs.Health = HealthUnhealthy + hs.Message = failure.Message + hs.Ready = true + return hs + } + isStarting := age < startDeadline isProgressDeadlineExceeded := !isStarting && (progressing.Reason == "ProgressDeadlineExceeded") - hs.Ready = progressing.Status == "True" + hs.Ready = progressing.Status == "True" && progressing.Reason != "ReplicaSetUpdated" - hs.Health = lo.Ternary(s.Ready >= s.Desired, HealthHealthy, lo.Ternary(s.Ready > 0, HealthWarning, HealthUnhealthy)) + hs.Health = lo.Ternary(isAvailable, HealthHealthy, lo.Ternary(s.Ready > 0, HealthWarning, HealthUnhealthy)) if s.Desired == 0 && s.Replicas == 0 { hs.Ready = true @@ -75,26 +91,32 @@ func getReplicaHealth(s ReplicaStatus) *HealthStatus { hs.Status = "Pending" hs.Health = HealthUnknown } - } else if s.Ready == 0 && isStarting && !isProgressDeadlineExceeded { - hs.Health = HealthUnknown + } else if s.Ready == 0 && isStarting { hs.Status = HealthStatusStarting - } else if s.Ready == 0 && !isStarting { - hs.Health = HealthUnhealthy - hs.Status = HealthStatusCrashLoopBackoff + } else if s.Ready == 0 { + if isProgressDeadlineExceeded { + hs.Status = HealthStatusCrashLoopBackoff + } else if isAvailable { + hs.Status = HealthStatusUpdating + } + } + + if isProgressDeadlineExceeded { + hs.Status = HealthStatusRolloutFailed + hs.Health = hs.Health.Worst(HealthWarning) } else if s.Desired == 0 && s.Replicas > 0 { hs.Status = HealthStatusScalingDown - hs.Health = lo.Ternary(isProgressDeadlineExceeded, HealthWarning, HealthHealthy) } else if s.Ready == s.Desired && s.Desired == s.Updated && s.Replicas == s.Desired { hs.Status = HealthStatusRunning - } else if s.Desired != s.Updated { - hs.Status = HealthStatusUpdating + } else if !isStarting && s.Desired != s.Updated { + hs.Status = HealthStatusRollingOut } else if s.Replicas > s.Desired { hs.Status = HealthStatusScalingDown } else if s.Replicas < s.Desired { hs.Status = HealthStatusScalingUp } - if isStarting && hs.Health == HealthUnhealthy { + if isStarting && (hs.Health == HealthUnhealthy || hs.Health == HealthWarning) { hs.Health = HealthUnknown } diff --git a/pkg/health/health_test.go b/pkg/health/health_test.go index 795d564..2075c3c 100644 --- a/pkg/health/health_test.go +++ b/pkg/health/health_test.go @@ -329,19 +329,12 @@ func TestDeploymentHealth(t *testing.T) { assertAppHealthMsg( t, "./deployment-rollout-failed.yaml", - health.HealthStatusUpdating, - health.HealthWarning, - true, - "1/2 ready, 1 updating", - ) - assertAppHealthMsg( - t, - "./testdata/deployment-progressing.yaml", - health.HealthStatusUpdating, + health.HealthStatusRollingOut, health.HealthWarning, true, "1/2 ready, 1 updating", ) + assertAppHealthMsg( t, "./testdata/deployment-suspended.yaml", @@ -353,20 +346,12 @@ func TestDeploymentHealth(t *testing.T) { assertAppHealthMsg( t, "./testdata/deployment-degraded.yaml", - health.HealthStatusUpdating, + health.HealthStatusRollingOut, health.HealthWarning, true, "1/2 ready, 1 updating", ) - assertAppHealthMsg( - t, - "./testdata/deployment-starting.yaml", - health.HealthStatusStarting, - health.HealthUnknown, - true, - "0/2 ready, 1 updating", - ) assertAppHealthMsg( t, "./testdata/deployment-scaling-down.yaml", @@ -375,14 +360,7 @@ func TestDeploymentHealth(t *testing.T) { true, "1/1 ready, 1 updating, 1 terminating", ) - assertAppHealthMsg( - t, - "./testdata/deployment-failed.yaml", - "Failed Create", - health.HealthUnhealthy, - false, - "0/1 ready", - ) + } func TestStatefulSetHealth(t *testing.T) { diff --git a/pkg/health/testdata/deployment-failed.yaml b/pkg/health/testdata/Kubernetes/Deployment/deployment-failed.yaml similarity index 88% rename from pkg/health/testdata/deployment-failed.yaml rename to pkg/health/testdata/Kubernetes/Deployment/deployment-failed.yaml index 6136a69..45ef505 100644 --- a/pkg/health/testdata/deployment-failed.yaml +++ b/pkg/health/testdata/Kubernetes/Deployment/deployment-failed.yaml @@ -7,6 +7,11 @@ metadata: control-plane: karina-operator namespace: platform-system annotations: + expected-status: Failed Create + expected-ready: "true" + expected-health: "unhealthy" + expected-message: 'pods "karina-c7585bd87-" is forbidden: error looking up service + account platform-system/karina: serviceaccount "karina" not found' deployment.kubernetes.io/revision: "1" creationTimestamp: 2023-05-10T08:11:03Z spec: diff --git a/pkg/health/testdata/deployment-progressing.yaml b/pkg/health/testdata/Kubernetes/Deployment/deployment-progressing.yaml similarity index 75% rename from pkg/health/testdata/deployment-progressing.yaml rename to pkg/health/testdata/Kubernetes/Deployment/deployment-progressing.yaml index cf61d45..a6ba5cc 100644 --- a/pkg/health/testdata/deployment-progressing.yaml +++ b/pkg/health/testdata/Kubernetes/Deployment/deployment-progressing.yaml @@ -2,9 +2,11 @@ apiVersion: apps/v1 kind: Deployment metadata: annotations: - deployment.kubernetes.io/revision: "4" - kubectl.kubernetes.io/last-applied-configuration: | - {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"guestbook-default"},"name":"guestbook-ui","namespace":"default"},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"guestbook-ui"}},"template":{"metadata":{"labels":{"app":"guestbook-ui","app.kubernetes.io/instance":"guestbook-default"}},"spec":{"containers":[{"image":"gcr.io/heptio-images/ks-guestbook-demo:0.3","name":"guestbook-ui","ports":[{"containerPort":80}]}]}}}} + expected-status: Rolling Out + expected-health: healthy + expected-message: "1/2 ready, 1 updating" + expected-replicas: "2" + expted-ready: "false" creationTimestamp: 2018-07-18T04:40:44Z generation: 4 labels: diff --git a/pkg/health/testdata/deployment-rollout-failed-unhealthy.yaml b/pkg/health/testdata/Kubernetes/Deployment/deployment-rollout-failed-unhealthy.yaml similarity index 94% rename from pkg/health/testdata/deployment-rollout-failed-unhealthy.yaml rename to pkg/health/testdata/Kubernetes/Deployment/deployment-rollout-failed-unhealthy.yaml index 512ee39..cbdab15 100644 --- a/pkg/health/testdata/deployment-rollout-failed-unhealthy.yaml +++ b/pkg/health/testdata/Kubernetes/Deployment/deployment-rollout-failed-unhealthy.yaml @@ -2,6 +2,9 @@ apiVersion: apps/v1 kind: Deployment metadata: name: guestbook-ui + annotations: + expected-health: warning + expected-status: Rollout Failed spec: progressDeadlineSeconds: 600 replicas: 2 diff --git a/pkg/health/testdata/deployment-starting.yaml b/pkg/health/testdata/Kubernetes/Deployment/deployment-starting.yaml similarity index 95% rename from pkg/health/testdata/deployment-starting.yaml rename to pkg/health/testdata/Kubernetes/Deployment/deployment-starting.yaml index eec0a6d..a54a603 100644 --- a/pkg/health/testdata/deployment-starting.yaml +++ b/pkg/health/testdata/Kubernetes/Deployment/deployment-starting.yaml @@ -5,6 +5,9 @@ metadata: labels: app.kubernetes.io/instance: guestbook-default name: guestbook-ui + annotations: + expected-status: Starting + expected-health: unknown namespace: default spec: progressDeadlineSeconds: 600 diff --git a/pkg/health/testdata/Kubernetes/Deployment/restart.yaml b/pkg/health/testdata/Kubernetes/Deployment/restart.yaml new file mode 100644 index 0000000..0fa5a1e --- /dev/null +++ b/pkg/health/testdata/Kubernetes/Deployment/restart.yaml @@ -0,0 +1,124 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + uid: 8d347012-945e-4e95-9b75-66aad2c923be + name: podinfo2 + labels: + helm.sh/chart: podinfo-6.7.1 + app.kubernetes.io/name: podinfo2 + app.kubernetes.io/version: 6.7.1 + helm.toolkit.fluxcd.io/name: podinfo2 + app.kubernetes.io/managed-by: Helm + helm.toolkit.fluxcd.io/namespace: flux-092532 + namespace: flux-092532 + annotations: + expected-status: Updating + expected-ready: "false" + expected-health: "healthy" + + meta.helm.sh/release-name: podinfo2 + meta.helm.sh/release-namespace: flux-092532 + deployment.kubernetes.io/revision: "2" + creationTimestamp: 2024-11-03T19:53:13Z +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: podinfo2 + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 25% + maxUnavailable: 1 + template: + spec: + volumes: + - name: data + emptyDir: {} + dnsPolicy: ClusterFirst + containers: + - env: + - name: PODINFO_UI_COLOR + value: "#34577c" + name: podinfo + image: ghcr.io/stefanprodan/podinfo:6.7.1 + ports: + - name: http + protocol: TCP + containerPort: 9898 + - name: http-metrics + protocol: TCP + containerPort: 9797 + - name: grpc + protocol: TCP + containerPort: 9999 + command: + - ./podinfo + - --port=9898 + - --cert-path=/data/cert + - --port-metrics=9797 + - --grpc-port=9999 + - --grpc-service-name=podinfo + - --level=info + - --random-delay=false + - --random-error=false + resources: + requests: + cpu: 1m + memory: 16Mi + volumeMounts: + - name: data + mountPath: /data + livenessProbe: + exec: + command: + - podcli + - check + - http + - localhost:9898/healthz + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + successThreshold: 1 + initialDelaySeconds: 1 + readinessProbe: + exec: + command: + - podcli + - check + - http + - localhost:9898/readyz + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + successThreshold: 1 + initialDelaySeconds: 1 + imagePullPolicy: IfNotPresent + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + metadata: + labels: + app.kubernetes.io/name: podinfo2 + annotations: + prometheus.io/port: "9898" + prometheus.io/scrape: "true" + kubectl.kubernetes.io/restartedAt: 2024-12-01T20:55:04Z + revisionHistoryLimit: 10 + progressDeadlineSeconds: 600 +status: + replicas: 1 + conditions: + - type: Available + reason: MinimumReplicasAvailable + status: "True" + message: Deployment has minimum availability. + - type: Progressing + reason: ReplicaSetUpdated + status: "True" + message: ReplicaSet "podinfo2-8c499d45b" is progressing. + updatedReplicas: 1 + unavailableReplicas: 1 diff --git a/pkg/health/testdata/deployment-degraded.yaml b/pkg/health/testdata/deployment-degraded.yaml index 7f49967..8eaf556 100644 --- a/pkg/health/testdata/deployment-degraded.yaml +++ b/pkg/health/testdata/deployment-degraded.yaml @@ -2,9 +2,6 @@ apiVersion: apps/v1 kind: Deployment metadata: annotations: - deployment.kubernetes.io/revision: "4" - kubectl.kubernetes.io/last-applied-configuration: | - {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"guestbook-default"},"name":"guestbook-ui","namespace":"default"},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"guestbook-ui"}},"template":{"metadata":{"labels":{"app":"guestbook-ui","app.kubernetes.io/instance":"guestbook-default"}},"spec":{"containers":[{"image":"gcr.io/heptio-images/ks-guestbook-demo:0.3","name":"guestbook-ui","ports":[{"containerPort":80}]}]}}}} creationTimestamp: 2018-07-18T04:40:44Z generation: 4 labels: @@ -55,7 +52,7 @@ status: lastUpdateTime: 2018-07-18T04:48:48Z message: Deployment has minimum availability. reason: MinimumReplicasAvailable - status: "True" + status: "false" type: Available - lastTransitionTime: 2018-07-18T06:29:23Z lastUpdateTime: 2018-07-18T06:29:23Z From 4cf65b62b084d72a3f73339372c503a14e5ea5c3 Mon Sep 17 00:00:00 2001 From: Moshe Immermam Date: Thu, 5 Dec 2024 11:46:45 +0200 Subject: [PATCH 2/3] chore: deployment/replicaset fixes --- pkg/health/health_deployment.go | 11 ++- pkg/health/health_test.go | 79 ++----------------- .../Deployment}/deployment-degraded.yaml | 4 + .../deployment-rollout-failed.yaml | 5 ++ .../Deployment}/deployment-scaled-up.yaml | 7 +- .../Deployment}/deployment-scaling-down.yaml | 7 +- .../Deployment}/deployment-scaling-up.yaml | 16 ++-- .../Deployment}/deployment-suspended.yaml | 7 +- .../Deployment/healthy.yaml} | 0 .../ReplicaSet/healthy.yml} | 43 +++++----- .../ReplicaSet/starting.yaml} | 0 .../Kubernetes/ReplicaSet/unhealthy.yaml | 54 +++++++++++++ .../StatefulSet}/statefulset-ondelete.yaml | 5 +- .../StatefulSet}/statefulset-starting.yaml | 0 .../StatefulSet}/statefulset.yaml | 6 +- 15 files changed, 121 insertions(+), 123 deletions(-) rename pkg/health/testdata/{ => Kubernetes/Deployment}/deployment-degraded.yaml (92%) rename pkg/health/testdata/{ => Kubernetes/Deployment}/deployment-rollout-failed.yaml (90%) rename pkg/health/testdata/{ => Kubernetes/Deployment}/deployment-scaled-up.yaml (96%) rename pkg/health/testdata/{ => Kubernetes/Deployment}/deployment-scaling-down.yaml (73%) rename pkg/health/testdata/{ => Kubernetes/Deployment}/deployment-scaling-up.yaml (93%) rename pkg/health/testdata/{ => Kubernetes/Deployment}/deployment-suspended.yaml (75%) rename pkg/health/testdata/{nginx.yaml => Kubernetes/Deployment/healthy.yaml} (100%) rename pkg/health/testdata/{replicaset-ittools.yml => Kubernetes/ReplicaSet/healthy.yml} (64%) rename pkg/health/testdata/{replicaset-unhealthy-pods.yaml => Kubernetes/ReplicaSet/starting.yaml} (100%) create mode 100644 pkg/health/testdata/Kubernetes/ReplicaSet/unhealthy.yaml rename pkg/health/testdata/{ => Kubernetes/StatefulSet}/statefulset-ondelete.yaml (63%) rename pkg/health/testdata/{ => Kubernetes/StatefulSet}/statefulset-starting.yaml (100%) rename pkg/health/testdata/{ => Kubernetes/StatefulSet}/statefulset.yaml (63%) diff --git a/pkg/health/health_deployment.go b/pkg/health/health_deployment.go index b007104..7e12658 100644 --- a/pkg/health/health_deployment.go +++ b/pkg/health/health_deployment.go @@ -53,7 +53,6 @@ func getReplicaHealth(s ReplicaStatus) *HealthStatus { age := time.Since(s.Object.GetCreationTimestamp().Time).Truncate(time.Minute).Abs() gs := GetGenericStatus(s.Object) - available := gs.FindCondition("Available") isAvailable := s.Ready > 0 if available.Status != "" { @@ -94,11 +93,7 @@ func getReplicaHealth(s ReplicaStatus) *HealthStatus { } else if s.Ready == 0 && isStarting { hs.Status = HealthStatusStarting } else if s.Ready == 0 { - if isProgressDeadlineExceeded { - hs.Status = HealthStatusCrashLoopBackoff - } else if isAvailable { - hs.Status = HealthStatusUpdating - } + hs.Status = lo.Ternary(isAvailable, HealthStatusUpdating, HealthStatusCrashLoopBackoff) } if isProgressDeadlineExceeded { @@ -116,6 +111,10 @@ func getReplicaHealth(s ReplicaStatus) *HealthStatus { hs.Status = HealthStatusScalingUp } + if s.Replicas != s.Desired || s.Replicas != s.Updated { + hs.Ready = false + } + if isStarting && (hs.Health == HealthUnhealthy || hs.Health == HealthWarning) { hs.Health = HealthUnknown } diff --git a/pkg/health/health_test.go b/pkg/health/health_test.go index 2075c3c..ade711a 100644 --- a/pkg/health/health_test.go +++ b/pkg/health/health_test.go @@ -315,66 +315,10 @@ func TestExternalSecrets(t *testing.T) { assertAppHealthMsg(t, b+"healthy.yaml", "SecretSynced", health.HealthHealthy, true) } -func TestDeploymentHealth(t *testing.T) { - assertAppHealthMsg(t, "./testdata/nginx.yaml", health.HealthStatusRunning, health.HealthHealthy, true, "1/1 ready") - assertAppHealthMsg( - t, - "./deployment-scaled-up.yaml", - health.HealthStatusRunning, - health.HealthHealthy, - true, - "3/3 ready", - ) - - assertAppHealthMsg( - t, - "./deployment-rollout-failed.yaml", - health.HealthStatusRollingOut, - health.HealthWarning, - true, - "1/2 ready, 1 updating", - ) - - assertAppHealthMsg( - t, - "./testdata/deployment-suspended.yaml", - health.HealthStatusSuspended, - health.HealthHealthy, - false, - "1/1 ready, 1 updating, 1 terminating", - ) - assertAppHealthMsg( - t, - "./testdata/deployment-degraded.yaml", - health.HealthStatusRollingOut, - health.HealthWarning, - true, - "1/2 ready, 1 updating", - ) - - assertAppHealthMsg( - t, - "./testdata/deployment-scaling-down.yaml", - health.HealthStatusScalingDown, - health.HealthHealthy, - true, - "1/1 ready, 1 updating, 1 terminating", - ) - -} - func TestStatefulSetHealth(t *testing.T) { + starting := "./testdata/Kubernetes/StatefulSet/statefulset-starting.yaml" assertAppHealthMsg( - t, - "./testdata/statefulset.yaml", - health.HealthStatusRunning, - health.HealthHealthy, - true, - "1/1 ready", - ) - assertAppHealthMsg( - t, - "./testdata/statefulset-starting.yaml", + t, starting, health.HealthStatusStarting, health.HealthUnknown, true, @@ -384,7 +328,8 @@ func TestStatefulSetHealth(t *testing.T) { ) assertAppHealthMsg( t, - "./testdata/statefulset-starting.yaml", + starting, + health.HealthStatusStarting, health.HealthUnknown, true, @@ -394,7 +339,7 @@ func TestStatefulSetHealth(t *testing.T) { ) assertAppHealthMsg( t, - "./testdata/statefulset-starting.yaml", + starting, health.HealthStatusCrashLoopBackoff, health.HealthUnhealthy, true, @@ -404,7 +349,7 @@ func TestStatefulSetHealth(t *testing.T) { ) assertAppHealthMsg( t, - "./testdata/statefulset-starting.yaml", + starting, health.HealthStatusCrashLoopBackoff, health.HealthUnhealthy, true, @@ -417,7 +362,7 @@ func TestStatefulSetHealth(t *testing.T) { func TestStatefulSetOnDeleteHealth(t *testing.T) { assertAppHealthMsg( t, - "./testdata/statefulset-ondelete.yaml", + "./testdata/Kubernetes/StatefulSet/statefulset-ondelete.yaml", "TerminatingStalled", health.HealthWarning, false, @@ -514,16 +459,6 @@ func TestHPA(t *testing.T) { ) } -func TestReplicaSet(t *testing.T) { - assertAppHealthWithOverwrite(t, "./testdata/replicaset-ittools.yml", map[string]string{ - "2024-08-03T06:06:18Z": time.Now().Add(-time.Minute * 2).UTC().Format("2006-01-02T15:04:05Z"), - }, health.HealthStatusRunning, health.HealthHealthy, false) - - assertAppHealthWithOverwrite(t, "./testdata/replicaset-unhealthy-pods.yaml", map[string]string{ - "2024-10-21T11:20:19Z": time.Now().Add(-time.Minute * 2).UTC().Format("2006-01-02T15:04:05Z"), - }, health.HealthStatusStarting, health.HealthUnknown, false) -} - // func TestAPIService(t *testing.T) { // assertAppHealthMsg(t, "./testdata/apiservice-v1-true.yaml", HealthStatusHealthy, health.HealthHealthy, true) // assertAppHealthMsg(t, "./testdata/apiservice-v1-false.yaml", HealthStatusProgressing, health.HealthHealthy, true) diff --git a/pkg/health/testdata/deployment-degraded.yaml b/pkg/health/testdata/Kubernetes/Deployment/deployment-degraded.yaml similarity index 92% rename from pkg/health/testdata/deployment-degraded.yaml rename to pkg/health/testdata/Kubernetes/Deployment/deployment-degraded.yaml index 8eaf556..21a9222 100644 --- a/pkg/health/testdata/deployment-degraded.yaml +++ b/pkg/health/testdata/Kubernetes/Deployment/deployment-degraded.yaml @@ -2,6 +2,10 @@ apiVersion: apps/v1 kind: Deployment metadata: annotations: + expected-ready: "false" + expected-status: "Rolling Out" + expected-health: "warning" + expected-message: "1/2 ready, 1 updating" creationTimestamp: 2018-07-18T04:40:44Z generation: 4 labels: diff --git a/pkg/health/testdata/deployment-rollout-failed.yaml b/pkg/health/testdata/Kubernetes/Deployment/deployment-rollout-failed.yaml similarity index 90% rename from pkg/health/testdata/deployment-rollout-failed.yaml rename to pkg/health/testdata/Kubernetes/Deployment/deployment-rollout-failed.yaml index 86f87e1..5bf2914 100644 --- a/pkg/health/testdata/deployment-rollout-failed.yaml +++ b/pkg/health/testdata/Kubernetes/Deployment/deployment-rollout-failed.yaml @@ -2,6 +2,11 @@ apiVersion: apps/v1 kind: Deployment metadata: name: guestbook-ui + annotations: + expected-ready: "false" + expected-status: "Rolling Out" + expected-health: "healthy" + expected-message: "1/2 ready, 1 updating" spec: progressDeadlineSeconds: 600 replicas: 2 diff --git a/pkg/health/testdata/deployment-scaled-up.yaml b/pkg/health/testdata/Kubernetes/Deployment/deployment-scaled-up.yaml similarity index 96% rename from pkg/health/testdata/deployment-scaled-up.yaml rename to pkg/health/testdata/Kubernetes/Deployment/deployment-scaled-up.yaml index 5e154b4..eaf8623 100644 --- a/pkg/health/testdata/deployment-scaled-up.yaml +++ b/pkg/health/testdata/Kubernetes/Deployment/deployment-scaled-up.yaml @@ -10,9 +10,10 @@ metadata: app.kubernetes.io/managed-by: Helm namespace: podinfo annotations: - meta.helm.sh/release-name: podinfo - meta.helm.sh/release-namespace: podinfo - deployment.kubernetes.io/revision: "1" + expected-ready: "true" + expected-status: "Running" + expected-health: "healthy" + expected-message: "3/3 ready" creationTimestamp: 2023-12-19T15:50:39Z spec: replicas: 3 diff --git a/pkg/health/testdata/deployment-scaling-down.yaml b/pkg/health/testdata/Kubernetes/Deployment/deployment-scaling-down.yaml similarity index 73% rename from pkg/health/testdata/deployment-scaling-down.yaml rename to pkg/health/testdata/Kubernetes/Deployment/deployment-scaling-down.yaml index ce7359f..0b073e3 100644 --- a/pkg/health/testdata/deployment-scaling-down.yaml +++ b/pkg/health/testdata/Kubernetes/Deployment/deployment-scaling-down.yaml @@ -2,9 +2,10 @@ apiVersion: apps/v1 kind: Deployment metadata: annotations: - deployment.kubernetes.io/revision: "4" - kubectl.kubernetes.io/last-applied-configuration: | - {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"guestbook-default"},"name":"guestbook-ui","namespace":"default"},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"guestbook-ui"}},"template":{"metadata":{"labels":{"app":"guestbook-ui","app.kubernetes.io/instance":"guestbook-default"}},"spec":{"containers":[{"image":"gcr.io/heptio-images/ks-guestbook-demo:0.3","name":"guestbook-ui","ports":[{"containerPort":80}]}]}}}} + expected-ready: "false" + expected-status: "Scaling Down" + expected-health: "healthy" + expected-message: "1/1 ready, 1 updating, 1 terminating" creationTimestamp: 2018-07-18T04:40:44Z generation: 4 labels: diff --git a/pkg/health/testdata/deployment-scaling-up.yaml b/pkg/health/testdata/Kubernetes/Deployment/deployment-scaling-up.yaml similarity index 93% rename from pkg/health/testdata/deployment-scaling-up.yaml rename to pkg/health/testdata/Kubernetes/Deployment/deployment-scaling-up.yaml index 9d18eca..9d1b46d 100644 --- a/pkg/health/testdata/deployment-scaling-up.yaml +++ b/pkg/health/testdata/Kubernetes/Deployment/deployment-scaling-up.yaml @@ -1,9 +1,3 @@ -Config -Changes1 -Insights0 -Relationships4 -Playbooks1 -Checks0 apiVersion: apps/v1 kind: Deployment metadata: @@ -16,9 +10,11 @@ metadata: app.kubernetes.io/managed-by: Helm namespace: podinfo annotations: - meta.helm.sh/release-name: podinfo - meta.helm.sh/release-namespace: podinfo - deployment.kubernetes.io/revision: "1" + annotations: + expected-ready: "false" + expected-status: "Rolling Out" + expected-health: "warning" + expected-message: "1/3 ready, 1 updating" creationTimestamp: 2023-12-19T15:50:39Z spec: replicas: 3 @@ -120,6 +116,6 @@ status: status: "True" message: ReplicaSet "podinfo-97c6d4b94" has successfully progressed. readyReplicas: 1 - updatedReplicas: 3 + updatedReplicas: 2 availableReplicas: 1 unavailableReplicas: 2 diff --git a/pkg/health/testdata/deployment-suspended.yaml b/pkg/health/testdata/Kubernetes/Deployment/deployment-suspended.yaml similarity index 75% rename from pkg/health/testdata/deployment-suspended.yaml rename to pkg/health/testdata/Kubernetes/Deployment/deployment-suspended.yaml index e8c5a40..fe37baa 100644 --- a/pkg/health/testdata/deployment-suspended.yaml +++ b/pkg/health/testdata/Kubernetes/Deployment/deployment-suspended.yaml @@ -2,9 +2,10 @@ apiVersion: apps/v1 kind: Deployment metadata: annotations: - deployment.kubernetes.io/revision: "4" - kubectl.kubernetes.io/last-applied-configuration: | - {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"guestbook-default"},"name":"guestbook-ui","namespace":"default"},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"guestbook-ui"}},"template":{"metadata":{"labels":{"app":"guestbook-ui","app.kubernetes.io/instance":"guestbook-default"}},"spec":{"containers":[{"image":"gcr.io/heptio-images/ks-guestbook-demo:0.3","name":"guestbook-ui","ports":[{"containerPort":80}]}]}}}} + expected-ready: "false" + expected-status: "Suspended" + expected-health: "healthy" + expected-message: "1/1 ready, 1 updating, 1 terminating" creationTimestamp: 2018-07-18T04:40:44Z generation: 4 labels: diff --git a/pkg/health/testdata/nginx.yaml b/pkg/health/testdata/Kubernetes/Deployment/healthy.yaml similarity index 100% rename from pkg/health/testdata/nginx.yaml rename to pkg/health/testdata/Kubernetes/Deployment/healthy.yaml diff --git a/pkg/health/testdata/replicaset-ittools.yml b/pkg/health/testdata/Kubernetes/ReplicaSet/healthy.yml similarity index 64% rename from pkg/health/testdata/replicaset-ittools.yml rename to pkg/health/testdata/Kubernetes/ReplicaSet/healthy.yml index a1db08f..bb5dda8 100644 --- a/pkg/health/testdata/replicaset-ittools.yml +++ b/pkg/health/testdata/Kubernetes/ReplicaSet/healthy.yml @@ -2,11 +2,10 @@ apiVersion: apps/v1 kind: ReplicaSet metadata: annotations: - deployment.kubernetes.io/desired-replicas: "1" - deployment.kubernetes.io/max-replicas: "1" - deployment.kubernetes.io/revision: "2" - meta.helm.sh/release-name: ittools - meta.helm.sh/release-namespace: default + expected-ready: "true" + expected-status: "Running" + expected-health: healthy" + expected-message: "1/1 ready" creationTimestamp: "2024-08-03T06:06:18Z" generation: 52 labels: @@ -17,12 +16,12 @@ metadata: name: ittools-5fbf458f49 namespace: default ownerReferences: - - apiVersion: apps/v1 - blockOwnerDeletion: true - controller: true - kind: Deployment - name: ittools - uid: d2beccff-8da9-42e8-8459-e7ff938b2ffd + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: Deployment + name: ittools + uid: d2beccff-8da9-42e8-8459-e7ff938b2ffd resourceVersion: "96413911" uid: c044b250-2445-4813-b00f-22b696c5fcf2 spec: @@ -43,17 +42,17 @@ spec: spec: automountServiceAccountToken: true containers: - - image: corentinth/it-tools:latest - imagePullPolicy: Always - name: it-tools - resources: - limits: - memory: 50Mi - requests: - cpu: 25m - memory: 10Mi - terminationMessagePath: /dev/termination-log - terminationMessagePolicy: File + - image: corentinth/it-tools:latest + imagePullPolicy: Always + name: it-tools + resources: + limits: + memory: 50Mi + requests: + cpu: 25m + memory: 10Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File dnsPolicy: ClusterFirst enableServiceLinks: false restartPolicy: Always diff --git a/pkg/health/testdata/replicaset-unhealthy-pods.yaml b/pkg/health/testdata/Kubernetes/ReplicaSet/starting.yaml similarity index 100% rename from pkg/health/testdata/replicaset-unhealthy-pods.yaml rename to pkg/health/testdata/Kubernetes/ReplicaSet/starting.yaml diff --git a/pkg/health/testdata/Kubernetes/ReplicaSet/unhealthy.yaml b/pkg/health/testdata/Kubernetes/ReplicaSet/unhealthy.yaml new file mode 100644 index 0000000..e6fe2ab --- /dev/null +++ b/pkg/health/testdata/Kubernetes/ReplicaSet/unhealthy.yaml @@ -0,0 +1,54 @@ +apiVersion: apps/v1 +kind: ReplicaSet +metadata: + uid: f6579017-448f-425a-9645-ea3c93700948 + name: failing-deployment-866585899d + labels: + app: failing-app + pod-template-hash: 866585899d + namespace: default + annotations: + expected-ready: "false" + expected-status: "CrashLoopBackOff" + expected-health: "unhealthy" + expected-message: "0/1 ready" + ownerReferences: + - uid: 1ab20b2b-e2c8-4e85-b7b6-5709ba594c0d + kind: Deployment + name: failing-deployment + apiVersion: apps/v1 + controller: true + blockOwnerDeletion: true + creationTimestamp: "@now-1d" +spec: + replicas: 1 + selector: + matchLabels: + app: failing-app + pod-template-hash: 866585899d + template: + spec: + dnsPolicy: ClusterFirst + containers: + - args: + - -c + - sleep 5 && exit 1 + name: failing-container + image: busybox + command: + - /bin/sh + resources: {} + imagePullPolicy: Always + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + metadata: + labels: + app: failing-app + pod-template-hash: 866585899d +status: + replicas: 1 + fullyLabeledReplicas: 1 diff --git a/pkg/health/testdata/statefulset-ondelete.yaml b/pkg/health/testdata/Kubernetes/StatefulSet/statefulset-ondelete.yaml similarity index 63% rename from pkg/health/testdata/statefulset-ondelete.yaml rename to pkg/health/testdata/Kubernetes/StatefulSet/statefulset-ondelete.yaml index 9f2adfa..ac743ca 100644 --- a/pkg/health/testdata/statefulset-ondelete.yaml +++ b/pkg/health/testdata/Kubernetes/StatefulSet/statefulset-ondelete.yaml @@ -2,8 +2,9 @@ apiVersion: apps/v1 kind: StatefulSet metadata: annotations: - kubectl.kubernetes.io/last-applied-configuration: | - {"apiVersion":"apps/v1beta2","kind":"StatefulSet","metadata":{"annotations":{},"labels":{"app":"redis","app.kubernetes.io/instance":"redis","chart":"redis-3.6.5","heritage":"Tiller","release":"redis"},"name":"redis-master","namespace":"default"},"spec":{"selector":{"matchLabels":{"app":"redis","release":"redis","role":"master"}},"serviceName":"redis-master","template":{"metadata":{"labels":{"app":"redis","app.kubernetes.io/instance":"redis","release":"redis","role":"master"}},"spec":{"containers":[{"env":[{"name":"REDIS_REPLICATION_MODE","value":"master"},{"name":"REDIS_PASSWORD","valueFrom":{"secretKeyRef":{"key":"redis-password","name":"redis"}}},{"name":"REDIS_DISABLE_COMMANDS","value":"FLUSHDB,FLUSHALL"}],"image":"docker.io/bitnami/redis:4.0.10-debian-9","imagePullPolicy":"Always","livenessProbe":{"exec":{"command":["redis-cli","ping"]},"failureThreshold":5,"initialDelaySeconds":30,"periodSeconds":10,"successThreshold":1,"timeoutSeconds":5},"name":"redis","ports":[{"containerPort":6379,"name":"redis"}],"readinessProbe":{"exec":{"command":["redis-cli","ping"]},"failureThreshold":5,"initialDelaySeconds":5,"periodSeconds":10,"successThreshold":1,"timeoutSeconds":1},"resources":{},"volumeMounts":[{"mountPath":"/bitnami/redis/data","name":"redis-data"}]}],"securityContext":{"fsGroup":1001,"runAsUser":1001},"serviceAccountName":"default"}},"updateStrategy":{"type":"OnDelete"},"volumeClaimTemplates":[{"metadata":{"labels":{"app":"redis","chart":"redis-3.6.5","component":"master","heritage":"Tiller","release":"redis"},"name":"redis-data"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"8Gi"}}}}]}} + expected-ready: "false" + expected-status: "Terminating" + expected-message: "1/1 ready, 1 updating" creationTimestamp: 2018-07-20T08:23:04Z generation: 1 labels: diff --git a/pkg/health/testdata/statefulset-starting.yaml b/pkg/health/testdata/Kubernetes/StatefulSet/statefulset-starting.yaml similarity index 100% rename from pkg/health/testdata/statefulset-starting.yaml rename to pkg/health/testdata/Kubernetes/StatefulSet/statefulset-starting.yaml diff --git a/pkg/health/testdata/statefulset.yaml b/pkg/health/testdata/Kubernetes/StatefulSet/statefulset.yaml similarity index 63% rename from pkg/health/testdata/statefulset.yaml rename to pkg/health/testdata/Kubernetes/StatefulSet/statefulset.yaml index 1ecd85e..a32b6bc 100644 --- a/pkg/health/testdata/statefulset.yaml +++ b/pkg/health/testdata/Kubernetes/StatefulSet/statefulset.yaml @@ -2,8 +2,10 @@ apiVersion: apps/v1 kind: StatefulSet metadata: annotations: - kubectl.kubernetes.io/last-applied-configuration: | - {"apiVersion":"apps/v1beta2","kind":"StatefulSet","metadata":{"annotations":{},"labels":{"app":"redis","app.kubernetes.io/instance":"redis","chart":"redis-3.6.5","heritage":"Tiller","release":"redis"},"name":"redis-master","namespace":"default"},"spec":{"selector":{"matchLabels":{"app":"redis","release":"redis","role":"master"}},"serviceName":"redis-master","template":{"metadata":{"labels":{"app":"redis","app.kubernetes.io/instance":"redis","release":"redis","role":"master"}},"spec":{"containers":[{"env":[{"name":"REDIS_REPLICATION_MODE","value":"master"},{"name":"REDIS_PASSWORD","valueFrom":{"secretKeyRef":{"key":"redis-password","name":"redis"}}},{"name":"REDIS_DISABLE_COMMANDS","value":"FLUSHDB,FLUSHALL"}],"image":"docker.io/bitnami/redis:4.0.10-debian-9","imagePullPolicy":"Always","livenessProbe":{"exec":{"command":["redis-cli","ping"]},"failureThreshold":5,"initialDelaySeconds":30,"periodSeconds":10,"successThreshold":1,"timeoutSeconds":5},"name":"redis","ports":[{"containerPort":6379,"name":"redis"}],"readinessProbe":{"exec":{"command":["redis-cli","ping"]},"failureThreshold":5,"initialDelaySeconds":5,"periodSeconds":10,"successThreshold":1,"timeoutSeconds":1},"resources":{},"volumeMounts":[{"mountPath":"/bitnami/redis/data","name":"redis-data"}]}],"securityContext":{"fsGroup":1001,"runAsUser":1001},"serviceAccountName":"default"}},"updateStrategy":{"type":"OnDelete"},"volumeClaimTemplates":[{"metadata":{"labels":{"app":"redis","chart":"redis-3.6.5","component":"master","heritage":"Tiller","release":"redis"},"name":"redis-data"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"8Gi"}}}}]}} + expected-ready: "true" + expected-status: "Running" + expected-health: "healthy" + expected-message: "1/1 ready" creationTimestamp: 2018-07-20T08:23:04Z generation: 1 labels: From 0b956b2cdc5873ab11b70832e43b92db00c09363 Mon Sep 17 00:00:00 2001 From: Moshe Immermam Date: Thu, 5 Dec 2024 12:26:21 +0200 Subject: [PATCH 3/3] chore: remove unused func --- pkg/health/health_test.go | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/pkg/health/health_test.go b/pkg/health/health_test.go index ade711a..dd96002 100644 --- a/pkg/health/health_test.go +++ b/pkg/health/health_test.go @@ -143,21 +143,6 @@ func assertAppHealthWithOverwriteMsg( assert.Equal(t, expectedMsg, health.Message) } -func assertAppHealthWithOverwrite( - t *testing.T, - yamlPath string, - overwrites map[string]string, - expectedStatus health.HealthStatusCode, - expectedHealth health.Health, - expectedReady bool, -) { - health, _ := getHealthStatus(yamlPath, t, overwrites) - assert.NotNil(t, health) - assert.Equal(t, expectedHealth, health.Health) - assert.Equal(t, expectedReady, health.Ready) - assert.Equal(t, expectedStatus, health.Status) -} - func getHealthStatus( yamlPath string, t *testing.T,