Skip to content

feat(gateway-operator): add per-operation upstream override to the RestApi CRD#2834

Draft
mehara-rothila wants to merge 1 commit into
wso2:mainfrom
mehara-rothila:feat/operator-per-op-upstream
Draft

feat(gateway-operator): add per-operation upstream override to the RestApi CRD#2834
mehara-rothila wants to merge 1 commit into
wso2:mainfrom
mehara-rothila:feat/operator-per-op-upstream

Conversation

@mehara-rothila

Copy link
Copy Markdown
Contributor

Purpose

Add per-operation upstream overrides to the gateway-operator's RestApi CRD, so an individual operation can route to a different backend by referencing a named entry in the API's upstreamDefinitions pool. This is the operator-side counterpart of the same feature on the other two planes: the platform-api control plane (PR #2155) and the gateway-controller data plane (PR #2012). The operator's CRD already carried the upstreamDefinitions pool and the API-level upstream.ref, but its Operation type had no per-operation upstream field, so this closes that gap and brings the CRD surface to parity with the platform-api.

Approach

  • Schema: Operation gains an optional upstream override whose main/sandbox each reference a pool entry by name (ref only, no inline URLs), mirroring the platform-api OperationUpstream shape. ref is required within each block, and a CEL validation (x-kubernetes-validations) requires at least one of main or sandbox.
  • Both served versions: the field is added identically to api/v1 (storage) and api/v1alpha1 (served). The two versions use conversion strategy None (a plain JSON round-trip that only works while the schemas are identical), and TestCRDVersionSchemasIdentical enforces that invariant, so the field must be mirrored in both.
  • No emission wiring needed: the operator serializes the deployment payload via json.Marshal, so the new field flows to the gateway automatically through its json tags. The gateway-controller then enforces and routes it (PR Add per-operation upstream override for REST API operations #2012).
  • Generated artifacts: zz_generated.deepcopy.go (both versions) and the RestApi CRD manifest were regenerated with the pinned controller-gen v0.16.5.

Example

A RestApi with a reusable pool, an API-level default upstream, and one operation overridden to a pool entry:

apiVersion: gateway.api-platform.wso2.com/v1
kind: RestApi
metadata:
  name: example-api
spec:
  context: /hello
  displayName: Hello API
  version: v1.0
  upstream:
    main:
      url: http://main.default.svc.cluster.local:8080   # API-level default
  upstreamDefinitions:                                   # reusable, named upstream pool
    - name: alt-backend
      basePath: /api/v2
      timeout:
        connect: 5s
      upstreams:
        - url: http://alt.default.svc.cluster.local:9090
          weight: 80
  operations:
    - method: GET
      path: /whoami
      upstream:
        main:
          ref: alt-backend        # this operation routes to alt-backend
    - method: GET
      path: /ping                 # no override, uses the API-level upstream

Testing

  • TestCRDVersionSchemasIdentical and the v1alpha1 to v1 conversion round-trip tests pass, confirming the two served versions stay schema-identical with the new field.
  • A new payload test (TestBuildRestAPIYAML_CarriesPerOperationUpstreamRef) verifies that operations[].upstream.main.ref survives into the emitted management-API YAML, and that an operation without an override does not emit an upstream.
  • The full api/... and internal/... suites pass, including the HTTPRoute compile tests (this change is purely additive and does not alter existing routing logic).

Note on merge order

This PR depends on the gateway-controller understanding operations[].upstream.ref, which lands in PR #2012. It should therefore be merged after #2012, and rebased onto a main that includes it, so the end-to-end path works at runtime.

Adds operations[].upstream to the RestApi CRD so an operation can reference a
named upstreamDefinitions entry (main/sandbox), mirroring the platform-api
per-operation override. The field is added identically to v1 and v1alpha1 to
keep the served-version schemas identical, with regenerated deepcopy and CRD
manifest and a payload test covering ref emission.
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 69e8aee6-0744-4a53-8b86-18772e764e69

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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