Skip to content

feat: add ADC-backed admission validation for APISIX CRDs#2758

Open
AlinsRan wants to merge 1 commit intoapache:masterfrom
AlinsRan:feat/webhook-adc-validation
Open

feat: add ADC-backed admission validation for APISIX CRDs#2758
AlinsRan wants to merge 1 commit intoapache:masterfrom
AlinsRan:feat/webhook-adc-validation

Conversation

@AlinsRan
Copy link
Copy Markdown
Contributor

@AlinsRan AlinsRan commented May 6, 2026

Summary

This PR adds live ADC-backed admission validation to the existing webhook validators for ApisixRoute, ApisixConsumer, ApisixTls, and Consumer resources.

Previously the webhooks only emitted warnings for missing references (services, secrets). With this change, resources are also structurally validated against a live APISIX instance before being admitted.

Changes

Core infrastructure

  • internal/types/error.go: Add ADCValidationErrors, ADCValidationError, ADCValidationServerAddrError, and ADCValidationDetail types to carry structured validation error details.

  • internal/adc/client/executor.go:

    • Add Validate() to the ADCExecutor interface and HTTPADCExecutor
    • Implement runHTTPValidate / runHTTPValidateForSingleServer that POST to the /configs/validate endpoint
    • Refactor buildHTTPRequest to accept an HTTP method and path (supporting both /sync and /configs/validate)
    • Set TLS minimum version to 1.2
    • Redact full request body from logs (log length only)
  • internal/adc/client/client.go: Add Client.Validate() which calls the executor's validate path and aggregates ADCValidationErrors.

Webhook validation helpers

  • internal/controller/webhook_validation.go (new): Lightweight Prepare*ForValidation helpers for each CRD type that build a TranslateContext without running the full reconciler loop. Used by the admission webhook to resolve references before translating.

Admission validator

  • internal/webhook/v1/adc_validation.go (new): adcAdmissionValidator that:
    • Resolves the IngressClass / GatewayProxy for the resource
    • Translates the resource into an ADC payload
    • Posts the payload to APISIX via client.Validate()
    • Fails open on infrastructure / transport errors (only ADCValidationErrors cause denial)
    • Populates global_rules and plugin_metadata in the validate payload so plugin references can be resolved

Webhook wiring

  • apisixroute_webhook.go, apisixconsumer_webhook.go, apisixtls_webhook.go, consumer_webhook.go: Wire adcAdmissionValidator; ADC init errors are logged and ignored (fail-open).

  • apisixtls_webhook.go: Skip ADC validation when secrets are missing to preserve the existing warn-only behaviour for that case.

  • consumer_webhook.go: Validate duplicate key-auth credential keys scoped to the same GatewayRef using a field-index query (O(1) instead of O(N) full list). Malformed inline JSON credentials are logged and skipped rather than causing a hard denial.

Behaviour notes

Scenario Before After
Valid resource, ADC reachable Admit with warnings Admit (pass validation)
Invalid resource, ADC reachable Admit with warnings Deny with structured errors
ADC unreachable / init error Admit with warnings Admit with warnings (fail-open)
ApisixTls with missing secrets Admit with warnings Admit with warnings (unchanged)
Consumer with duplicate key-auth key Admit Deny
Consumer with malformed inline credential JSON Admit Admit (log + skip duplicate check)

Validate ApisixRoute, ApisixConsumer, ApisixTls and Consumer resources
against a live APISIX instance during admission instead of only
producing warnings.

Key changes:
- Add ADCValidationErrors / ADCValidationError types (internal/types)
- Add Validate() to HTTPADCExecutor and Client; introduce the
  /configs/validate endpoint support in executor.go (TLS min-version
  set to 1.2, request body no longer logged in full)
- Add internal/controller/webhook_validation.go: lightweight helpers
  (PrepareApisixRouteForValidation, PrepareApisixConsumerForValidation,
  PrepareConsumerForValidation, PrepareApisixTlsForValidation) that
  build a TranslateContext without starting the full reconciler loop
- Add internal/webhook/v1/adc_validation.go: adcAdmissionValidator
  that translates a CRD into an ADC payload and posts it to APISIX for
  structural validation; fails open on infrastructure errors
- Wire adcAdmissionValidator into all four webhook validators; init
  errors are logged and ignored (fail-open)
- ApisixTls: skip ADC validation when secrets are missing to preserve
  the existing warn-only behaviour for that case
- Consumer: validate duplicate key-auth credential keys scoped to the
  same GatewayRef using a field-index query; malformed inline JSON is
  logged and skipped (not a hard denial)
- global_rules and plugin_metadata are now populated in the ADC
  validate payload so APISIX can resolve plugin references

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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