Skip to content

fix: honor default gateway parent refs#1047

Open
pm-ju wants to merge 2 commits into
volcano-sh:mainfrom
pm-ju:fix-router-default-gateway-parentrefs
Open

fix: honor default gateway parent refs#1047
pm-ju wants to merge 2 commits into
volcano-sh:mainfrom
pm-ju:fix-router-default-gateway-parentrefs

Conversation

@pm-ju
Copy link
Copy Markdown
Contributor

@pm-ju pm-ju commented May 14, 2026

/kind bug

What this PR does / why we need it:

Gateway API ParentReference defaults group to gateway.networking.k8s.io and kind to Gateway when those fields are omitted.

The router currently requires kind: Gateway in some HTTPRoute and ModelRoute paths, so valid routes using parentRefs with only a name can be skipped or not indexed under their Gateway.

This change:

  • treats omitted group/kind as the Gateway API Gateway default
  • ignores explicit non-Gateway parentRefs
  • applies the behavior consistently in HTTPRoute controller queueing, HTTPRoute store indexing, ModelRoute gateway indexing, and ModelRoute gateway matching
  • adds unit coverage for default Gateway parentRefs and non-Gateway refs

Which issue(s) this PR fixes:

None

Special notes for reviewers:

Verification:

image

go test ./pkg/kthena-router/datastore ./pkg/kthena-router/controller

Copilot AI review requested due to automatic review settings May 14, 2026 07:45
@volcano-sh-bot
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign git-malu for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the handling of ParentReference objects within the HTTPRouteController and the datastore by introducing helper functions to identify Gateway resources. The review feedback identifies a logic error in the isGatewayParentRef function, which fails to correctly handle empty string groups as the default Gateway API group per the specification. This oversight also impacts the newly added test cases, which use empty strings to attempt to test non-matching groups. Additionally, the reviewer pointed out that the new helper functions and constants are duplicated across packages and should be moved to a shared location to improve maintainability.

Comment thread pkg/kthena-router/controller/httproute_controller.go Outdated
Comment thread pkg/kthena-router/datastore/store.go Outdated
Comment on lines +758 to +760
if parentRef.Group != nil && *parentRef.Group != gatewayv1.Group(gatewayAPIGroupName) {
return false
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

According to the Gateway API specification for ParentReference, the Group field defaults to gateway.networking.k8s.io when it is either unspecified (nil) or an empty string. The current implementation treats an explicit empty string as a non-Gateway group, which is incorrect. This logic should be updated to handle the empty string case as a default.

Suggested change
if parentRef.Group != nil && *parentRef.Group != gatewayv1.Group(gatewayAPIGroupName) {
return false
}
if parentRef.Group != nil && *parentRef.Group != "" && *parentRef.Group != gatewayv1.Group(gatewayAPIGroupName) {
return false
}

Comment on lines +755 to +770
const gatewayAPIGroupName = "gateway.networking.k8s.io"

func isGatewayParentRef(parentRef gatewayv1.ParentReference) bool {
if parentRef.Group != nil && *parentRef.Group != gatewayv1.Group(gatewayAPIGroupName) {
return false
}
return parentRef.Kind == nil || *parentRef.Kind == gatewayv1.Kind("Gateway")
}

func gatewayParentRefKey(defaultNamespace string, parentRef gatewayv1.ParentReference) string {
namespace := defaultNamespace
if parentRef.Namespace != nil {
namespace = string(*parentRef.Namespace)
}
return fmt.Sprintf("%s/%s", namespace, string(parentRef.Name))
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The constant gatewayAPIGroupName and the helper functions isGatewayParentRef and gatewayParentRefKey are duplicated between the controller and the datastore. To improve maintainability and ensure consistent behavior across the project, these should be defined in a single location (e.g., the datastore package or a common utils package) and shared.

_, err = gatewayClient.GatewayV1().HTTPRoutes(ns).Create(ctx, httpRoute, metav1.CreateOptions{})
assert.NoError(t, err)

serviceGroup := gatewayv1.Group("")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This test case uses Group("") to represent a non-Gateway parent reference. However, per the Gateway API specification, an empty string group in a ParentReference is inferred as gateway.networking.k8s.io. To correctly test a non-matching group, please use a different value (e.g., "core" or "example.com").

Suggested change
serviceGroup := gatewayv1.Group("")
serviceGroup := gatewayv1.Group("core")

func TestMatchModelServerIgnoresNonGatewayParentRef(t *testing.T) {
s := New()
weight := uint32(100)
serviceGroup := gatewayv1.Group("")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This test case uses Group("") to represent a non-Gateway parent reference. However, per the Gateway API specification, an empty string group in a ParentReference is inferred as gateway.networking.k8s.io. To correctly test a non-matching group, please use a different value (e.g., "core" or "example.com").

Suggested change
serviceGroup := gatewayv1.Group("")
serviceGroup := gatewayv1.Group("core")

Comment on lines +26 to +27

gatewayAPIGroupName = "gateway.networking.k8s.io"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

low priority, we already have these in yml

parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: default
namespace: kthena-system

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair, the examples already set them explicitly, so this is not urgent.

The reason I opened it is that Gateway API allows group and kind to be omitted and defaulted to gateway.networking.k8s.io / Gateway. So this is more about accepting valid user manifests, not fixing the current examples.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Signed-off-by: pm-ju <pmdevops29@gmail.com>
@pm-ju pm-ju force-pushed the fix-router-default-gateway-parentrefs branch from 8279242 to f628670 Compare May 19, 2026 12:50
Signed-off-by: pm-ju <pmdevops29@gmail.com>
Copilot AI review requested due to automatic review settings May 19, 2026 15:03
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Comment on lines +758 to +765
const gatewayAPIGroupName = "gateway.networking.k8s.io"

func isGatewayParentRef(parentRef gatewayv1.ParentReference) bool {
if parentRef.Group != nil && *parentRef.Group != "" && *parentRef.Group != gatewayv1.Group(gatewayAPIGroupName) {
return false
}
return parentRef.Kind == nil || *parentRef.Kind == "" || *parentRef.Kind == gatewayv1.Kind("Gateway")
}
Comment on lines +767 to +773
func gatewayParentRefKey(defaultNamespace string, parentRef gatewayv1.ParentReference) string {
namespace := defaultNamespace
if parentRef.Namespace != nil {
namespace = string(*parentRef.Namespace)
}
return fmt.Sprintf("%s/%s", namespace, string(parentRef.Name))
}
Comment on lines +234 to +240
func gatewayParentRefNamespaceAndKey(defaultNamespace string, parentRef gatewayv1.ParentReference) (string, string) {
namespace := defaultNamespace
if parentRef.Namespace != nil {
namespace = string(*parentRef.Namespace)
}
return namespace, fmt.Sprintf("%s/%s", namespace, string(parentRef.Name))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants