Skip to content

Commit ec9b53a

Browse files
committed
Add SupportedFeatures to GatewayClassStatus
1 parent aa0f45c commit ec9b53a

File tree

7 files changed

+135
-5
lines changed

7 files changed

+135
-5
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package status
2+
3+
import (
4+
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
5+
)
6+
7+
// SupportedFeatures returns the list of features supported by NGINX Gateway Fabric.
8+
// The list must be sorted in ascending alphabetical order.
9+
func SupportedFeatures() []gatewayv1.SupportedFeature {
10+
return []gatewayv1.SupportedFeature{
11+
{Name: "BackendTLSPolicy"},
12+
{Name: "GatewayAddressEmpty"},
13+
{Name: "GatewayHTTPListenerIsolation"},
14+
{Name: "GatewayInfrastructurePropagation"},
15+
{Name: "GatewayPort8080"},
16+
{Name: "GatewayStaticAddresses"},
17+
{Name: "HTTPRouteBackendProtocolWebSocket"},
18+
{Name: "HTTPRouteDestinationPortMatching"},
19+
{Name: "HTTPRouteHostRewrite"},
20+
{Name: "HTTPRouteMethodMatching"},
21+
{Name: "HTTPRouteParentRefPort"},
22+
{Name: "HTTPRoutePathRedirect"},
23+
{Name: "HTTPRoutePathRewrite"},
24+
{Name: "HTTPRoutePortRedirect"},
25+
{Name: "HTTPRouteQueryParamMatching"},
26+
{Name: "HTTPRouteRequestMirror"},
27+
{Name: "HTTPRouteRequestMultipleMirrors"},
28+
{Name: "HTTPRouteRequestPercentageMirror"},
29+
{Name: "HTTPRouteResponseHeaderModification"},
30+
{Name: "HTTPRouteSchemeRedirect"},
31+
}
32+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package status
2+
3+
import (
4+
"slices"
5+
"testing"
6+
7+
. "github.com/onsi/gomega"
8+
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
9+
)
10+
11+
func TestSupportedFeatures(t *testing.T) {
12+
t.Parallel()
13+
g := NewWithT(t)
14+
15+
features := SupportedFeatures()
16+
17+
// Verify we have the expected features
18+
expectedFeatures := []gatewayv1.FeatureName{
19+
"BackendTLSPolicy",
20+
"GatewayAddressEmpty",
21+
"GatewayHTTPListenerIsolation",
22+
"GatewayInfrastructurePropagation",
23+
"GatewayPort8080",
24+
"GatewayStaticAddresses",
25+
"HTTPRouteBackendProtocolWebSocket",
26+
"HTTPRouteDestinationPortMatching",
27+
"HTTPRouteHostRewrite",
28+
"HTTPRouteMethodMatching",
29+
"HTTPRouteParentRefPort",
30+
"HTTPRoutePathRedirect",
31+
"HTTPRoutePathRewrite",
32+
"HTTPRoutePortRedirect",
33+
"HTTPRouteQueryParamMatching",
34+
"HTTPRouteRequestMirror",
35+
"HTTPRouteRequestMultipleMirrors",
36+
"HTTPRouteRequestPercentageMirror",
37+
"HTTPRouteResponseHeaderModification",
38+
"HTTPRouteSchemeRedirect",
39+
}
40+
41+
g.Expect(features).To(HaveLen(len(expectedFeatures)))
42+
43+
// Verify all expected features are present
44+
for _, expected := range expectedFeatures {
45+
g.Expect(slices.ContainsFunc(features, func(f gatewayv1.SupportedFeature) bool {
46+
return f.Name == expected
47+
})).To(BeTrue(), "expected feature %s not found", expected)
48+
}
49+
50+
// Verify the list is sorted alphabetically
51+
g.Expect(slices.IsSortedFunc(features, func(a, b gatewayv1.SupportedFeature) int {
52+
if a.Name < b.Name {
53+
return -1
54+
}
55+
if a.Name > b.Name {
56+
return 1
57+
}
58+
return 0
59+
})).To(BeTrue(), "features should be sorted alphabetically")
60+
}

internal/controller/status/prepare_requests.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,8 @@ func PrepareGatewayClassRequests(
210210
NsName: client.ObjectKeyFromObject(gc.Source),
211211
ResourceType: &v1.GatewayClass{},
212212
Setter: newGatewayClassStatusSetter(v1.GatewayClassStatus{
213-
Conditions: apiConds,
213+
Conditions: apiConds,
214+
SupportedFeatures: SupportedFeatures(),
214215
}),
215216
}
216217

@@ -227,6 +228,7 @@ func PrepareGatewayClassRequests(
227228
gwClass.Generation,
228229
transitionTime,
229230
),
231+
SupportedFeatures: SupportedFeatures(),
230232
}),
231233
}
232234

internal/controller/status/prepare_requests_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,7 @@ func TestBuildGatewayClassStatuses(t *testing.T) {
644644
Message: conditions.GatewayClassMessageGatewayClassConflict,
645645
},
646646
},
647+
SupportedFeatures: SupportedFeatures(),
647648
},
648649
{Name: "ignored-2"}: {
649650
Conditions: []metav1.Condition{
@@ -656,6 +657,7 @@ func TestBuildGatewayClassStatuses(t *testing.T) {
656657
Message: conditions.GatewayClassMessageGatewayClassConflict,
657658
},
658659
},
660+
SupportedFeatures: SupportedFeatures(),
659661
},
660662
},
661663
},
@@ -689,6 +691,7 @@ func TestBuildGatewayClassStatuses(t *testing.T) {
689691
Message: "The Gateway API CRD versions are supported",
690692
},
691693
},
694+
SupportedFeatures: SupportedFeatures(),
692695
},
693696
},
694697
},

internal/controller/status/status_setters.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func newGatewayStatusSetter(status gatewayv1.GatewayStatus) Setter {
4141

4242
func gwStatusEqual(prev, cur gatewayv1.GatewayStatus) bool {
4343
addressesEqual := slices.EqualFunc(prev.Addresses, cur.Addresses, func(a1, a2 gatewayv1.GatewayStatusAddress) bool {
44-
if !helpers.EqualPointers[gatewayv1.AddressType](a1.Type, a2.Type) {
44+
if !helpers.EqualPointers(a1.Type, a2.Type) {
4545
return false
4646
}
4747

@@ -217,7 +217,7 @@ func newGatewayClassStatusSetter(status gatewayv1.GatewayClassStatus) Setter {
217217
return func(obj client.Object) (wasSet bool) {
218218
gc := helpers.MustCastObject[*gatewayv1.GatewayClass](obj)
219219

220-
if ConditionsEqual(gc.Status.Conditions, status.Conditions) {
220+
if gcStatusEqual(gc.Status, status) {
221221
return false
222222
}
223223

@@ -226,6 +226,16 @@ func newGatewayClassStatusSetter(status gatewayv1.GatewayClassStatus) Setter {
226226
}
227227
}
228228

229+
func gcStatusEqual(prev, cur gatewayv1.GatewayClassStatus) bool {
230+
if !ConditionsEqual(prev.Conditions, cur.Conditions) {
231+
return false
232+
}
233+
234+
return slices.EqualFunc(prev.SupportedFeatures, cur.SupportedFeatures, func(f1, f2 gatewayv1.SupportedFeature) bool {
235+
return f1.Name == f2.Name
236+
})
237+
}
238+
229239
func newBackendTLSPolicyStatusSetter(
230240
status gatewayv1.PolicyStatus,
231241
gatewayCtlrName string,

internal/controller/status/status_setters_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,30 @@ func TestNewGatewayClassStatusSetter(t *testing.T) {
696696
},
697697
expStatusSet: false,
698698
},
699+
{
700+
name: "GatewayClass has same conditions but different SupportedFeatures",
701+
newStatus: gatewayv1.GatewayClassStatus{
702+
Conditions: []metav1.Condition{{Message: "same condition"}},
703+
SupportedFeatures: []gatewayv1.SupportedFeature{{Name: "Feature1"}},
704+
},
705+
status: gatewayv1.GatewayClassStatus{
706+
Conditions: []metav1.Condition{{Message: "same condition"}},
707+
SupportedFeatures: []gatewayv1.SupportedFeature{{Name: "Feature2"}},
708+
},
709+
expStatusSet: true,
710+
},
711+
{
712+
name: "GatewayClass has same conditions and same SupportedFeatures",
713+
newStatus: gatewayv1.GatewayClassStatus{
714+
Conditions: []metav1.Condition{{Message: "same condition"}},
715+
SupportedFeatures: []gatewayv1.SupportedFeature{{Name: "Feature1"}},
716+
},
717+
status: gatewayv1.GatewayClassStatus{
718+
Conditions: []metav1.Condition{{Message: "same condition"}},
719+
SupportedFeatures: []gatewayv1.SupportedFeature{{Name: "Feature1"}},
720+
},
721+
expStatusSet: false,
722+
},
699723
}
700724

701725
for _, test := range tests {

tests/Makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ GW_SERVICE_TYPE = NodePort## Service type to use for the gateway
1212
NGF_VERSION ?= edge## NGF version to be tested
1313
PULL_POLICY ?= Never## Pull policy for the images
1414
NGINX_CONF_DIR = internal/controller/nginx/conf
15-
SUPPORTED_EXTENDED_FEATURES = HTTPRouteQueryParamMatching,HTTPRouteMethodMatching,HTTPRoutePortRedirect,HTTPRouteSchemeRedirect,HTTPRouteHostRewrite,HTTPRoutePathRewrite,GatewayPort8080,GatewayAddressEmpty,HTTPRouteResponseHeaderModification,HTTPRoutePathRedirect,GatewayHTTPListenerIsolation,GatewayInfrastructurePropagation,HTTPRouteRequestMirror,HTTPRouteRequestMultipleMirrors,HTTPRouteRequestPercentageMirror,HTTPRouteBackendProtocolWebSocket,HTTPRouteParentRefPort,HTTPRouteDestinationPortMatching,GatewayStaticAddresses,BackendTLSPolicy
1615
SUPPORTED_EXTENDED_FEATURES_OPENSHIFT = HTTPRouteQueryParamMatching,HTTPRouteMethodMatching,HTTPRoutePortRedirect,HTTPRouteSchemeRedirect,HTTPRouteHostRewrite,HTTPRoutePathRewrite,GatewayPort8080,GatewayAddressEmpty,HTTPRouteResponseHeaderModification,HTTPRoutePathRedirect,GatewayHTTPListenerIsolation,GatewayInfrastructurePropagation,HTTPRouteRequestMirror,HTTPRouteRequestMultipleMirrors,HTTPRouteRequestPercentageMirror,HTTPRouteBackendProtocolWebSocket,HTTPRouteParentRefPort,HTTPRouteDestinationPortMatching
1716
STANDARD_CONFORMANCE_PROFILES = GATEWAY-HTTP,GATEWAY-GRPC
1817
EXPERIMENTAL_CONFORMANCE_PROFILES = GATEWAY-TLS
@@ -58,7 +57,7 @@ run-conformance-tests: ## Run conformance tests
5857
--image=$(CONFORMANCE_PREFIX):$(CONFORMANCE_TAG) --image-pull-policy=Never \
5958
--overrides='{ "spec": { "serviceAccountName": "conformance" } }' \
6059
--restart=Never -- sh -c "go test -v . -tags conformance,experimental -args --gateway-class=$(GATEWAY_CLASS) \
61-
--supported-features=$(SUPPORTED_EXTENDED_FEATURES) --version=$(NGF_VERSION) --skip-tests=$(SKIP_TESTS) --conformance-profiles=$(CONFORMANCE_PROFILES) \
60+
--version=$(NGF_VERSION) --skip-tests=$(SKIP_TESTS) --conformance-profiles=$(CONFORMANCE_PROFILES) \
6261
--report-output=output.txt; cat output.txt" | tee output.txt
6362
./scripts/check-pod-exit-code.sh conformance
6463
sed -e '1,/CONFORMANCE PROFILE/d' output.txt > conformance-profile.yaml

0 commit comments

Comments
 (0)