@@ -17,11 +17,14 @@ limitations under the License.
17
17
package v1alpha1
18
18
19
19
import (
20
+ "fmt"
21
+
20
22
promv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
21
23
autoscalingv2 "k8s.io/api/autoscaling/v2"
22
24
corev1 "k8s.io/api/core/v1"
23
25
networkingv1 "k8s.io/api/networking/v1"
24
26
"k8s.io/utils/ptr"
27
+ gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
25
28
)
26
29
27
30
const (
@@ -38,7 +41,39 @@ const (
38
41
// Expose defines attributes to expose the service.
39
42
type Expose struct {
40
43
Service Service `json:"service,omitempty"`
41
- Ingress Ingress `json:"ingress,omitempty"`
44
+ // Deprecated: Use .spec.router instead.
45
+ // Ingress Ingress `json:"ingress,omitempty"`
46
+ // Deprecated: Use .spec.router instead.
47
+ // HTTPRoute HTTPRoute `json:"httpRoute,omitempty"`
48
+ }
49
+
50
+ // +kubebuilder:validation:XValidation:rule="!(has(self.gateway) && has(self.ingressClass))", message="ingressClass and gateway cannot be specified together"
51
+ type Router struct {
52
+ // HostDomainName is the domain name of the hostname matched by the router.
53
+ // The hostname is constructed as "<nimServiceName>.<hostDomainName>", where the <nimServiceName> a subdomain of the matched hostname.
54
+ // eg. example.com for "<nimServiceName>.example.com"
55
+ // +kubebuilder:validation:MinLength=1
56
+ // +kubebuilder:validation:MaxLength=63
57
+ // +kubebuilder:validation:Pattern=`^(([a-z0-9][a-z0-9\-]*[a-z0-9])|[a-z0-9]+\.)*([a-z]+|xn\-\-[a-z0-9]+)\.?$`
58
+ HostDomainName string `json:"hostDomainName,omitempty"`
59
+
60
+ // Annotations for the router, e.g. for ingress class or gateway
61
+ Annotations map [string ]string `json:"annotations,omitempty"`
62
+
63
+ // IngressClass is the class of the ingress controller to use for the created ingress.
64
+ IngressClass * string `json:"ingressClass,omitempty"`
65
+
66
+ // Gateway is the gateway to use for the created HTTPRoute.
67
+ Gateway * Gateway `json:"gateway,omitempty"`
68
+ }
69
+
70
+ type Gateway struct {
71
+ // +kubebuilder:validation:MinLength=1
72
+ // Namespace of the gateway
73
+ Namespace string `json:"namespace"`
74
+ // +kubebuilder:validation:MinLength=1
75
+ // Name of the gateway
76
+ Name string `json:"name"`
42
77
}
43
78
44
79
// Service defines attributes to create a service.
@@ -67,12 +102,6 @@ type Service struct {
67
102
Annotations map [string ]string `json:"annotations,omitempty"`
68
103
}
69
104
70
- // ExposeV1 defines attributes to expose the service.
71
- type ExposeV1 struct {
72
- Service Service `json:"service,omitempty"`
73
- Ingress IngressV1 `json:"ingress,omitempty"`
74
- }
75
-
76
105
// Metrics defines attributes to setup metrics collection.
77
106
type Metrics struct {
78
107
Enabled * bool `json:"enabled,omitempty"`
@@ -119,6 +148,32 @@ type Ingress struct {
119
148
Spec networkingv1.IngressSpec `json:"spec,omitempty"`
120
149
}
121
150
151
+ // HTTPRoute defines attributes to HTTPRoute in Gateway API.
152
+ type HTTPRoute struct {
153
+ Enabled * bool `json:"enabled,omitempty"`
154
+ Annotations map [string ]string `json:"annotations,omitempty"`
155
+ Spec * HTTPRouteSpec `json:"spec,omitempty"`
156
+ }
157
+
158
+ type HTTPRouteSpec struct {
159
+ gatewayv1.CommonRouteSpec `json:",inline"`
160
+ Host gatewayv1.Hostname `json:"host,omitempty"`
161
+ Paths []HTTPPathMatch `json:"paths,omitempty"`
162
+ }
163
+
164
+ type HTTPPathMatch struct {
165
+ // Type specifies how to match against the path Value.
166
+ // +optional
167
+ // +kubebuilder:default=PathPrefix
168
+ Type * gatewayv1.PathMatchType `json:"type,omitempty"`
169
+
170
+ // Value of the HTTP path to match against.
171
+ // +optional
172
+ // +kubebuilder:default="/"
173
+ // +kubebuilder:validation:MaxLength=1024
174
+ Value * string `json:"value,omitempty"`
175
+ }
176
+
122
177
// IngressV1 defines attributes for ingress
123
178
//
124
179
// +kubebuilder:validation:XValidation:rule="(has(self.spec) && has(self.enabled) && self.enabled) || !has(self.enabled) || !self.enabled", message="spec cannot be nil when ingress is enabled"
@@ -142,46 +197,81 @@ type ResourceRequirements struct {
142
197
Requests corev1.ResourceList `json:"requests,omitempty" protobuf:"bytes,2,rep,name=requests,casttype=ResourceList,castkey=ResourceName"`
143
198
}
144
199
145
- func (i * IngressV1 ) GenerateNetworkingV1IngressSpec (name string ) networkingv1. IngressSpec {
146
- if i . Spec == nil {
147
- return networkingv1. IngressSpec {}
200
+ func (r * Router ) GenerateGatewayHTTPRouteSpec (name string ) gatewayv1. HTTPRouteSpec {
201
+ if r . Gateway == nil {
202
+ return gatewayv1. HTTPRouteSpec {}
148
203
}
149
204
150
- ingressSpec := networkingv1.IngressSpec {
151
- IngressClassName : & i .Spec .IngressClassName ,
152
- Rules : []networkingv1.IngressRule {
205
+ return gatewayv1.HTTPRouteSpec {
206
+ CommonRouteSpec : gatewayv1.CommonRouteSpec {
207
+ ParentRefs : []gatewayv1.ParentReference {
208
+ {
209
+ Name : gatewayv1 .ObjectName (r .Gateway .Name ),
210
+ Namespace : ptr .To (gatewayv1 .Namespace (r .Gateway .Namespace )),
211
+ },
212
+ },
213
+ },
214
+ Hostnames : []gatewayv1.Hostname {gatewayv1 .Hostname (r .getHostname (name ))},
215
+ Rules : []gatewayv1.HTTPRouteRule {
153
216
{
154
- Host : i .Spec .Host ,
155
- IngressRuleValue : networkingv1.IngressRuleValue {
156
- HTTP : & networkingv1.HTTPIngressRuleValue {},
217
+ BackendRefs : []gatewayv1.HTTPBackendRef {
218
+ {
219
+ BackendRef : gatewayv1.BackendRef {
220
+ BackendObjectReference : gatewayv1.BackendObjectReference {
221
+ Name : gatewayv1 .ObjectName (name ),
222
+ Port : ptr .To (gatewayv1 .PortNumber (DefaultAPIPort )),
223
+ },
224
+ },
225
+ },
226
+ },
227
+ Matches : []gatewayv1.HTTPRouteMatch {
228
+ {
229
+ Path : & gatewayv1.HTTPPathMatch {
230
+ Type : ptr .To (gatewayv1 .PathMatchPathPrefix ),
231
+ Value : ptr .To ("/" ),
232
+ },
233
+ },
157
234
},
158
235
},
159
236
},
160
237
}
238
+ }
161
239
162
- svcBackend := networkingv1.IngressBackend {
163
- Service : & networkingv1.IngressServiceBackend {
164
- Name : name ,
165
- Port : networkingv1.ServiceBackendPort {
166
- Name : DefaultNamedPortAPI ,
240
+ func (r * Router ) getHostname (name string ) string {
241
+ return fmt .Sprintf ("%s.%s" , name , r .HostDomainName )
242
+ }
243
+
244
+ func (r * Router ) GenerateIngressSpec (name string ) networkingv1.IngressSpec {
245
+ if r .IngressClass == nil {
246
+ return networkingv1.IngressSpec {}
247
+ }
248
+
249
+ return networkingv1.IngressSpec {
250
+ IngressClassName : r .IngressClass ,
251
+ Rules : []networkingv1.IngressRule {
252
+ {
253
+ Host : r .getHostname (name ),
254
+ IngressRuleValue : networkingv1.IngressRuleValue {
255
+ HTTP : & networkingv1.HTTPIngressRuleValue {
256
+ Paths : []networkingv1.HTTPIngressPath {
257
+ {
258
+ Path : "/" ,
259
+ PathType : ptr .To (networkingv1 .PathTypePrefix ),
260
+ Backend : networkingv1.IngressBackend {
261
+ Service : & networkingv1.IngressServiceBackend {
262
+ Name : name ,
263
+ Port : networkingv1.ServiceBackendPort {
264
+ Name : DefaultNamedPortAPI ,
265
+ },
266
+ },
267
+ },
268
+ },
269
+ },
270
+ },
271
+ },
167
272
},
168
273
},
169
274
}
170
- if len (i .Spec .Paths ) == 0 {
171
- ingressSpec .Rules [0 ].HTTP .Paths = append (ingressSpec .Rules [0 ].HTTP .Paths , networkingv1.HTTPIngressPath {
172
- Path : "/" ,
173
- PathType : ptr .To (networkingv1 .PathTypePrefix ),
174
- Backend : svcBackend ,
175
- })
176
- }
177
- for _ , path := range i .Spec .Paths {
178
- ingressSpec .Rules [0 ].HTTP .Paths = append (ingressSpec .Rules [0 ].HTTP .Paths , networkingv1.HTTPIngressPath {
179
- Path : path .Path ,
180
- PathType : path .PathType ,
181
- Backend : svcBackend ,
182
- })
183
- }
184
- return ingressSpec
185
275
}
186
276
187
277
type IngressSpec struct {
0 commit comments