Skip to content

fix(issues): detect missing Gateway API references - #1392

Merged
nadaverell merged 1 commit into
fix/rad-346-webhook-missing-servicefrom
fix/rad-346-gateway-missing-refs
Aug 9, 2026
Merged

fix(issues): detect missing Gateway API references#1392
nadaverell merged 1 commit into
fix/rad-346-webhook-missing-servicefrom
fix/rad-346-gateway-missing-refs

Conversation

@nadaverell

@nadaverell nadaverell commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • detect Gateways that reference a missing GatewayClass after a two-minute reconciliation grace
  • detect HTTPRoute, GRPCRoute, TCPRoute, and TLSRoute parentRefs that target a missing Gateway
  • require authoritative cluster or exact-namespace informer coverage before asserting absence
  • preserve unrelated Gateway controller conditions while deduplicating exact structural echoes, including Envoy Gateway PortNotFound
  • apply the same authority check to KEDA Rollout scaleTargetRefs so partial caches cannot produce false missing-target issues

Validation

  • make build
  • make test
  • make tsc
  • go test ./internal/issues ./internal/k8s
  • go test ./... from pkg/k8score/
  • live EKS smoke on radar-test-nonprod: grace suppression, both findings present, target creation recovery, and fixture cleanup
  • Playwright Issues-page smoke with both findings rendered and zero console errors
  • visual-test skipped: no UI delta

Stack

Linear: RAD-346


Note

Medium Risk
Changes live issue detection for Gateway networking and dynamic-cache “absence” semantics; incorrect authority or dedupe could hide real problems or briefly miss issues during informer sync, but behavior is heavily tested and biased toward silence when coverage is incomplete.

Overview
Extends Gateway API missing-reference detection beyond route backend Services: after a 2-minute grace, it flags Gateways with a non-existent spec.gatewayClassName and routes (HTTPRoute, GRPCRoute, TCPRoute, TLSRoute) whose parentRefs point at a missing Gateway (same- or cross-namespace). Backend Service / port / ReferenceGrant checks still require the Service lister; topology checks (class + parent) run even when Services aren’t available.

Issue taxonomy maps Missing GatewayClass to gateway_not_ready and Missing Gateway parent to gateway_route_invalid; user-facing catalog copy is updated accordingly.

Dedupe no longer drops every ResolvedRefs:* condition when any structural missing-ref exists on the route. It only hides matching controller echoes (e.g. backend missing → BackendNotFound / PortNotFound; ReferenceGrant → RefNotPermitted). A missing parent structural row does not suppress unrelated ResolvedRefs conditions.

Dynamic cache authority: new HasWatchedInSyncedNamespace returns “missing” only when the relevant informer has synced for that namespace (including during informer scope replacement). KEDA Rollout scaleTargetRefs use the same rule so partial watches don’t emit false missing scaleTargetRef issues. Initial add-event suppression is renamed/clarified so it isn’t confused with sync authority.

Reviewed by Cursor Bugbot for commit 93ee479. Bugbot is set up for automated code reviews on this repo. Configure here.

@nadaverell
nadaverell requested a review from hisco as a code owner August 9, 2026 07:36
@nadaverell
nadaverell force-pushed the fix/rad-346-gateway-missing-refs branch from 7daa6e4 to a0b4968 Compare August 9, 2026 08:13
@nadaverell
nadaverell force-pushed the fix/rad-346-gateway-missing-refs branch from a0b4968 to 93ee479 Compare August 9, 2026 08:26
@nadaverell
nadaverell merged commit 2da1e04 into fix/rad-346-webhook-missing-service Aug 9, 2026
1 check passed
@nadaverell
nadaverell deleted the fix/rad-346-gateway-missing-refs branch August 9, 2026 08:33
nadaverell added a commit that referenced this pull request Aug 9, 2026
## Summary
- detect Gateways that reference a missing GatewayClass after a
two-minute reconciliation grace
- detect HTTPRoute, GRPCRoute, TCPRoute, and TLSRoute parentRefs that
target a missing Gateway
- require authoritative cluster or exact-namespace informer coverage
before asserting absence
- preserve unrelated Gateway controller conditions while deduplicating
exact structural echoes, including Envoy Gateway PortNotFound
- apply the same authority check to KEDA Rollout scaleTargetRefs so
partial caches cannot produce false missing-target issues

## Validation
- `make build`
- `make test`
- `make tsc`
- `go test ./internal/issues ./internal/k8s`
- `go test ./...` from `pkg/k8score/`
- live EKS smoke on `radar-test-nonprod`: grace suppression, both
findings present, target creation recovery, and fixture cleanup
- Playwright Issues-page smoke with both findings rendered and zero
console errors
- visual-test skipped: no UI delta

## Stack
- stacked on #1391
- #1391 is stacked on #1390

Linear: RAD-346

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes live issue detection for Gateway networking and dynamic-cache
“absence” semantics; incorrect authority or dedupe could hide real
problems or briefly miss issues during informer sync, but behavior is
heavily tested and biased toward silence when coverage is incomplete.
> 
> **Overview**
> Extends **Gateway API missing-reference detection** beyond route
backend Services: after a **2-minute grace**, it flags **Gateways** with
a non-existent `spec.gatewayClassName` and **routes** (`HTTPRoute`,
`GRPCRoute`, `TCPRoute`, `TLSRoute`) whose `parentRefs` point at a
**missing Gateway** (same- or cross-namespace). **Backend Service / port
/ ReferenceGrant** checks still require the Service lister; **topology**
checks (class + parent) run even when Services aren’t available.
> 
> **Issue taxonomy** maps `Missing GatewayClass` to
**gateway_not_ready** and `Missing Gateway parent` to
**gateway_route_invalid**; user-facing catalog copy is updated
accordingly.
> 
> **Dedupe** no longer drops every `ResolvedRefs:*` condition when any
structural missing-ref exists on the route. It only hides **matching**
controller echoes (e.g. backend missing → `BackendNotFound` /
`PortNotFound`; ReferenceGrant → `RefNotPermitted`). A **missing
parent** structural row does **not** suppress unrelated `ResolvedRefs`
conditions.
> 
> **Dynamic cache authority**: new `HasWatchedInSyncedNamespace` returns
“missing” only when the relevant informer has **synced** for that
namespace (including during informer scope replacement). **KEDA
`Rollout` scaleTargetRefs** use the same rule so partial watches don’t
emit false **missing scaleTargetRef** issues. Initial add-event
suppression is renamed/clarified so it isn’t confused with sync
authority.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
93ee479. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant