feat(api,admin,gateway): add dynamic cross-zone proxy target ACL management#287
Open
feat(api,admin,gateway): add dynamic cross-zone proxy target ACL management#287
Conversation
…gement Remove the hardcoded "gateway" mesh-client from Realm DefaultConsumers and instead add it only to routes that are actual cross-zone proxy targets. When an ApiExposure has subscribers in a different zone, the reconciler now detects this via HasCrossZoneSubscribers and sets the WithProxyTarget option so the real route's ACL includes "gateway". Failover secondary proxy routes also get the consumer automatically. A new MapApiSubscriptionToApiExposure watch ensures ApiExposures are re-reconciled when subscriptions change, so the gateway consumer is added or removed dynamically. Includes integration tests for the cross-zone ACL lifecycle (add/remove subscription triggers consumer update), a failover route assertion, and Ginkgo/Gomega unit tests for route_util option functions and helpers.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR makes cross-zone proxy ACL handling dynamic by removing the hardcoded "gateway" consumer from Realm defaults and instead adding/removing it on specific Routes that are cross-zone proxy targets, based on current ApiSubscription state.
Changes:
- Remove
"gateway"fromRealm.Spec.DefaultConsumersand shift responsibility toRoute.Spec.Security.DefaultConsumersfor proxy-target routes. - Add
WithProxyTarget/IsProxyTargetroute creation option and apply it when an ApiExposure has cross-zone subscribers; ensure failover secondary proxy routes also allow the gateway consumer. - Add an ApiSubscription watch to re-reconcile affected ApiExposures when subscriptions change; extend integration/unit tests for add/remove lifecycle and failover behavior.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| gateway/internal/features/suite_test.go | Updates mock realm defaults to no longer include "gateway". |
| gateway/internal/features/builder_test.go | Adjusts feature tests to simulate proxy-target behavior via route-level DefaultConsumers. |
| gateway/internal/controller/realm_controller_test.go | Updates realm controller test fixtures to remove "gateway" from realm defaults. |
| api/internal/handler/util/suite_test.go | Adds a Ginkgo suite for util route option tests. |
| api/internal/handler/util/route_util_test.go | Adds unit tests for new route util options/helpers (including WithProxyTarget). |
| api/internal/handler/util/route_util.go | Introduces GatewayConsumerName and WithProxyTarget; applies gateway consumer to real routes marked as proxy targets and to failover secondary proxy routes. |
| api/internal/handler/apiexposure/util.go | Adds HasCrossZoneSubscribers helper to detect cross-zone subscribers for an ApiExposure. |
| api/internal/handler/apiexposure/handler.go | Uses HasCrossZoneSubscribers to set WithProxyTarget(...) when creating the real route. |
| api/internal/controller/apiexposure_controller_test.go | Adds integration tests for cross-zone ACL add/remove lifecycle and asserts failover secondary ACL contains gateway consumer. |
| api/internal/controller/apiexposure_controller.go | Adds watch/map function to requeue ApiExposures when ApiSubscriptions change. |
| admin/internal/handler/zone/handler.go | Stops creating gateway realms with "gateway" as a realm-level default consumer. |
| admin/internal/controller/zone_controller_test.go | Updates expectations for gateway realm default consumers to be empty. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…refine watch predicates - Move DeleteOnlyPredicate to common/pkg/controller for reuse across domains - Change ApiExposure's ApiSubscription watch predicate from ResourceVersionChangedPredicate to GenerationChangedPredicate OR DeleteOnlyPredicate, avoiding unnecessary reconciliations on status-only updates - Add IsBeingDeleted check in HasCrossZoneSubscribers (API domain), FindCrossZoneSSESubscriptionZones and FindCrossZoneCallbackSubscriptions (Event domain) to skip subscriptions with a non-nil DeletionTimestamp, preventing stale proxy routes during finalizer execution
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Remove the hardcoded "gateway" mesh-client from Realm DefaultConsumers
and instead add it only to routes that are actual cross-zone proxy
targets. When an ApiExposure has subscribers in a different zone, the
reconciler now detects this via HasCrossZoneSubscribers and sets the
WithProxyTarget option so the real route's ACL includes "gateway".
Failover secondary proxy routes also get the consumer automatically.
A new MapApiSubscriptionToApiExposure watch ensures ApiExposures are
re-reconciled when subscriptions change, so the gateway consumer is
added or removed dynamically.
Includes integration tests for the cross-zone ACL lifecycle (add/remove
subscription triggers consumer update), a failover route assertion, and
Ginkgo/Gomega unit tests for route_util option functions and helpers.