diff --git a/resource_customizations/gateway.networking.k8s.io/HTTPRoute/health.lua b/resource_customizations/gateway.networking.k8s.io/HTTPRoute/health.lua index ce73b35f4e..384c8c8a2e 100644 --- a/resource_customizations/gateway.networking.k8s.io/HTTPRoute/health.lua +++ b/resource_customizations/gateway.networking.k8s.io/HTTPRoute/health.lua @@ -9,10 +9,39 @@ function checkConditions(conditions, conditionType) return true end +-- isParentGenerationObserved checks if a parent's conditions match the current resource generation +-- For HTTPRoute, observedGeneration is stored in each condition within a parent +function isParentGenerationObserved(obj, parent) + if obj.metadata.generation == nil then + -- If no generation is set, accept all conditions + return true + end + + if parent.conditions == nil or #parent.conditions == 0 then + return false + end + + -- Check if all conditions have observedGeneration matching current generation + for _, condition in ipairs(parent.conditions) do + if condition.observedGeneration ~= nil then + if condition.observedGeneration ~= obj.metadata.generation then + return false + end + end + end + + return true +end + if obj.status ~= nil then if obj.status.parents ~= nil then for _, parent in ipairs(obj.status.parents) do if parent.conditions ~= nil then + -- Skip this parent if it's not from the current generation + if not isParentGenerationObserved(obj, parent) then + goto continue + end + local resolvedRefsFalse, resolvedRefsMsg = checkConditions(parent.conditions, "ResolvedRefs") local acceptedFalse, acceptedMsg = checkConditions(parent.conditions, "Accepted") @@ -44,15 +73,20 @@ if obj.status ~= nil then hs.message = "Parent " .. (parent.parentRef.name or "") .. ": " .. progressingMsg return hs end + + ::continue:: end end if #obj.status.parents > 0 then for _, parent in ipairs(obj.status.parents) do if parent.conditions ~= nil and #parent.conditions > 0 then - hs.status = "Healthy" - hs.message = "HTTPRoute is healthy" - return hs + -- Only mark as healthy if we found a parent from the current generation + if isParentGenerationObserved(obj, parent) then + hs.status = "Healthy" + hs.message = "HTTPRoute is healthy" + return hs + end end end end diff --git a/resource_customizations/gateway.networking.k8s.io/HTTPRoute/health_test.yaml b/resource_customizations/gateway.networking.k8s.io/HTTPRoute/health_test.yaml index 0e828ea517..5d3966c0f4 100644 --- a/resource_customizations/gateway.networking.k8s.io/HTTPRoute/health_test.yaml +++ b/resource_customizations/gateway.networking.k8s.io/HTTPRoute/health_test.yaml @@ -14,4 +14,8 @@ tests: - healthStatus: status: Progressing message: "Parent example-gateway: Route is still being programmed" - inputPath: testdata/progressing.yaml \ No newline at end of file + inputPath: testdata/progressing.yaml +- healthStatus: + status: Healthy + message: HTTPRoute is healthy + inputPath: testdata/healthy_multiple_generations.yaml diff --git a/resource_customizations/gateway.networking.k8s.io/HTTPRoute/testdata/healthy_multiple_generations.yaml b/resource_customizations/gateway.networking.k8s.io/HTTPRoute/testdata/healthy_multiple_generations.yaml new file mode 100644 index 0000000000..0aab4f61bd --- /dev/null +++ b/resource_customizations/gateway.networking.k8s.io/HTTPRoute/testdata/healthy_multiple_generations.yaml @@ -0,0 +1,59 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: example-httproute + generation: 2 +spec: + parentRefs: + - kind: Gateway + name: eg + namespace: envoy-gateway-system + sectionName: foo-nonexistent + hostnames: + - "example-httproute.example.com" + rules: + - backendRefs: + - name: example-service + port: 8080 +status: + parents: + - conditions: + - lastTransitionTime: "2025-10-14T11:19:41Z" + message: No listeners match this parent ref + observedGeneration: 1 + reason: NoMatchingParent + status: "False" + type: Accepted + - lastTransitionTime: "2025-10-14T11:19:41Z" + message: Resolved all the Object references for the Route + observedGeneration: 1 + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + group: gateway.networking.k8s.io + kind: Gateway + name: eg + namespace: envoy-gateway-system + sectionName: foo-nonexistent + - conditions: + - lastTransitionTime: "2025-10-14T11:25:18Z" + message: Route is accepted + observedGeneration: 2 + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: "2025-10-14T11:25:18Z" + message: Resolved all the Object references for the Route + observedGeneration: 2 + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + group: gateway.networking.k8s.io + kind: Gateway + name: eg + namespace: envoy-gateway-system + sectionName: https-net