-
Notifications
You must be signed in to change notification settings - Fork 297
/
infra.go
233 lines (196 loc) · 5.97 KB
/
infra.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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
// Copyright Envoy Gateway Authors
// SPDX-License-Identifier: Apache-2.0
// The full text of the Apache license is available in the LICENSE file at
// the root of the repo.
package ir
import (
"errors"
"fmt"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"github.com/envoyproxy/gateway/api/config/v1alpha1"
)
const (
DefaultProxyName = "default"
DefaultProxyImage = "envoyproxy/envoy-dev:latest"
)
// Infra defines managed infrastructure.
// +k8s:deepcopy-gen=true
type Infra struct {
// Proxy defines managed proxy infrastructure.
Proxy *ProxyInfra
}
// ProxyInfra defines managed proxy infrastructure.
// +k8s:deepcopy-gen=true
type ProxyInfra struct {
// Metadata defines metadata for the managed proxy infrastructure.
Metadata *InfraMetadata
// Name is the name used for managed proxy infrastructure.
Name string
// Config defines user-facing configuration of the managed proxy infrastructure.
Config *v1alpha1.EnvoyProxy
// Image is the container image used for the managed proxy infrastructure.
// If unset, defaults to "envoyproxy/envoy-dev:latest".
Image string
// Listeners define the listeners exposed by the proxy infrastructure.
Listeners []ProxyListener
}
// InfraMetadata defines metadata for the managed proxy infrastructure.
// +k8s:deepcopy-gen=true
type InfraMetadata struct {
// Labels define a map of string keys and values that can be used to organize
// and categorize proxy infrastructure objects.
Labels map[string]string
}
// ProxyListener defines the listener configuration of the proxy infrastructure.
// +k8s:deepcopy-gen=true
type ProxyListener struct {
// Address is the address that the listener should listen on.
Address string
// Ports define network ports of the listener.
Ports []ListenerPort
}
// ListenerPort defines a network port of a listener.
// +k8s:deepcopy-gen=true
type ListenerPort struct {
// Name is the name of the listener port.
Name string
// Protocol is the protocol that the listener port will listener for.
Protocol ProtocolType
// ServicePort is the port number the proxy service is listening on.
ServicePort int32
// ContainerPort is the port number the proxy container is listening on.
ContainerPort int32
}
// ProtocolType defines the application protocol accepted by a ListenerPort.
//
// Valid values include "HTTP" and "HTTPS".
type ProtocolType string
const (
// HTTPProtocolType accepts cleartext HTTP/1.1 sessions over TCP or HTTP/2
// over cleartext.
HTTPProtocolType ProtocolType = "HTTP"
// HTTPSProtocolType accepts HTTP/1.1 or HTTP/2 sessions over TLS.
HTTPSProtocolType ProtocolType = "HTTPS"
// TLSProtocolType accepts TLS sessions over TCP.
TLSProtocolType ProtocolType = "TLS"
// TCPProtocolType accepts TCP connection.
TCPProtocolType ProtocolType = "TCP"
// UDPProtocolType accepts UDP connection.
UDPProtocolType ProtocolType = "UDP"
)
// NewInfra returns a new Infra with default parameters.
func NewInfra() *Infra {
return &Infra{
Proxy: NewProxyInfra(),
}
}
// NewProxyInfra returns a new ProxyInfra with default parameters.
func NewProxyInfra() *ProxyInfra {
return &ProxyInfra{
Metadata: NewInfraMetadata(),
Name: DefaultProxyName,
Image: DefaultProxyImage,
Listeners: NewProxyListeners(),
}
}
// NewProxyListeners returns a new slice of ProxyListener with default parameters.
func NewProxyListeners() []ProxyListener {
return []ProxyListener{
{
Ports: nil,
},
}
}
// NewInfraMetadata returns a new InfraMetadata.
func NewInfraMetadata() *InfraMetadata {
return &InfraMetadata{
Labels: map[string]string{},
}
}
// GetProxyInfra returns the ProxyInfra.
func (i *Infra) GetProxyInfra() *ProxyInfra {
if i.Proxy == nil {
i.Proxy = NewProxyInfra()
return i.Proxy
}
if len(i.Proxy.Name) == 0 {
i.Proxy.Name = DefaultProxyName
}
if len(i.Proxy.Image) == 0 {
i.Proxy.Image = DefaultProxyImage
}
if len(i.Proxy.Listeners) == 0 {
i.Proxy.Listeners = NewProxyListeners()
}
if i.Proxy.Metadata == nil {
i.Proxy.Metadata = NewInfraMetadata()
}
return i.Proxy
}
// GetProxyMetadata returns the InfraMetadata.
func (p *ProxyInfra) GetProxyMetadata() *InfraMetadata {
if p.Metadata == nil {
p.Metadata = NewInfraMetadata()
}
return p.Metadata
}
// GetProxyConfig returns the ProxyInfra config.
func (p *ProxyInfra) GetProxyConfig() *v1alpha1.EnvoyProxy {
if p.Config == nil {
p.Config = new(v1alpha1.EnvoyProxy)
}
return p.Config
}
// Validate validates the provided Infra.
func (i *Infra) Validate() error {
if i == nil {
return errors.New("infra ir is nil")
}
var errs []error
if i.Proxy != nil {
if err := i.Proxy.Validate(); err != nil {
errs = append(errs, err)
}
}
return utilerrors.NewAggregate(errs)
}
// Validate validates the provided ProxyInfra.
func (p *ProxyInfra) Validate() error {
var errs []error
if len(p.Name) == 0 {
errs = append(errs, errors.New("name field required"))
}
if len(p.Image) == 0 {
errs = append(errs, errors.New("image field required"))
}
if len(p.Listeners) > 1 {
errs = append(errs, errors.New("no more than 1 listener is supported"))
}
if len(p.Listeners) > 0 {
for i := range p.Listeners {
listener := p.Listeners[i]
if len(listener.Ports) == 0 {
errs = append(errs, errors.New("listener ports field required"))
}
for j := range listener.Ports {
if len(listener.Ports[j].Name) == 0 {
errs = append(errs, errors.New("listener name field required"))
}
if listener.Ports[j].ServicePort < 1 || listener.Ports[j].ServicePort > 65353 {
errs = append(errs, errors.New("listener service port must be a valid port number"))
}
if listener.Ports[j].ContainerPort < 1024 || listener.Ports[j].ContainerPort > 65353 {
errs = append(errs, errors.New("listener container port must be a valid ephemeral port number"))
}
}
}
}
return utilerrors.NewAggregate(errs)
}
// ObjectName returns the name of the proxy infrastructure object.
func (p *ProxyInfra) ObjectName() string {
if len(p.Name) == 0 {
return fmt.Sprintf("envoy-%s", DefaultProxyName)
}
return "envoy-" + p.Name
}