-
Notifications
You must be signed in to change notification settings - Fork 2.8k
/
helpers.go
161 lines (137 loc) · 4.43 KB
/
helpers.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium
package gateway_api
import (
"context"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
"github.com/cilium/cilium/operator/pkg/model"
)
const (
kindGateway = "Gateway"
kindHTTPRoute = "HTTPRoute"
kindTLSRoute = "TLSRoute"
kindUDPRoute = "UDPRoute"
kindTCPRoute = "TCPRoute"
kindService = "Service"
kindSecret = "Secret"
)
func IsGateway(parent gatewayv1beta1.ParentReference) bool {
return (parent.Kind == nil || *parent.Kind == kindGateway) && (parent.Group == nil || *parent.Group == gatewayv1beta1.GroupName)
}
func IsService(be gatewayv1beta1.BackendObjectReference) bool {
return (be.Kind == nil || *be.Kind == kindService) && (be.Group == nil || *be.Group == corev1.GroupName)
}
func IsSecret(secret gatewayv1beta1.SecretObjectReference) bool {
return (secret.Kind == nil || *secret.Kind == kindSecret) && (secret.Group == nil || *secret.Group == corev1.GroupName)
}
func GatewayAddressTypePtr(addr gatewayv1beta1.AddressType) *gatewayv1beta1.AddressType {
return &addr
}
func GroupPtr(name string) *gatewayv1beta1.Group {
group := gatewayv1beta1.Group(name)
return &group
}
func KindPtr(name string) *gatewayv1beta1.Kind {
kind := gatewayv1beta1.Kind(name)
return &kind
}
func namespaceDerefOr(namespace *gatewayv1beta1.Namespace, defaultNamespace string) string {
if namespace != nil && *namespace != "" {
return string(*namespace)
}
return defaultNamespace
}
// isAllowed returns true if the provided HTTPRoute is allowed to attach to given gateway
func isAllowed(ctx context.Context, c client.Client, gw *gatewayv1beta1.Gateway, hr *gatewayv1beta1.HTTPRoute) bool {
for _, listener := range gw.Spec.Listeners {
// all routes in the same namespace are allowed for this listener
if listener.AllowedRoutes == nil || listener.AllowedRoutes.Namespaces == nil {
return hr.GetNamespace() == gw.GetNamespace()
}
// check if route is kind-allowed
if !isKindAllowed(listener) {
continue
}
// check if route is namespace-allowed
switch *listener.AllowedRoutes.Namespaces.From {
case gatewayv1beta1.NamespacesFromAll:
return true
case gatewayv1beta1.NamespacesFromSame:
if hr.GetNamespace() == gw.GetNamespace() {
return true
}
case gatewayv1beta1.NamespacesFromSelector:
nsList := &corev1.NamespaceList{}
selector, _ := metav1.LabelSelectorAsSelector(listener.AllowedRoutes.Namespaces.Selector)
if err := c.List(ctx, nsList, client.MatchingLabelsSelector{Selector: selector}); err != nil {
log.WithError(err).Error("Unable to list namespaces")
return false
}
for _, ns := range nsList.Items {
if ns.Name == hr.GetNamespace() {
return true
}
}
}
}
return false
}
func isKindAllowed(listener gatewayv1beta1.Listener) bool {
if listener.AllowedRoutes.Kinds == nil {
return true
}
for _, kind := range listener.AllowedRoutes.Kinds {
if (kind.Group == nil || string(*kind.Group) == gatewayv1beta1.GroupName) &&
kind.Kind == kindHTTPRoute {
return true
}
}
return false
}
func computeHosts(gw *gatewayv1beta1.Gateway, hr *gatewayv1beta1.HTTPRoute) []string {
hosts := make([]string, 0, len(hr.Spec.Hostnames))
for _, listener := range gw.Spec.Listeners {
hosts = append(hosts, model.ComputeHosts(toStringSlice(hr.Spec.Hostnames), (*string)(listener.Hostname))...)
}
return hosts
}
func toStringSlice(s []gatewayv1beta1.Hostname) []string {
res := make([]string, 0, len(s))
for _, h := range s {
res = append(res, string(h))
}
return res
}
func getSupportedKind(protocol gatewayv1beta1.ProtocolType) gatewayv1beta1.Kind {
switch protocol {
case gatewayv1beta1.TLSProtocolType:
return kindTLSRoute
case gatewayv1beta1.HTTPSProtocolType:
return kindHTTPRoute
case gatewayv1beta1.HTTPProtocolType:
return kindHTTPRoute
case gatewayv1beta1.TCPProtocolType:
return kindTCPRoute
case gatewayv1beta1.UDPProtocolType:
return kindUDPRoute
default:
return "Unknown"
}
}
func mergeMap(left, right map[string]string) map[string]string {
if left == nil {
return right
} else {
for key, value := range right {
left[key] = value
}
}
return left
}
func setMergedLabelsAndAnnotations(temp, desired client.Object) {
temp.SetAnnotations(mergeMap(temp.GetAnnotations(), desired.GetAnnotations()))
temp.SetLabels(mergeMap(temp.GetLabels(), desired.GetLabels()))
}