Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 42 additions & 102 deletions internal/adc/translator/annotations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ import (

"github.com/incubator4/go-resty-expr/expr"
"github.com/stretchr/testify/assert"
"k8s.io/utils/ptr"
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"

adctypes "github.com/apache/apisix-ingress-controller/api/adc"
"github.com/apache/apisix-ingress-controller/internal/adc/translator/annotations"
Expand Down Expand Up @@ -457,143 +455,85 @@ func TestAddServerPortVars(t *testing.T) {
}

func TestShouldInjectServerPortVars(t *testing.T) {
sectionName := gatewayv1.SectionName("http-main")
port := gatewayv1.PortNumber(9080)

// explicit is the provenance-aware signal the controller derives from the
// matched RouteParentRefContext (TranslateContext.HasExplicitListenerMatch);
// here we exercise how each mode consumes it together with the port count.
tests := []struct {
name string
mode config.ListenerPortMatchMode
parentRefs []gatewayv1.ParentReference
ports map[int32]struct{}
expected bool
name string
mode config.ListenerPortMatchMode
explicit bool
ports map[int32]struct{}
expected bool
}{
{
name: "empty listener ports",
mode: config.ListenerPortMatchModeAuto,
explicit: true,
ports: map[int32]struct{}{},
expected: false,
},
{
name: "single port without sectionName",
mode: config.ListenerPortMatchModeAuto,
parentRefs: []gatewayv1.ParentReference{
{Name: "gw"},
},
ports: map[int32]struct{}{
9080: {},
},
name: "auto mode: single port without explicit target",
mode: config.ListenerPortMatchModeAuto,
explicit: false,
ports: map[int32]struct{}{9080: {}},
expected: false,
},
{
name: "single port with sectionName",
mode: config.ListenerPortMatchModeAuto,
parentRefs: []gatewayv1.ParentReference{
{Name: "gw", SectionName: &sectionName},
},
ports: map[int32]struct{}{
9080: {},
},
name: "auto mode: single port with explicit target",
mode: config.ListenerPortMatchModeAuto,
explicit: true,
ports: map[int32]struct{}{9080: {}},
expected: true,
},
{
name: "multiple ports without sectionName",
mode: config.ListenerPortMatchModeAuto,
parentRefs: []gatewayv1.ParentReference{
{Name: "gw"},
},
ports: map[int32]struct{}{
9080: {},
9081: {},
},
name: "auto mode: multiple ports without explicit target",
mode: config.ListenerPortMatchModeAuto,
explicit: false,
ports: map[int32]struct{}{9080: {}, 9081: {}},
expected: true,
},
{
name: "explicit mode with multiple ports and no explicit target",
mode: config.ListenerPortMatchModeExplicit,
parentRefs: []gatewayv1.ParentReference{
{Name: "gw"},
},
ports: map[int32]struct{}{
9080: {},
9081: {},
},
name: "explicit mode: multiple ports without explicit target",
mode: config.ListenerPortMatchModeExplicit,
explicit: false,
ports: map[int32]struct{}{9080: {}, 9081: {}},
expected: false,
},
{
name: "explicit mode with parentRef.port",
mode: config.ListenerPortMatchModeExplicit,
parentRefs: []gatewayv1.ParentReference{
{Name: "gw", Port: &port},
},
ports: map[int32]struct{}{
9080: {},
},
name: "explicit mode: single port with explicit target",
mode: config.ListenerPortMatchModeExplicit,
explicit: true,
ports: map[int32]struct{}{9080: {}},
expected: true,
},
{
name: "explicit mode with single port and no explicit target",
mode: config.ListenerPortMatchModeExplicit,
parentRefs: []gatewayv1.ParentReference{
{Name: "gw"},
},
ports: map[int32]struct{}{
9080: {},
},
name: "explicit mode: single port without explicit target",
mode: config.ListenerPortMatchModeExplicit,
explicit: false,
ports: map[int32]struct{}{9080: {}},
expected: false,
},
{
name: "off mode ignores explicit target",
mode: config.ListenerPortMatchModeOff,
parentRefs: []gatewayv1.ParentReference{
{Name: "gw", SectionName: &sectionName},
},
ports: map[int32]struct{}{
9080: {},
9081: {},
},
name: "off mode: ignores explicit target with multiple ports",
mode: config.ListenerPortMatchModeOff,
explicit: true,
ports: map[int32]struct{}{9080: {}, 9081: {}},
expected: false,
},
{
name: "off mode ignores explicit parentRef.port target",
mode: config.ListenerPortMatchModeOff,
parentRefs: []gatewayv1.ParentReference{
{Name: "gw", Port: &port},
},
ports: map[int32]struct{}{
9080: {},
},
expected: false,
},
{
name: "explicit mode: non-Gateway parentRef with port is not treated as explicit target",
mode: config.ListenerPortMatchModeExplicit,
parentRefs: []gatewayv1.ParentReference{
{Name: "gw"},
{Name: "svc", Kind: ptr.To(gatewayv1.Kind("Service")), Port: &port},
},
ports: map[int32]struct{}{
9080: {},
},
expected: false,
},
{
name: "auto mode: non-Gateway parentRef with port does not trigger single-port injection",
mode: config.ListenerPortMatchModeAuto,
parentRefs: []gatewayv1.ParentReference{
{Name: "gw"},
{Name: "svc", Kind: ptr.To(gatewayv1.Kind("Service")), Port: &port},
},
ports: map[int32]struct{}{
9080: {},
},
name: "off mode: ignores explicit target with single port",
mode: config.ListenerPortMatchModeOff,
explicit: true,
ports: map[int32]struct{}{9080: {}},
expected: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
translator := &Translator{ListenerPortMatchMode: tt.mode}
assert.Equal(t, tt.expected, translator.shouldInjectServerPortVars(tt.parentRefs, tt.ports))
assert.Equal(t, tt.expected, translator.shouldInjectServerPortVars(tt.explicit, tt.ports))
})
}
}
2 changes: 1 addition & 1 deletion internal/adc/translator/grpcroute.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ func (t *Translator) TranslateGRPCRoute(tctx *provider.TranslateContext, grpcRou
listenerPorts[listener.Port] = struct{}{}
}

if t.shouldInjectServerPortVars(tctx.RouteParentRefs, listenerPorts) {
if t.shouldInjectServerPortVars(tctx.HasExplicitListenerMatch, listenerPorts) {
for _, route := range routes {
addServerPortVars(route, listenerPorts)
}
Expand Down
105 changes: 24 additions & 81 deletions internal/adc/translator/grpcroute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ import (
)

func TestTranslateGRPCRouteServerPortVarsByMode(t *testing.T) {
sectionName := gatewayv1.SectionName("grpc-main")
parentPort := gatewayv1.PortNumber(9080)

singlePortVars := adctypes.Vars{
{
{StrVal: "server_port"},
Expand All @@ -52,40 +49,27 @@ func TestTranslateGRPCRouteServerPortVarsByMode(t *testing.T) {
}

tests := []struct {
name string
mode config.ListenerPortMatchMode
parentRefs []gatewayv1.ParentReference
listeners []gatewayv1.Listener
expected adctypes.Vars
name string
mode config.ListenerPortMatchMode
// explicit is the provenance-aware signal the controller stores on tctx
// (HasExplicitListenerMatch); the cross-Gateway sectionName/port
// resolution that computes it is covered by the controller tests.
explicit bool
listeners []gatewayv1.Listener
expected adctypes.Vars
}{
{
name: "auto mode: no injection for single listener without explicit target",
mode: config.ListenerPortMatchModeAuto,
parentRefs: []gatewayv1.ParentReference{
{Name: "gw"},
},
listeners: []gatewayv1.Listener{
{Name: "grpc-main", Protocol: gatewayv1.HTTPProtocolType, Port: gatewayv1.PortNumber(9080)},
},
expected: nil,
},
{
name: "auto mode: inject for sectionName target",
mode: config.ListenerPortMatchModeAuto,
parentRefs: []gatewayv1.ParentReference{
{Name: "gw", SectionName: &sectionName},
},
listeners: []gatewayv1.Listener{
{Name: "grpc-main", Protocol: gatewayv1.HTTPProtocolType, Port: gatewayv1.PortNumber(9080)},
},
expected: singlePortVars,
},
{
name: "auto mode: inject for port target",
mode: config.ListenerPortMatchModeAuto,
parentRefs: []gatewayv1.ParentReference{
{Name: "gw", Port: &parentPort},
},
name: "auto mode: inject for explicit sectionName target",
mode: config.ListenerPortMatchModeAuto,
explicit: true,
listeners: []gatewayv1.Listener{
{Name: "grpc-main", Protocol: gatewayv1.HTTPProtocolType, Port: gatewayv1.PortNumber(9080)},
},
Expand All @@ -94,45 +78,16 @@ func TestTranslateGRPCRouteServerPortVarsByMode(t *testing.T) {
{
name: "auto mode: inject for multiple listener ports",
mode: config.ListenerPortMatchModeAuto,
parentRefs: []gatewayv1.ParentReference{
{Name: "gw"},
},
listeners: []gatewayv1.Listener{
{Name: "grpc-main", Protocol: gatewayv1.HTTPProtocolType, Port: gatewayv1.PortNumber(9081)},
{Name: "grpc-alt", Protocol: gatewayv1.HTTPProtocolType, Port: gatewayv1.PortNumber(9080)},
},
expected: multiPortVars,
},
{
name: "auto mode: inject for multiple listener ports when listener names collide across gateways",
mode: config.ListenerPortMatchModeAuto,
parentRefs: []gatewayv1.ParentReference{
{Name: "gw-a"},
{Name: "gw-b"},
},
listeners: []gatewayv1.Listener{
{Name: "http", Protocol: gatewayv1.HTTPProtocolType, Port: gatewayv1.PortNumber(9081)},
{Name: "http", Protocol: gatewayv1.HTTPProtocolType, Port: gatewayv1.PortNumber(9080)},
},
expected: multiPortVars,
},
{
name: "explicit mode: inject for sectionName target",
mode: config.ListenerPortMatchModeExplicit,
parentRefs: []gatewayv1.ParentReference{
{Name: "gw", SectionName: &sectionName},
},
listeners: []gatewayv1.Listener{
{Name: "grpc-main", Protocol: gatewayv1.HTTPProtocolType, Port: gatewayv1.PortNumber(9080)},
},
expected: singlePortVars,
},
{
name: "explicit mode: inject for port target",
mode: config.ListenerPortMatchModeExplicit,
parentRefs: []gatewayv1.ParentReference{
{Name: "gw", Port: &parentPort},
},
name: "explicit mode: inject for explicit target",
mode: config.ListenerPortMatchModeExplicit,
explicit: true,
listeners: []gatewayv1.Listener{
{Name: "grpc-main", Protocol: gatewayv1.HTTPProtocolType, Port: gatewayv1.PortNumber(9080)},
},
Expand All @@ -141,21 +96,16 @@ func TestTranslateGRPCRouteServerPortVarsByMode(t *testing.T) {
{
name: "explicit mode: no injection for multiple listener ports without explicit target",
mode: config.ListenerPortMatchModeExplicit,
parentRefs: []gatewayv1.ParentReference{
{Name: "gw"},
},
listeners: []gatewayv1.Listener{
{Name: "grpc-main", Protocol: gatewayv1.HTTPProtocolType, Port: gatewayv1.PortNumber(9081)},
{Name: "grpc-alt", Protocol: gatewayv1.HTTPProtocolType, Port: gatewayv1.PortNumber(9080)},
},
expected: nil,
},
{
name: "off mode: no injection even with sectionName target",
mode: config.ListenerPortMatchModeOff,
parentRefs: []gatewayv1.ParentReference{
{Name: "gw", SectionName: &sectionName},
},
name: "off mode: no injection even with explicit target",
mode: config.ListenerPortMatchModeOff,
explicit: true,
listeners: []gatewayv1.Listener{
{Name: "grpc-main", Protocol: gatewayv1.HTTPProtocolType, Port: gatewayv1.PortNumber(9080)},
},
Expand All @@ -164,32 +114,25 @@ func TestTranslateGRPCRouteServerPortVarsByMode(t *testing.T) {
{
name: "off mode: no injection for multiple listener ports",
mode: config.ListenerPortMatchModeOff,
parentRefs: []gatewayv1.ParentReference{
{Name: "gw"},
},
listeners: []gatewayv1.Listener{
{Name: "grpc-main", Protocol: gatewayv1.HTTPProtocolType, Port: gatewayv1.PortNumber(9081)},
{Name: "grpc-alt", Protocol: gatewayv1.HTTPProtocolType, Port: gatewayv1.PortNumber(9080)},
},
expected: nil,
},
{
name: "empty mode normalizes to off",
mode: "",
parentRefs: []gatewayv1.ParentReference{
{Name: "gw", Port: &parentPort},
},
name: "empty mode normalizes to off",
mode: "",
explicit: true,
listeners: []gatewayv1.Listener{
{Name: "grpc-main", Protocol: gatewayv1.HTTPProtocolType, Port: gatewayv1.PortNumber(9080)},
},
expected: nil,
},
{
name: "unknown mode normalizes to off",
mode: "bogus",
parentRefs: []gatewayv1.ParentReference{
{Name: "gw", SectionName: &sectionName},
},
name: "unknown mode normalizes to off",
mode: "bogus",
explicit: true,
listeners: []gatewayv1.Listener{
{Name: "grpc-main", Protocol: gatewayv1.HTTPProtocolType, Port: gatewayv1.PortNumber(9080)},
},
Expand All @@ -200,7 +143,7 @@ func TestTranslateGRPCRouteServerPortVarsByMode(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tctx := provider.NewDefaultTranslateContext(context.Background())
tctx.RouteParentRefs = tt.parentRefs
tctx.HasExplicitListenerMatch = tt.explicit
tctx.Listeners = tt.listeners

grpcRoute := &gatewayv1.GRPCRoute{
Expand Down
2 changes: 1 addition & 1 deletion internal/adc/translator/httproute.go
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,7 @@ func (t *Translator) TranslateHTTPRoute(tctx *provider.TranslateContext, httpRou

// Add server_port matching only when a route explicitly targets a listener
// or when multiple listener ports need to be disambiguated.
if t.shouldInjectServerPortVars(tctx.RouteParentRefs, listenerPorts) {
if t.shouldInjectServerPortVars(tctx.HasExplicitListenerMatch, listenerPorts) {
for _, route := range routes {
addServerPortVars(route, listenerPorts)
}
Expand Down
Loading
Loading