diff --git a/resource_customizations/core.spinkube.dev/SpinApp/health.lua b/resource_customizations/core.spinkube.dev/SpinApp/health.lua new file mode 100644 index 0000000000..91289fe6f4 --- /dev/null +++ b/resource_customizations/core.spinkube.dev/SpinApp/health.lua @@ -0,0 +1,71 @@ +hs = {} + +-- Check if status exists +if not obj.status then + hs.status = "Progressing" + hs.message = "Waiting for status to be available" + return hs +end + +-- Initialize variables for conditions +local available = false +local progressing = false +local availableMessage = "" +local progressingMessage = "" + +-- Check conditions - prioritize failure conditions first +if obj.status.conditions then + for _, condition in ipairs(obj.status.conditions) do + if condition.type == "Progressing" then + -- Check for timeout or failure in progressing condition first + if condition.status == "False" and (condition.reason == "ProgressDeadlineExceeded" or string.find(string.lower(condition.message or ""), "timeout") or string.find(string.lower(condition.message or ""), "failed")) then + hs.status = "Degraded" + hs.message = condition.message or "Application deployment has failed" + return hs + end + -- If progressing is true, mark it (any progressing=true condition wins) + if condition.status == "True" then + progressing = true + progressingMessage = condition.message or "Application progress status" + end + elseif condition.type == "Available" then + -- For available, we want all to be true, so any false condition wins + if condition.status == "True" then + available = true + availableMessage = condition.message or "Application availability status" + else + available = false + availableMessage = condition.message or "Application is not available" + end + end + end +end + +-- Check ready replicas if specified +local readyReplicas = obj.status.readyReplicas or 0 +local desiredReplicas = obj.spec.replicas or 1 + +-- Determine status based on conditions +if not available then + hs.status = "Degraded" + hs.message = availableMessage or "Application is not available" + return hs +end + +if readyReplicas < desiredReplicas then + hs.status = "Progressing" + hs.message = string.format("Waiting for replicas to be ready (%d/%d)", readyReplicas, desiredReplicas) + return hs +end + +if progressing then + hs.status = "Progressing" + hs.message = progressingMessage or "Application is still progressing" + return hs +end + +-- All checks passed +hs.status = "Healthy" +hs.message = string.format("Application is healthy with %d/%d replicas ready", readyReplicas, desiredReplicas) + +return hs \ No newline at end of file diff --git a/resource_customizations/core.spinkube.dev/SpinApp/health_test.yaml b/resource_customizations/core.spinkube.dev/SpinApp/health_test.yaml new file mode 100644 index 0000000000..eaa6964f35 --- /dev/null +++ b/resource_customizations/core.spinkube.dev/SpinApp/health_test.yaml @@ -0,0 +1,17 @@ +tests: +- healthStatus: + status: Healthy + message: "Application is healthy with 2/2 replicas ready" + inputPath: testdata/healthy.yaml +- healthStatus: + status: Degraded + message: "ReplicaSet \"simple-spinapp-5b8d8bc656\" has timed out progressing." + inputPath: testdata/degraded.yaml +- healthStatus: + status: Progressing + message: "ReplicaSet \"simple-spinapp-c54f5bdb4\" has successfully progressed." + inputPath: testdata/progressing.yaml +- healthStatus: + status: Progressing + message: "Waiting for status to be available" + inputPath: testdata/no-status.yaml \ No newline at end of file diff --git a/resource_customizations/core.spinkube.dev/SpinApp/testdata/degraded.yaml b/resource_customizations/core.spinkube.dev/SpinApp/testdata/degraded.yaml new file mode 100644 index 0000000000..8e25b8cb22 --- /dev/null +++ b/resource_customizations/core.spinkube.dev/SpinApp/testdata/degraded.yaml @@ -0,0 +1,36 @@ +apiVersion: core.spinkube.dev/v1alpha1 +kind: SpinApp +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"core.spinkube.dev/v1alpha1","kind":"SpinApp","metadata":{"annotations":{},"labels":{"argocd.argoproj.io/instance":"spin-apps"},"name":"simple-spinapp","namespace":"spin-apps"},"spec":{"executor":"containerd-shim-spin","image":"ghcr.io/spinkube/containerd-shim-spin/examples/spin-rust-hello:v0.13.19","replicas":2}} + creationTimestamp: '2025-02-17T20:30:09Z' + generation: 8 + labels: + argocd.argoproj.io/instance: spin-apps + name: simple-spinapp + namespace: spin-apps + resourceVersion: '34094' + uid: ef4b3af3-ae67-4c49-8cbb-0cc4fb7b83ba +spec: + checks: {} + enableAutoscaling: false + executor: containerd-shim-spin + image: ghcr.io/spinkube/containerd-shim-spin/examples/spin-rust-hello:v0.13.19 + replicas: 2 + resources: {} + runtimeConfig: {} +status: + activeScheduler: containerd-shim-spin + conditions: + - lastTransitionTime: '2025-02-17T20:55:37Z' + message: Deployment has minimum availability. + reason: MinimumReplicasAvailable + status: 'True' + type: Available + - lastTransitionTime: '2025-02-17T21:05:38Z' + message: ReplicaSet "simple-spinapp-5b8d8bc656" has timed out progressing. + reason: ProgressDeadlineExceeded + status: 'False' + type: Progressing + readyReplicas: 2 diff --git a/resource_customizations/core.spinkube.dev/SpinApp/testdata/healthy.yaml b/resource_customizations/core.spinkube.dev/SpinApp/testdata/healthy.yaml new file mode 100644 index 0000000000..96e3aa19f6 --- /dev/null +++ b/resource_customizations/core.spinkube.dev/SpinApp/testdata/healthy.yaml @@ -0,0 +1,36 @@ +apiVersion: core.spinkube.dev/v1alpha1 +kind: SpinApp +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"core.spinkube.dev/v1alpha1","kind":"SpinApp","metadata":{"annotations":{},"labels":{"argocd.argoproj.io/instance":"spin-apps"},"name":"simple-spinapp","namespace":"spin-apps"},"spec":{"executor":"containerd-shim-spin","image":"ghcr.io/spinkube/containerd-shim-spin/examples/spin-rust-hello:v0.13.0","replicas":2}} + creationTimestamp: '2025-02-17T20:30:09Z' + generation: 9 + labels: + argocd.argoproj.io/instance: spin-apps + name: simple-spinapp + namespace: spin-apps + resourceVersion: '38985' + uid: ef4b3af3-ae67-4c49-8cbb-0cc4fb7b83ba +spec: + checks: {} + enableAutoscaling: false + executor: containerd-shim-spin + image: ghcr.io/spinkube/containerd-shim-spin/examples/spin-rust-hello:v0.13.0 + replicas: 2 + resources: {} + runtimeConfig: {} +status: + activeScheduler: containerd-shim-spin + conditions: + - lastTransitionTime: '2025-02-17T20:55:37Z' + message: Deployment has minimum availability. + reason: MinimumReplicasAvailable + status: 'True' + type: Available + - lastTransitionTime: '2025-02-17T21:37:41Z' + message: ReplicaSet "simple-spinapp-c54f5bdb4" has successfully progressed. + reason: NewReplicaSetAvailable + status: 'False' + type: Progressing + readyReplicas: 2 diff --git a/resource_customizations/core.spinkube.dev/SpinApp/testdata/no-status.yaml b/resource_customizations/core.spinkube.dev/SpinApp/testdata/no-status.yaml new file mode 100644 index 0000000000..c2745b79c7 --- /dev/null +++ b/resource_customizations/core.spinkube.dev/SpinApp/testdata/no-status.yaml @@ -0,0 +1,9 @@ +apiVersion: core.spinkube.dev/v1alpha1 +kind: SpinApp +metadata: + name: simple-spinapp + namespace: spin-apps +spec: + executor: containerd-shim-spin + image: ghcr.io/spinkube/containerd-shim-spin/examples/spin-rust-hello:v0.13.0 + replicas: 2 \ No newline at end of file diff --git a/resource_customizations/core.spinkube.dev/SpinApp/testdata/progressing.yaml b/resource_customizations/core.spinkube.dev/SpinApp/testdata/progressing.yaml new file mode 100644 index 0000000000..6fe6d15fcb --- /dev/null +++ b/resource_customizations/core.spinkube.dev/SpinApp/testdata/progressing.yaml @@ -0,0 +1,36 @@ +apiVersion: core.spinkube.dev/v1alpha1 +kind: SpinApp +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"core.spinkube.dev/v1alpha1","kind":"SpinApp","metadata":{"annotations":{},"labels":{"argocd.argoproj.io/instance":"spin-apps"},"name":"simple-spinapp","namespace":"spin-apps"},"spec":{"executor":"containerd-shim-spin","image":"ghcr.io/spinkube/containerd-shim-spin/examples/spin-rust-hello:v0.13.0","replicas":2}} + creationTimestamp: '2025-02-17T20:30:09Z' + generation: 9 + labels: + argocd.argoproj.io/instance: spin-apps + name: simple-spinapp + namespace: spin-apps + resourceVersion: '38985' + uid: ef4b3af3-ae67-4c49-8cbb-0cc4fb7b83ba +spec: + checks: {} + enableAutoscaling: false + executor: containerd-shim-spin + image: ghcr.io/spinkube/containerd-shim-spin/examples/spin-rust-hello:v0.13.0 + replicas: 2 + resources: {} + runtimeConfig: {} +status: + activeScheduler: containerd-shim-spin + conditions: + - lastTransitionTime: '2025-02-17T20:55:37Z' + message: Deployment has minimum availability. + reason: MinimumReplicasAvailable + status: 'True' + type: Available + - lastTransitionTime: '2025-02-17T21:37:41Z' + message: ReplicaSet "simple-spinapp-c54f5bdb4" has successfully progressed. + reason: NewReplicaSetAvailable + status: 'True' + type: Progressing + readyReplicas: 2