test(conformance): enable HTTPRouteMethodMatching for hybrid gateway - #4715
test(conformance): enable HTTPRouteMethodMatching for hybrid gateway#4715tao12345666333 wants to merge 5 commits into
Conversation
59f6743 to
c742669
Compare
e62a642 to
65505d0
Compare
|
/muthur review this PR |
|
Run report (federated)
|
There was a problem hiding this comment.
Go Code Review: Hybridgateway HTTPRoute method matching
Summary
| Verdict | REQUEST_CHANGES |
|---|---|
| Critical/High | 1 |
This PR reworks the hybridgateway HTTPRoute→KongRoute translation so method-only matches materialize the default root path / (and are ordered above header-only matches), renames the header-only regex-path helpers/constant to default-path equivalents, and enables the HTTPRouteMethodMatching Gateway API conformance feature for the traditional-compatible router / hybrid gateway.
The core translation/priority logic (isDefaultPathHTTPRouteMatch, priorityForDefaultPathHTTPRouteMatch, calculateHTTPRoutePriorityClass, WithHTTPRouteMatch, WithDefaultPathRegexPath) is internally consistent and well covered by the added unit tests; multiple scenarios (method-only, header-only, method+header, explicit PathPrefix "/" vs nil path, exact/regex paths) were traced without finding a mis-ranking.
The issue is in the feature-declaration half: GetSupportedFeatures is keyed solely by router flavor and is gwType-blind, so advertising SupportHTTPRouteMethodMatching on the shared traditionalCompatibleRouterSupportedFeatures slice flips the advertised bit for standard gateways too — while the same PR adds a compensating conformance skip for the standard+traditional-compatible combination, i.e. it isn't verified there. Both findings survived the adversarial audit pass (verified against GetSupportedFeatures, setSupportedFeatures/getRouterFlavor, and the conformance skip wiring).
Additional Risk pass: No leaked secrets, security vulnerabilities, or resource/memory leaks found. The only non-Go changed file is CHANGELOG.md (documentation only). No additional concerns found beyond the two findings below.
| traditionalCompatibleRouterSupportedFeatures = append(slices.Clone(commonSupportedFeatures), | ||
| // HTTPRoute extended. | ||
| features.SupportHTTPRouteMethodMatching, |
There was a problem hiding this comment.
🔴 High bug
Feature advertised for standard gateways where this PR does not implement it (and CI skips it).
SupportHTTPRouteMethodMatching is added to traditionalCompatibleRouterSupportedFeatures, which is returned by GetSupportedFeatures(routerType consts.RouterFlavor) — a function keyed only by router flavor, with no notion of hybrid vs. standard gateway. That same function feeds two consumers:
- Production:
setSupportedFeatures(controller/gatewayclass/controller_reconciler_utils.go:75-92) callsGetSupportedFeatures(flavor)(flavor fromgetRouterFlavor, derived purely fromKONG_ROUTER_FLAVOR) and writes the result verbatim intoGatewayClass.Status.SupportedFeatures. - Conformance:
conformance_test.go:63calls the identicalGetSupportedFeatures(kongRouterFlavor)for both gateway types.
This PR's fix lives entirely under controller/hybridgateway/...; the standard (non-hybrid, embedded-KIC) route-translation path is untouched. Yet in the same PR, test/conformance/skipped_tests_test.go:28 adds HTTPRouteMethodMatching to skippedTestsForStandardTraditionalCompatibleRouter, which skippedTestsForConfig applies only when gwType == standardGateway.
Failing sequence: a standard GatewayClass backed by a DataPlane running KONG_ROUTER_FLAVOR=traditional_compatible (the default flavor for the non-hybrid path) reconciles → setSupportedFeatures now publishes SupportHTTPRouteMethodMatching in .status.supportedFeatures, advertising a capability that this same PR simultaneously marks as unverified/skipped in conformance for that exact combination. Any consumer using GatewayClass.status.supportedFeatures for capability discovery (the standard Gateway API mechanism) is misinformed.
Fix options:
- Make the supported-feature set gwType-aware (thread a hybrid signal through
setSupportedFeatures/GetSupportedFeatures) so method matching is only surfaced for the hybrid gateway; or - Keep
SupportHTTPRouteMethodMatchingout of the sharedtraditionalCompatibleRouterSupportedFeaturesslice and special-case it on the hybrid path only; or - If standard + traditional-compatible method matching genuinely works today, remove the standard conformance skip instead so advertisement and verification agree.
There was a problem hiding this comment.
As stated in the PR title, I intentionally only modified HybridGateway here. The benefit of this is that it makes the PR review more convenient and reduces the scope of changes. So I will keep it as it is for now.
| // WithDefaultPathRegexPath replaces the default root path with a catch-all regex | ||
| // path so regex_priority can order default-path HTTPRoute matches. | ||
| func (b *KongRouteBuilder) WithDefaultPathRegexPath() *KongRouteBuilder { | ||
| if len(b.route.Spec.Paths) == 0 || (len(b.route.Spec.Paths) == 1 && b.route.Spec.Paths[0] == "/") { |
There was a problem hiding this comment.
🔵 Low risk
Default-path invariant not enforced for the capture-group path form.
WithDefaultPathRegexPath's guard matches only an empty Paths slice or the single-element ["/"]. When setCaptureGroup == true (a rule carrying a URLRewrite/RequestRedirect filter with ReplacePrefixMatch), an explicit Path{Type: PathPrefix, Value: "/"} combined with a Method produces the two-element capture-group form ["~/$", "~/(.*)"] from GenerateKongRoutePathFromHTTPRouteMatch. Because priorityForDefaultPathHTTPRouteMatch treats explicit PathPrefix "/" as a default-path match, WithRegexPriority(...).WithDefaultPathRegexPath() runs — but the 2-element slice doesn't match the guard, so Paths stays ["~/$", "~/(.*)"] instead of collapsing to KongHTTPRouteDefaultPathRegexPath.
This is not a mis-route: both entries are already regex-form so regex_priority still applies, and "~/$" is subsumed by "~/(.*)". But the Gateway-API-equivalent input with Path omitted (nil) collapses to a single ["~/(.*)"], so two equivalent inputs yield different internal KongRoute representations, and only the plain (non-capture-group) default-path cases are covered by tests. Consider extending the guard to also normalize the ["~/$", "~/(.*)"] form (and adding a test) so the invariant "default-path priority routes always use KongHTTPRouteDefaultPathRegexPath" actually holds.
Signed-off-by: Jintao Zhang <zhangjintao9020@gmail.com>
Signed-off-by: Jintao Zhang <zhangjintao9020@gmail.com>
Signed-off-by: Jintao Zhang <zhangjintao9020@gmail.com>
Signed-off-by: Jintao Zhang <zhangjintao9020@gmail.com>
Signed-off-by: Jintao Zhang <zhangjintao9020@gmail.com>
3e32533 to
a95ffb4
Compare
What this PR does / why we need it:
Which issue this PR fixes
Fixes #3445
Special notes for your reviewer:
PR Readiness Checklist:
Complete these before marking the PR as
ready to review:CHANGELOG.mdrelease notes have been updated to reflect significant changes