-
Notifications
You must be signed in to change notification settings - Fork 107
/
Copy pathgateway.go
138 lines (111 loc) · 3.45 KB
/
gateway.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package graph
import (
"sort"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/validation/field"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/gateway-api/apis/v1beta1"
"github.com/nginxinc/nginx-gateway-fabric/internal/framework/conditions"
ngfsort "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/sort"
staticConds "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/conditions"
)
// Gateway represents the winning Gateway resource.
type Gateway struct {
// Source is the corresponding Gateway resource.
Source *v1beta1.Gateway
// Listeners include the listeners of the Gateway.
Listeners map[string]*Listener
// Conditions holds the conditions for the Gateway.
Conditions []conditions.Condition
// Valid indicates whether the Gateway Spec is valid.
Valid bool
}
// processedGateways holds the resources that belong to NGF.
type processedGateways struct {
Winner *v1beta1.Gateway
Ignored map[types.NamespacedName]*v1beta1.Gateway
}
// GetAllNsNames returns all the NamespacedNames of the Gateway resources that belong to NGF
func (gws processedGateways) GetAllNsNames() []types.NamespacedName {
winnerCnt := 0
if gws.Winner != nil {
winnerCnt = 1
}
length := winnerCnt + len(gws.Ignored)
if length == 0 {
return nil
}
allNsNames := make([]types.NamespacedName, 0, length)
if gws.Winner != nil {
allNsNames = append(allNsNames, client.ObjectKeyFromObject(gws.Winner))
}
for nsName := range gws.Ignored {
allNsNames = append(allNsNames, nsName)
}
return allNsNames
}
// processGateways determines which Gateway resource belong to NGF (determined by the Gateway GatewayClassName field).
func processGateways(
gws map[types.NamespacedName]*v1beta1.Gateway,
gcName string,
) processedGateways {
referencedGws := make([]*v1beta1.Gateway, 0, len(gws))
for _, gw := range gws {
if string(gw.Spec.GatewayClassName) != gcName {
continue
}
referencedGws = append(referencedGws, gw)
}
if len(referencedGws) == 0 {
return processedGateways{}
}
sort.Slice(referencedGws, func(i, j int) bool {
return ngfsort.LessObjectMeta(&referencedGws[i].ObjectMeta, &referencedGws[j].ObjectMeta)
})
ignoredGws := make(map[types.NamespacedName]*v1beta1.Gateway)
for _, gw := range referencedGws[1:] {
ignoredGws[client.ObjectKeyFromObject(gw)] = gw
}
return processedGateways{
Winner: referencedGws[0],
Ignored: ignoredGws,
}
}
func buildGateway(
gw *v1beta1.Gateway,
secretResolver *secretResolver,
gc *GatewayClass,
refGrantResolver *referenceGrantResolver,
protectedPorts ProtectedPorts,
) *Gateway {
if gw == nil {
return nil
}
conds := validateGateway(gw, gc)
if len(conds) > 0 {
return &Gateway{
Source: gw,
Valid: false,
Conditions: conds,
}
}
return &Gateway{
Source: gw,
Listeners: buildListeners(gw, secretResolver, refGrantResolver, protectedPorts),
Valid: true,
}
}
func validateGateway(gw *v1beta1.Gateway, gc *GatewayClass) []conditions.Condition {
var conds []conditions.Condition
if gc == nil {
conds = append(conds, staticConds.NewGatewayInvalid("GatewayClass doesn't exist")...)
} else if !gc.Valid {
conds = append(conds, staticConds.NewGatewayInvalid("GatewayClass is invalid")...)
}
if len(gw.Spec.Addresses) > 0 {
path := field.NewPath("spec", "addresses")
valErr := field.Forbidden(path, "addresses are not supported")
conds = append(conds, staticConds.NewGatewayUnsupportedValue(valErr.Error())...)
}
return conds
}