fix(operator): reject conflicting cross-namespace expose routes - #2783
fix(operator): reject conflicting cross-namespace expose routes#2783chance-coleman wants to merge 4 commits into
Conversation
|
@greptileai review |
Greptile SummaryThe PR adds admission-time detection of conflicting cross-namespace HTTP expose routes and keeps the supporting in-memory indexes synchronized during package updates and deletion.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains; both previously reported issues are addressed by the current code. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Package admission request] --> B[Normalize gateway and FQDN]
B --> C[Look up indexed exposes]
C --> D{Different namespace with same key?}
D -- No --> G[Approve after remaining validation]
D -- Yes --> E{Both routes have path matches?}
E -- Yes --> G
E -- No --> F[Deny conflicting endpoint]
H[Package watch event] --> I{Added or Modified?}
I -- Yes --> J[Replace stored package and indexes]
I -- No, Deleted --> K[Load stored package before removal]
K --> L[Remove exposure, SSO, and UDP indexes]
Reviews (3): Last reviewed commit: "Merge branch 'main' into chance/core-600" | Re-trigger Greptile |
|
LGTM 🚀 |
mjnagel
left a comment
There was a problem hiding this comment.
Haven't done any code review but do want to call out that this is a breaking change and should be reflected as such in release notes at a minimum. I believe there is also technically a use-case for this when using advanced http match in an expose entry - you could have certain paths route to services in different namespaces (for the same endpoint). Whether that is something that is currently being used and/or should be supported I'm not sure.
Yeah this is a good callout. I think it wouldn't be a breaking change if we prevent expose entries that technically cause a conflict? If they have the same spec one of the expose entries will just not work (and I would consider that as a bug fix?). Maybe we take into account more than just the expose fqdn to make sure there aren't conflicts. |
|
On the breaking change: i agree that any existing overlap is already silently broken at the Istio level (last VirtualService wins, undefined behavior). The admission deny just makes it visible. That said, i think it makes sense to call this change in behavior out. so I'll add a release note calling it out. On advancedHTTP.match: The current check uses gateway:fqdn only and would incorrectly deny two packages routing different paths on the same host. I'm thinking i will just implement a fix for this now, if |
I need to think through this... But would it instead be worth it to just take a hash or string combination of all the fields that make an expose route unique/work? i.e. FQDN + advancedHTTP + any other fields? |
the hash approach is better than skip for catching exact duplicates, but neither solves actual path overlap detection. Whether that extra coverage is worth the added implementation complexity is the real question. |
|
Getting around to reviewing this again - the root of this issue is that we want to block Packages if their expose entry would match on the same endpoint (host + path) as another existing Package. Reviewing the istio configuration here I think this could be a rough approach for handling: Details
The main edge cases/missing pieces in the examples above are some of the more complex/annoying settings:
I think we could handle any/all of these if we wanted, but it does start to increase the complexity more and more. I couldn't come up with a solid way to take a hash approach or more cleanly diff things - I think we'd really have to compare setting by setting for each of these. After going through that exercise I'm not actually convinced it's the right approach - it starts to feel like we're coupling too closely to advanced Istio mechanisms. Thinking about this a bit more from our actual userbase... most users will probably not be touching
Both of these would be a bit permissive when Curious on thoughts here @joelmccoy @chance-coleman - does this direction make sense? |
|
Option 2 does feel better to me. it's not just safer default for operators but its also more honest what happens at runtime. for the cross namespace path routing use case to work both sides would have to set a |
45a94f7 to
7337cf7
Compare
Description
Adds admission-time collision detection for HTTP
PackageCR expose entries.Two packages in different namespaces cannot claim the same gateway and FQDN when either route is a catch-all. Both routes remain allowed when they define
advancedHTTP.matchfor path-based routing. Deprecatedexpose.matchentries are treated as advanced matches.The cross-namespace rule intentionally follows option 2 from the review discussion:
advancedHTTP.match.PackageCR.This changes admission behavior for previously ambiguous configurations that already had undefined runtime routing behavior. The breaking-change release note is intentionally deferred to the
1.11release preparation and is not added to the1.9notes.Related Issue
Fixes #CORE-600
Type of change
Steps to Validate
npm run test:unit.npm run format:check.advancedHTTP.match.expose.matchentries are treated as advanced matches.PackageCR.Checklist before merging
1.11release preparation