@@ -363,6 +363,95 @@ AIRoutingPolicy specifies HTTP listeners, the AIAccessPolicy overrides
363363them to HTTPS — access policy takes precedence over routing config for
364364the listener protocol.
365365
366+ # ## Status
367+
368+ Both CRDs report their state through standard `metav1.Condition`
369+ entries plus per-component status maps. The conditions give aggregate
370+ signals (suitable for `kubectl wait --for=condition=...`); the maps
371+ give per-provider or per-component detail for debugging.
372+
373+ # ### AIRoutingPolicy
374+
375+ ` ` ` yaml
376+ status:
377+ conditions:
378+ - type: Accepted # spec is syntactically valid
379+ status: "True"
380+ reason: Valid
381+ - type: GatewayBound # targetRef Gateway exists
382+ status: "True"
383+ reason: Bound
384+ - type: ProvidersConfigured # all provider resources created
385+ status: "False"
386+ reason: PartialFailure
387+ message: "2/3 providers configured"
388+ - type: RoutingActive # AIGatewayRoute + BTP created and accepted
389+ status: "True"
390+ reason: Applied
391+
392+ providers:
393+ - name: ollama
394+ ready: true
395+ - name: openai
396+ ready: true
397+ - name: bedrock
398+ ready: false
399+ error: "invalid endpoint URL: missing scheme"
400+
401+ models:
402+ - name: gpt-4o
403+ ready: true
404+ - name: qwen2.5:3b
405+ ready: true
406+ ` ` `
407+
408+ | Condition | True when | False reasons |
409+ |-----------|-----------|---------------|
410+ | `Accepted` | Spec passes validation (endpoints parse, names unique) | `InvalidSpec` |
411+ | `GatewayBound` | Target Gateway exists in namespace | `GatewayNotFound` |
412+ | `ProvidersConfigured` | All Backend + AIServiceBackend + BSP resources created | `PartialFailure`, `ApplyFailed`, `CredentialSecretNotFound` |
413+ | `RoutingActive` | AIGatewayRoute + BackendTrafficPolicy created and accepted | `ApplyFailed` |
414+
415+ The `status.providers[]` list mirrors `spec.providers[]` and reports
416+ per-provider readiness. When `ProvidersConfigured` is False, the
417+ provider entries show exactly which providers failed and why —
418+ eliminating guesswork in multi-provider configurations.
419+
420+ The `status.models[]` list tracks per-model route rule creation. In
421+ the common case all models are ready; a model becomes not-ready if its
422+ referenced provider is missing from the spec.
423+
424+ # ### AIAccessPolicy
425+
426+ ` ` ` yaml
427+ status:
428+ conditions:
429+ - type: Accepted
430+ status: "True"
431+ reason: Valid
432+ - type: GatewayBound
433+ status: "True"
434+ reason: Bound
435+ - type: BundleReady # trust bundle parsed with ≥1 valid cert
436+ status: "True"
437+ reason: Loaded
438+ message: "2 certificates from SPIFFE JSON bundle"
439+ - type: MTLSActive # CA Secret + server cert + CTP created
440+ status: "True"
441+ reason: Applied
442+ ` ` `
443+
444+ | Condition | True when | False reasons |
445+ |-----------|-----------|---------------|
446+ | `Accepted` | Spec passes validation | `InvalidSpec` |
447+ | `GatewayBound` | Target Gateway exists in namespace | `GatewayNotFound` |
448+ | `BundleReady` | Trust bundle ConfigMap read and parsed with ≥1 valid cert | `BundleNotFound`, `BundleEmpty`, `BundleParseError` |
449+ | `MTLSActive` | CA Secret, server cert, and ClientTrafficPolicy created | `ApplyFailed`, `CertGenerationFailed` |
450+
451+ ` BundleReady` is re-evaluated on every requeue (default 5 minutes),
452+ so it reflects trust bundle rotations. The message includes the
453+ certificate count for visibility into how many CAs are trusted.
454+
366455# ## Future: guardrails
367456
368457Content filtering, prompt injection detection, and PII redaction are
@@ -515,27 +604,35 @@ policy simply means that capability isn't configured.
515604
516605```
517606AIRoutingPolicyReconciler
607+ ├── validate spec → set Accepted condition
608+ ├── verify target Gateway exists → set GatewayBound condition
518609 ├── parse provider endpoints (URL → host + port)
519610 ├── for each provider:
520611 │ ├── create/update Backend (gateway.envoyproxy.io)
521612 │ ├── create/update AIServiceBackend (aigateway.envoyproxy.io)
522- │ └── create/update BackendSecurityPolicy (if credentials set)
613+ │ ├── create/update BackendSecurityPolicy (if credentials set)
614+ │ └── record result in status.providers[ ]
615+ ├── set ProvidersConfigured condition (aggregate)
523616 ├── create/update AIGatewayRoute
524617 │ ├── one rule per model (x-ai-eg-model match → backendRefs)
525- │ └── llmRequestCosts (if any model has rateLimit)
618+ │ ├── llmRequestCosts (if any model has rateLimit)
619+ │ └── record result in status.models[ ]
526620 ├── create/update BackendTrafficPolicy
527621 │ ├── per-model failover/retry config
528- │ └── per-model rate limit rules (x-ai-eg-model header selectors)
529- ├── clean up orphaned resources for removed providers
530- └── update status conditions
622+ │ └── per-model rate limit rules
623+ ├── set RoutingActive condition
624+ └── clean up orphaned resources for removed providers
531625
532626AIAccessPolicyReconciler
627+ ├── validate spec → set Accepted condition
628+ ├── verify target Gateway exists → set GatewayBound condition
533629 ├── read SPIRE trust bundle ConfigMap
534630 ├── parse SPIFFE JSON → extract x509-svid certs → PEM
631+ ├── set BundleReady condition (with cert count)
535632 ├── create/update CA Secret
536633 ├── create/update self-signed server cert (if no serverCertRef)
537634 ├── create/update ClientTrafficPolicy
538- └── update status conditions
635+ └── set MTLSActive condition
539636```
540637
541638All generated resources carry an owner reference to their policy CR.
0 commit comments