Skip to content

Commit 918d650

Browse files
authored
Fix HTTPRoute section name related bugs (#568)
- Previously, NKG assumed section names in parentRefs of HTTPRoute were unique, even when they referenced different Gateways. This commit fixes that. Fixes #484 - Previously, when NKG reported status for a parentRef with an empty section name, it would give the ref the name "unattached" in the HTTPRoute status. This behavior is not Gateway API spec compliant -- the API prescribe to use empty section name in that case. Now NKG will use empty section name. See the corresponding FIXME in the code https://github.com/nginxinc/nginx-kubernetes-gateway/blob/b594695bb42a79653eb8217a6dfd00c6d9594d5b/internal/state/statuses.go#L151 Note: the FIXME advice is wrong. - Previously, in case of multiple parentRefs in an HTTPRoute, when reporting their statuses in the HTTPRoute status, NKG could change the order of the refs in the status. This commit restores the order. See the corresponding FIXME in the code https://github.com/nginxinc/nginx-kubernetes-gateway/blob/b594695bb42a79653eb8217a6dfd00c6d9594d5b/internal/status/httproute.go#L25
1 parent 0f472ec commit 918d650

11 files changed

+462
-435
lines changed

internal/state/change_processor_test.go

+82-44
Original file line numberDiff line numberDiff line change
@@ -335,14 +335,18 @@ var _ = Describe("ChangeProcessor", func() {
335335
HTTPRouteStatuses: map[types.NamespacedName]state.HTTPRouteStatus{
336336
{Namespace: "test", Name: "hr-1"}: {
337337
ObservedGeneration: hr1.Generation,
338-
ParentStatuses: map[string]state.ParentStatus{
339-
"listener-80-1": {
338+
ParentStatuses: []state.ParentStatus{
339+
{
340+
GatewayNsName: client.ObjectKeyFromObject(gw1),
341+
SectionName: helpers.GetPointer[v1beta1.SectionName]("listener-80-1"),
340342
Conditions: append(
341343
conditions.NewDefaultRouteConditions(),
342344
conditions.NewTODO("GatewayClass is invalid or doesn't exist"),
343345
),
344346
},
345-
"listener-443-1": {
347+
{
348+
GatewayNsName: client.ObjectKeyFromObject(gw1),
349+
SectionName: helpers.GetPointer[v1beta1.SectionName]("listener-443-1"),
346350
Conditions: append(
347351
conditions.NewDefaultRouteConditions(),
348352
conditions.NewTODO("GatewayClass is invalid or doesn't exist"),
@@ -440,12 +444,16 @@ var _ = Describe("ChangeProcessor", func() {
440444
HTTPRouteStatuses: map[types.NamespacedName]state.HTTPRouteStatus{
441445
{Namespace: "test", Name: "hr-1"}: {
442446
ObservedGeneration: hr1.Generation,
443-
ParentStatuses: map[string]state.ParentStatus{
444-
"listener-80-1": {
445-
Conditions: conditions.NewDefaultRouteConditions(),
447+
ParentStatuses: []state.ParentStatus{
448+
{
449+
GatewayNsName: client.ObjectKeyFromObject(gw1),
450+
SectionName: helpers.GetPointer[v1beta1.SectionName]("listener-80-1"),
451+
Conditions: conditions.NewDefaultRouteConditions(),
446452
},
447-
"listener-443-1": {
448-
Conditions: conditions.NewDefaultRouteConditions(),
453+
{
454+
GatewayNsName: client.ObjectKeyFromObject(gw1),
455+
SectionName: helpers.GetPointer[v1beta1.SectionName]("listener-443-1"),
456+
Conditions: conditions.NewDefaultRouteConditions(),
449457
},
450458
},
451459
},
@@ -549,12 +557,16 @@ var _ = Describe("ChangeProcessor", func() {
549557
HTTPRouteStatuses: map[types.NamespacedName]state.HTTPRouteStatus{
550558
{Namespace: "test", Name: "hr-1"}: {
551559
ObservedGeneration: hr1Updated.Generation,
552-
ParentStatuses: map[string]state.ParentStatus{
553-
"listener-80-1": {
554-
Conditions: conditions.NewDefaultRouteConditions(),
560+
ParentStatuses: []state.ParentStatus{
561+
{
562+
GatewayNsName: client.ObjectKeyFromObject(gw1),
563+
SectionName: helpers.GetPointer[v1beta1.SectionName]("listener-80-1"),
564+
Conditions: conditions.NewDefaultRouteConditions(),
555565
},
556-
"listener-443-1": {
557-
Conditions: conditions.NewDefaultRouteConditions(),
566+
{
567+
GatewayNsName: client.ObjectKeyFromObject(gw1),
568+
SectionName: helpers.GetPointer[v1beta1.SectionName]("listener-443-1"),
569+
Conditions: conditions.NewDefaultRouteConditions(),
558570
},
559571
},
560572
},
@@ -659,12 +671,16 @@ var _ = Describe("ChangeProcessor", func() {
659671
HTTPRouteStatuses: map[types.NamespacedName]state.HTTPRouteStatus{
660672
{Namespace: "test", Name: "hr-1"}: {
661673
ObservedGeneration: hr1Updated.Generation,
662-
ParentStatuses: map[string]state.ParentStatus{
663-
"listener-80-1": {
664-
Conditions: conditions.NewDefaultRouteConditions(),
674+
ParentStatuses: []state.ParentStatus{
675+
{
676+
GatewayNsName: client.ObjectKeyFromObject(gw1Updated),
677+
SectionName: helpers.GetPointer[v1beta1.SectionName]("listener-80-1"),
678+
Conditions: conditions.NewDefaultRouteConditions(),
665679
},
666-
"listener-443-1": {
667-
Conditions: conditions.NewDefaultRouteConditions(),
680+
{
681+
GatewayNsName: client.ObjectKeyFromObject(gw1Updated),
682+
SectionName: helpers.GetPointer[v1beta1.SectionName]("listener-443-1"),
683+
Conditions: conditions.NewDefaultRouteConditions(),
668684
},
669685
},
670686
},
@@ -768,12 +784,16 @@ var _ = Describe("ChangeProcessor", func() {
768784
HTTPRouteStatuses: map[types.NamespacedName]state.HTTPRouteStatus{
769785
{Namespace: "test", Name: "hr-1"}: {
770786
ObservedGeneration: hr1Updated.Generation,
771-
ParentStatuses: map[string]state.ParentStatus{
772-
"listener-80-1": {
773-
Conditions: conditions.NewDefaultRouteConditions(),
787+
ParentStatuses: []state.ParentStatus{
788+
{
789+
GatewayNsName: client.ObjectKeyFromObject(gw1Updated),
790+
SectionName: helpers.GetPointer[v1beta1.SectionName]("listener-80-1"),
791+
Conditions: conditions.NewDefaultRouteConditions(),
774792
},
775-
"listener-443-1": {
776-
Conditions: conditions.NewDefaultRouteConditions(),
793+
{
794+
GatewayNsName: client.ObjectKeyFromObject(gw1Updated),
795+
SectionName: helpers.GetPointer[v1beta1.SectionName]("listener-443-1"),
796+
Conditions: conditions.NewDefaultRouteConditions(),
777797
},
778798
},
779799
},
@@ -880,12 +900,16 @@ var _ = Describe("ChangeProcessor", func() {
880900
HTTPRouteStatuses: map[types.NamespacedName]state.HTTPRouteStatus{
881901
{Namespace: "test", Name: "hr-1"}: {
882902
ObservedGeneration: hr1Updated.Generation,
883-
ParentStatuses: map[string]state.ParentStatus{
884-
"listener-80-1": {
885-
Conditions: conditions.NewDefaultRouteConditions(),
903+
ParentStatuses: []state.ParentStatus{
904+
{
905+
GatewayNsName: client.ObjectKeyFromObject(gw1Updated),
906+
SectionName: helpers.GetPointer[v1beta1.SectionName]("listener-80-1"),
907+
Conditions: conditions.NewDefaultRouteConditions(),
886908
},
887-
"listener-443-1": {
888-
Conditions: conditions.NewDefaultRouteConditions(),
909+
{
910+
GatewayNsName: client.ObjectKeyFromObject(gw1Updated),
911+
SectionName: helpers.GetPointer[v1beta1.SectionName]("listener-443-1"),
912+
Conditions: conditions.NewDefaultRouteConditions(),
889913
},
890914
},
891915
},
@@ -981,25 +1005,33 @@ var _ = Describe("ChangeProcessor", func() {
9811005
HTTPRouteStatuses: map[types.NamespacedName]state.HTTPRouteStatus{
9821006
{Namespace: "test", Name: "hr-1"}: {
9831007
ObservedGeneration: hr1Updated.Generation,
984-
ParentStatuses: map[string]state.ParentStatus{
985-
"listener-80-1": {
986-
Conditions: conditions.NewDefaultRouteConditions(),
1008+
ParentStatuses: []state.ParentStatus{
1009+
{
1010+
GatewayNsName: client.ObjectKeyFromObject(gw1Updated),
1011+
SectionName: helpers.GetPointer[v1beta1.SectionName]("listener-80-1"),
1012+
Conditions: conditions.NewDefaultRouteConditions(),
9871013
},
988-
"listener-443-1": {
989-
Conditions: conditions.NewDefaultRouteConditions(),
1014+
{
1015+
GatewayNsName: client.ObjectKeyFromObject(gw1Updated),
1016+
SectionName: helpers.GetPointer[v1beta1.SectionName]("listener-443-1"),
1017+
Conditions: conditions.NewDefaultRouteConditions(),
9901018
},
9911019
},
9921020
},
9931021
{Namespace: "test", Name: "hr-2"}: {
9941022
ObservedGeneration: hr2.Generation,
995-
ParentStatuses: map[string]state.ParentStatus{
996-
"listener-80-1": {
1023+
ParentStatuses: []state.ParentStatus{
1024+
{
1025+
GatewayNsName: client.ObjectKeyFromObject(gw2),
1026+
SectionName: helpers.GetPointer[v1beta1.SectionName]("listener-80-1"),
9971027
Conditions: append(
9981028
conditions.NewDefaultRouteConditions(),
9991029
conditions.NewTODO("Gateway is ignored"),
10001030
),
10011031
},
1002-
"listener-443-1": {
1032+
{
1033+
GatewayNsName: client.ObjectKeyFromObject(gw2),
1034+
SectionName: helpers.GetPointer[v1beta1.SectionName]("listener-443-1"),
10031035
Conditions: append(
10041036
conditions.NewDefaultRouteConditions(),
10051037
conditions.NewTODO("Gateway is ignored"),
@@ -1098,12 +1130,16 @@ var _ = Describe("ChangeProcessor", func() {
10981130
HTTPRouteStatuses: map[types.NamespacedName]state.HTTPRouteStatus{
10991131
{Namespace: "test", Name: "hr-2"}: {
11001132
ObservedGeneration: hr2.Generation,
1101-
ParentStatuses: map[string]state.ParentStatus{
1102-
"listener-80-1": {
1103-
Conditions: conditions.NewDefaultRouteConditions(),
1133+
ParentStatuses: []state.ParentStatus{
1134+
{
1135+
GatewayNsName: client.ObjectKeyFromObject(gw2),
1136+
SectionName: helpers.GetPointer[v1beta1.SectionName]("listener-80-1"),
1137+
Conditions: conditions.NewDefaultRouteConditions(),
11041138
},
1105-
"listener-443-1": {
1106-
Conditions: conditions.NewDefaultRouteConditions(),
1139+
{
1140+
GatewayNsName: client.ObjectKeyFromObject(gw2),
1141+
SectionName: helpers.GetPointer[v1beta1.SectionName]("listener-443-1"),
1142+
Conditions: conditions.NewDefaultRouteConditions(),
11071143
},
11081144
},
11091145
},
@@ -2102,9 +2138,11 @@ var _ = Describe("ChangeProcessor", func() {
21022138
HTTPRouteStatuses: map[types.NamespacedName]state.HTTPRouteStatus{
21032139
hrNsName: {
21042140
ObservedGeneration: hr.Generation,
2105-
ParentStatuses: map[string]state.ParentStatus{
2106-
"listener-80-1": {
2107-
Conditions: conditions.NewDefaultRouteConditions(),
2141+
ParentStatuses: []state.ParentStatus{
2142+
{
2143+
GatewayNsName: gwNsName,
2144+
SectionName: helpers.GetPointer[v1beta1.SectionName]("listener-80-1"),
2145+
Conditions: conditions.NewDefaultRouteConditions(),
21082146
},
21092147
},
21102148
},

internal/state/graph/backend_refs_test.go

+33-33
Original file line numberDiff line numberDiff line change
@@ -309,11 +309,11 @@ func TestAddBackendGroupsToRouteTest(t *testing.T) {
309309
return rules
310310
}
311311

312-
const sectionName = "test"
313-
sectionNameRefs := map[string]ParentRef{
314-
sectionName: {
315-
Idx: 0,
316-
Gateway: types.NamespacedName{Namespace: "test", Name: "gateway"},
312+
sectionNameRefs := []ParentRef{
313+
{
314+
Idx: 0,
315+
Gateway: types.NamespacedName{Namespace: "test", Name: "gateway"},
316+
Attached: true,
317317
},
318318
}
319319

@@ -337,10 +337,10 @@ func TestAddBackendGroupsToRouteTest(t *testing.T) {
337337
}{
338338
{
339339
route: &Route{
340-
Source: hrWithOneBackend,
341-
SectionNameRefs: sectionNameRefs,
342-
Valid: true,
343-
Rules: createRules(hrWithOneBackend, allValid, allValid),
340+
Source: hrWithOneBackend,
341+
ParentRefs: sectionNameRefs,
342+
Valid: true,
343+
Rules: createRules(hrWithOneBackend, allValid, allValid),
344344
},
345345
expectedBackendGroups: []BackendGroup{
346346
{
@@ -362,10 +362,10 @@ func TestAddBackendGroupsToRouteTest(t *testing.T) {
362362
},
363363
{
364364
route: &Route{
365-
Source: hrWithTwoBackends,
366-
SectionNameRefs: sectionNameRefs,
367-
Valid: true,
368-
Rules: createRules(hrWithTwoBackends, allValid, allValid),
365+
Source: hrWithTwoBackends,
366+
ParentRefs: sectionNameRefs,
367+
Valid: true,
368+
Rules: createRules(hrWithTwoBackends, allValid, allValid),
369369
},
370370
expectedBackendGroups: []BackendGroup{
371371
{
@@ -394,42 +394,42 @@ func TestAddBackendGroupsToRouteTest(t *testing.T) {
394394
},
395395
{
396396
route: &Route{
397-
Source: hrWithOneBackend,
398-
SectionNameRefs: sectionNameRefs,
399-
Valid: false,
397+
Source: hrWithOneBackend,
398+
ParentRefs: sectionNameRefs,
399+
Valid: false,
400400
},
401401
expectedBackendGroups: nil,
402402
expectedConditions: nil,
403403
name: "invalid route",
404404
},
405405
{
406406
route: &Route{
407-
Source: hrWithOneBackend,
408-
SectionNameRefs: sectionNameRefs,
409-
Valid: true,
410-
Rules: createRules(hrWithOneBackend, allInvalid, allValid),
407+
Source: hrWithOneBackend,
408+
ParentRefs: sectionNameRefs,
409+
Valid: true,
410+
Rules: createRules(hrWithOneBackend, allInvalid, allValid),
411411
},
412412
expectedBackendGroups: nil,
413413
expectedConditions: nil,
414414
name: "invalid matches",
415415
},
416416
{
417417
route: &Route{
418-
Source: hrWithOneBackend,
419-
SectionNameRefs: sectionNameRefs,
420-
Valid: true,
421-
Rules: createRules(hrWithOneBackend, allValid, allInvalid),
418+
Source: hrWithOneBackend,
419+
ParentRefs: sectionNameRefs,
420+
Valid: true,
421+
Rules: createRules(hrWithOneBackend, allValid, allInvalid),
422422
},
423423
expectedBackendGroups: nil,
424424
expectedConditions: nil,
425425
name: "invalid filters",
426426
},
427427
{
428428
route: &Route{
429-
Source: hrWithInvalidRule,
430-
SectionNameRefs: sectionNameRefs,
431-
Valid: true,
432-
Rules: createRules(hrWithInvalidRule, allValid, allValid),
429+
Source: hrWithInvalidRule,
430+
ParentRefs: sectionNameRefs,
431+
Valid: true,
432+
Rules: createRules(hrWithInvalidRule, allValid, allValid),
433433
},
434434
expectedBackendGroups: []BackendGroup{
435435
{
@@ -451,10 +451,10 @@ func TestAddBackendGroupsToRouteTest(t *testing.T) {
451451
},
452452
{
453453
route: &Route{
454-
Source: hrWithZeroBackendRefs,
455-
SectionNameRefs: sectionNameRefs,
456-
Valid: true,
457-
Rules: createRules(hrWithZeroBackendRefs, allValid, allValid),
454+
Source: hrWithZeroBackendRefs,
455+
ParentRefs: sectionNameRefs,
456+
Valid: true,
457+
Rules: createRules(hrWithZeroBackendRefs, allValid, allValid),
458458
},
459459
expectedBackendGroups: []BackendGroup{
460460
{
@@ -474,7 +474,7 @@ func TestAddBackendGroupsToRouteTest(t *testing.T) {
474474
addBackendGroupsToRoute(test.route, services)
475475

476476
g.Expect(helpers.Diff(test.expectedBackendGroups, test.route.GetAllBackendGroups())).To(BeEmpty())
477-
g.Expect(test.route.GetAllConditionsForSectionName(sectionName)).To(Equal(test.expectedConditions))
477+
g.Expect(test.route.Conditions).To(Equal(test.expectedConditions))
478478
})
479479
}
480480
}

internal/state/graph/graph_test.go

+12-13
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"sigs.k8s.io/gateway-api/apis/v1beta1"
1313

1414
"github.com/nginxinc/nginx-kubernetes-gateway/internal/helpers"
15-
"github.com/nginxinc/nginx-kubernetes-gateway/internal/state/conditions"
1615
"github.com/nginxinc/nginx-kubernetes-gateway/internal/state/secrets/secretsfakes"
1716
"github.com/nginxinc/nginx-kubernetes-gateway/internal/state/validation"
1817
"github.com/nginxinc/nginx-kubernetes-gateway/internal/state/validation/validationfakes"
@@ -179,27 +178,27 @@ func TestBuildGraph(t *testing.T) {
179178
routeHR1 := &Route{
180179
Valid: true,
181180
Source: hr1,
182-
SectionNameRefs: map[string]ParentRef{
183-
"listener-80-1": {
184-
Idx: 0,
185-
Gateway: client.ObjectKeyFromObject(gw1),
181+
ParentRefs: []ParentRef{
182+
{
183+
Idx: 0,
184+
Gateway: client.ObjectKeyFromObject(gw1),
185+
Attached: true,
186186
},
187187
},
188-
UnattachedSectionNameRefs: map[string]conditions.Condition{},
189-
Rules: []Rule{createValidRuleWithBackendGroup(hr1Group)},
188+
Rules: []Rule{createValidRuleWithBackendGroup(hr1Group)},
190189
}
191190

192191
routeHR3 := &Route{
193192
Valid: true,
194193
Source: hr3,
195-
SectionNameRefs: map[string]ParentRef{
196-
"listener-443-1": {
197-
Idx: 0,
198-
Gateway: client.ObjectKeyFromObject(gw1),
194+
ParentRefs: []ParentRef{
195+
{
196+
Idx: 0,
197+
Gateway: client.ObjectKeyFromObject(gw1),
198+
Attached: true,
199199
},
200200
},
201-
UnattachedSectionNameRefs: map[string]conditions.Condition{},
202-
Rules: []Rule{createValidRuleWithBackendGroup(hr3Group)},
201+
Rules: []Rule{createValidRuleWithBackendGroup(hr3Group)},
203202
}
204203

205204
secretMemoryMgr := &secretsfakes.FakeSecretDiskMemoryManager{}

0 commit comments

Comments
 (0)