generated from kubernetes/kubernetes-template-project
-
Notifications
You must be signed in to change notification settings - Fork 498
/
Copy pathgateway.go
93 lines (79 loc) · 3.42 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
/*
Copyright 2021 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package validation
import (
"fmt"
"k8s.io/apimachinery/pkg/util/validation/field"
gatewayv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1"
)
var (
// set of protocols for which we need to validate that hostname is empty
protocolsHostnameInvalid = map[gatewayv1b1.ProtocolType]struct{}{
gatewayv1b1.TCPProtocolType: {},
gatewayv1b1.UDPProtocolType: {},
}
// set of protocols for which TLSConfig shall not be present
protocolsTLSInvalid = map[gatewayv1b1.ProtocolType]struct{}{
gatewayv1b1.HTTPProtocolType: {},
gatewayv1b1.UDPProtocolType: {},
gatewayv1b1.TCPProtocolType: {},
}
)
// ValidateGateway validates gw according to the Gateway API specification.
// For additional details of the Gateway spec, refer to:
// https://gateway-api.sigs.k8s.io/v1beta1/references/spec/#gateway.networking.k8s.io/v1beta1.Gateway
//
// Validation that is not possible with CRD annotations may be added here in the future.
// See https://github.com/kubernetes-sigs/gateway-api/issues/868 for more information.
func ValidateGateway(gw *gatewayv1b1.Gateway) field.ErrorList {
return validateGatewaySpec(&gw.Spec, field.NewPath("spec"))
}
// validateGatewaySpec validates whether required fields of spec are set according to the
// Gateway API specification.
func validateGatewaySpec(spec *gatewayv1b1.GatewaySpec, path *field.Path) field.ErrorList {
var errs field.ErrorList
errs = append(errs, validateGatewayListeners(spec.Listeners, path.Child("listeners"))...)
return errs
}
// validateGatewayListeners validates whether required fields of listeners are set according
// to the Gateway API specification.
func validateGatewayListeners(listeners []gatewayv1b1.Listener, path *field.Path) field.ErrorList {
var errs field.ErrorList
errs = append(errs, validateListenerTLSConfig(listeners, path)...)
errs = append(errs, validateListenerHostname(listeners, path)...)
return errs
}
func validateListenerTLSConfig(listeners []gatewayv1b1.Listener, path *field.Path) field.ErrorList {
var errs field.ErrorList
for i, l := range listeners {
if isProtocolInSubset(l.Protocol, protocolsTLSInvalid) && l.TLS != nil {
errs = append(errs, field.Forbidden(path.Index(i).Child("tls"), fmt.Sprintf("should be empty for protocol %v", l.Protocol)))
}
}
return errs
}
func isProtocolInSubset(protocol gatewayv1b1.ProtocolType, set map[gatewayv1b1.ProtocolType]struct{}) bool {
_, ok := set[protocol]
return ok
}
// validateListenerHostname validates each listener hostname
// should be empty in case protocol is TCP or UDP
func validateListenerHostname(listeners []gatewayv1b1.Listener, path *field.Path) field.ErrorList {
var errs field.ErrorList
for i, h := range listeners {
if isProtocolInSubset(h.Protocol, protocolsHostnameInvalid) && h.Hostname != nil {
errs = append(errs, field.Forbidden(path.Index(i).Child("hostname"), fmt.Sprintf("should be empty for protocol %v", h.Protocol)))
}
}
return errs
}