feat(exposure-driven-proxy-routes): proxy routes are now created from api exposures perspective#316
feat(exposure-driven-proxy-routes): proxy routes are now created from api exposures perspective#316julius-malcovsky wants to merge 4 commits intomainfrom
Conversation
… api exposures perspective Co-authored-by: Björn Kottner <BjoernKarma@users.noreply.github.com> Co-authored-by: Ismael Garba <iagarba@users.noreply.github.com> Co-authored-by: Stefan Siber <stefan-ctrl@users.noreply.github.com> Co-authored-by: Ron Gummich <ron96g@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR implements an exposure-driven pattern for proxy route creation, where API exposures (providers) now create proxy routes for all cross-zone subscriptions, rather than each subscription creating its own routes. This architectural change simplifies subscription logic and centralizes route management under the ApiExposure controller.
Changes:
- Centralized proxy route creation: ApiExposure now queries approved subscriptions via
FindCrossZoneApiSubscriptionZones()and creates proxy routes for each subscriber zone - Simplified subscriptions: ApiSubscription handlers now only reference routes created by ApiExposure, reducing complexity
- Improved watch predicate: ApiExposure controller watches ApiSubscription changes with ResourceVersionChangedPredicate to react to approval status changes (not just spec changes)
- Stale route cleanup: New
CleanupStaleProxyRoutes()function removes routes that weren't touched in the current reconciliation cycle - Comprehensive tests: Large new test suite validates failover scenarios, deduplication, and approval workflows
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| api/internal/handler/util/route_util.go | New CleanupStaleProxyRoutes() function for stale route cleanup |
| api/internal/handler/util/getters.go | New FindCrossZoneApiSubscriptionZones() function to identify zones needing proxy routes |
| api/internal/handler/apisubscription/handler.go | Refactored to reference proxy routes created by ApiExposure instead of creating them |
| api/internal/handler/apiexposure/handler.go | Now creates proxy routes for all cross-zone subscriptions; enhanced deletion logic |
| api/internal/controller/apiexposure_controller.go | Changed ApiSubscription watch to ResourceVersionChangedPredicate |
| api/config/crd/bases/api.cp.ei.telekom.de_apiexposures.yaml | Added proxyRoutes array field to ApiExposureStatus |
| api/api/v1/apiexposure_types.go | Added ProxyRoutes field to ApiExposureStatus struct |
| api/api/v1/zz_generated.deepcopy.go | Updated deepcopy implementation for ProxyRoutes |
| api/internal/controller/apisubscription_controller_test.go | Updated tests; removed obsolete failover scenarios |
| api/internal/controller/apisubscription_controller_failover_test.go | New comprehensive failover test suite |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Björn Kottner <BjoernKarma@users.noreply.github.com> Co-authored-by: Ismael Garba <iagarba@users.noreply.github.com> Co-authored-by: Stefan Siber <stefan-ctrl@users.noreply.github.com> Co-authored-by: Ron Gummich <ron96g@users.noreply.github.com>
| options = append(options, util.ReturnReferenceOnly()) | ||
| if sameZoneAsExposure { | ||
| // Same zone: reference the real route in exposure zone | ||
| zone, err := util.GetZone(ctx, scopedClient, apiExposure.Spec.Zone.K8s()) |
There was a problem hiding this comment.
Is this needed? Cant we get them from the ApiExposure status directly? Then we could laos add a Blocked condition to indicate that ApiExposure is not done or whatever.
api/internal/handler/util/getters.go
Outdated
|
|
||
| // Check approval status | ||
| approvalGranted := false | ||
| for _, cond := range sub.GetConditions() { |
There was a problem hiding this comment.
Have a look at the event domain how its done there. There are already methods to do this
api/internal/handler/util/getters.go
Outdated
|
|
||
| // Skip subscriptions that are being deleted; their finalizer may still | ||
| // be running, but they should no longer influence proxy route creation. | ||
| if sub.GetDeletionTimestamp() != nil { |
There was a problem hiding this comment.
check event domain how its done there
api/internal/handler/util/getters.go
Outdated
| var zones []types.ObjectRef | ||
|
|
||
| // Helper function to add a zone if it's not already seen and passes filters | ||
| addZoneIfValid := func(zone types.ObjectRef, reason string) { |
There was a problem hiding this comment.
Personally I think this is really hard to read with the inline function and then the 2 loops
There was a problem hiding this comment.
tried a different approach - let me know if its easier on the eyes :)
| // This handles zone changes: when subscriptions move or are deleted, old proxy routes are cleaned up. | ||
| // NOTE: This does NOT delete provider failover routes (labeled with failover.secondary=true), | ||
| // as those are managed separately by ApiExposure and should not be cleaned up here. | ||
| func CleanupStaleProxyRoutes(ctx context.Context, apiBasePath string) (int, error) { |
There was a problem hiding this comment.
Do we need this or can we just use the JanitorClient?
There was a problem hiding this comment.
Context: Now the ApiExposure always provisions the entire state (all Routes), therefore, the JanitorClient can just cleanup all Rout CRs that were not "touched" in the reconcilation
Co-authored-by: Björn Kottner <BjoernKarma@users.noreply.github.com> Co-authored-by: Ismael Garba <iagarba@users.noreply.github.com> Co-authored-by: Stefan Siber <stefan-ctrl@users.noreply.github.com> Co-authored-by: Ron Gummich <ron96g@users.noreply.github.com>
…lity Co-authored-by: Björn Kottner <BjoernKarma@users.noreply.github.com> Co-authored-by: Ismael Garba <iagarba@users.noreply.github.com> Co-authored-by: Stefan Siber <stefan-ctrl@users.noreply.github.com> Co-authored-by: Ron Gummich <ron96g@users.noreply.github.com>
… api exposures perspective