@@ -17,11 +17,14 @@ limitations under the License.
1717package v1alpha1
1818
1919import (
20+ "fmt"
21+
2022 promv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
2123 autoscalingv2 "k8s.io/api/autoscaling/v2"
2224 corev1 "k8s.io/api/core/v1"
2325 networkingv1 "k8s.io/api/networking/v1"
2426 "k8s.io/utils/ptr"
27+ gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
2528)
2629
2730const (
@@ -38,9 +41,58 @@ const (
3841// Expose defines attributes to expose the service.
3942type Expose struct {
4043 Service Service `json:"service,omitempty"`
44+ // Deprecated: Use .spec.router instead.
4145 Ingress Ingress `json:"ingress,omitempty"`
4246}
4347
48+ // +kubebuilder:validation:XValidation:rule="!(has(self.gateway) && has(self.ingress))", message="ingress and gateway cannot be specified together"
49+ type Router struct {
50+ // HostDomainName is the domain name of the hostname matched by the router.
51+ // The hostname is constructed as "<nimServiceName>.<namespace>.<hostDomainName>", where the <nimServiceName> a subdomain of the matched hostname.
52+ // eg. example.com for "<nimServiceName>.<namespace>.example.com"
53+ // +kubebuilder:validation:MinLength=1
54+ // +kubebuilder:validation:MaxLength=63
55+ // +kubebuilder:validation:Pattern=`^(([a-z0-9][a-z0-9\-]*[a-z0-9])|[a-z0-9]+\.)*([a-z]+|xn\-\-[a-z0-9]+)\.?$`
56+ HostDomainName string `json:"hostDomainName,omitempty"`
57+
58+ // Annotations for the router, e.g. for ingress class or gateway
59+ Annotations map [string ]string `json:"annotations,omitempty"`
60+
61+ // Ingress is the ingress controller to use for the created ingress.
62+ Ingress * RouterIngress `json:"ingress,omitempty"`
63+
64+ // Gateway is the gateway to use for the created HTTPRoute.
65+ Gateway * Gateway `json:"gateway,omitempty"`
66+ }
67+
68+ type RouterIngress struct {
69+ // +kubebuilder:validation:MinLength=1
70+ // IngressClass is the ingress class to use for the created ingress.
71+ IngressClass string `json:"ingressClass"`
72+
73+ // TLSSecretName is the name of the secret containing the TLS certificate and key.
74+ TLSSecretName string `json:"tlsSecretName,omitempty"`
75+ }
76+
77+ type Gateway struct {
78+ // +kubebuilder:validation:MinLength=1
79+ // Namespace of the gateway
80+ Namespace string `json:"namespace"`
81+ // +kubebuilder:validation:MinLength=1
82+ // Name of the gateway
83+ Name string `json:"name"`
84+
85+ // +kubebuilder:default:=true
86+ // HTTPRoutesEnabled is a flag to enable HTTPRoutes for the created gateway.
87+ HTTPRoutesEnabled bool `json:"httpRoutesEnabled,omitempty"`
88+ }
89+
90+ // DEPRECATED ExposeV1 defines attributes to expose the service.
91+ type ExposeV1 struct {
92+ Service Service `json:"service,omitempty"`
93+ Ingress IngressV1 `json:"ingress,omitempty"`
94+ }
95+
4496// Service defines attributes to create a service.
4597type Service struct {
4698 Type corev1.ServiceType `json:"type,omitempty"`
@@ -67,10 +119,13 @@ type Service struct {
67119 Annotations map [string ]string `json:"annotations,omitempty"`
68120}
69121
70- // ExposeV1 defines attributes to expose the service.
71- type ExposeV1 struct {
72- Service Service `json:"service,omitempty"`
73- Ingress IngressV1 `json:"ingress,omitempty"`
122+ // Deprecated: Use .spec.router.ingress instead.
123+ // IngressV1 defines attributes for ingress
124+ // +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"
125+ type IngressV1 struct {
126+ Enabled * bool `json:"enabled,omitempty"`
127+ Annotations map [string ]string `json:"annotations,omitempty"`
128+ Spec * IngressSpec `json:"spec,omitempty"`
74129}
75130
76131// Metrics defines attributes to setup metrics collection.
@@ -119,15 +174,6 @@ type Ingress struct {
119174 Spec networkingv1.IngressSpec `json:"spec,omitempty"`
120175}
121176
122- // IngressV1 defines attributes for ingress
123- //
124- // +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"
125- type IngressV1 struct {
126- Enabled * bool `json:"enabled,omitempty"`
127- Annotations map [string ]string `json:"annotations,omitempty"`
128- Spec * IngressSpec `json:"spec,omitempty"`
129- }
130-
131177// ResourceRequirements defines the resources required for a container.
132178type ResourceRequirements struct {
133179 // Limits describes the maximum amount of compute resources allowed.
@@ -184,6 +230,100 @@ func (i *IngressV1) GenerateNetworkingV1IngressSpec(name string) networkingv1.In
184230 return ingressSpec
185231}
186232
233+ func (r * Router ) GenerateGatewayHTTPRouteSpec (namespace , name string , port int32 ) gatewayv1.HTTPRouteSpec {
234+ if r .Gateway == nil || ! r .Gateway .HTTPRoutesEnabled {
235+ return gatewayv1.HTTPRouteSpec {}
236+ }
237+
238+ return gatewayv1.HTTPRouteSpec {
239+ CommonRouteSpec : gatewayv1.CommonRouteSpec {
240+ ParentRefs : []gatewayv1.ParentReference {
241+ {
242+ Name : gatewayv1 .ObjectName (r .Gateway .Name ),
243+ Namespace : ptr .To (gatewayv1 .Namespace (r .Gateway .Namespace )),
244+ },
245+ },
246+ },
247+ Hostnames : []gatewayv1.Hostname {gatewayv1 .Hostname (r .getHostname (namespace , name ))},
248+ Rules : []gatewayv1.HTTPRouteRule {
249+ {
250+ BackendRefs : []gatewayv1.HTTPBackendRef {
251+ {
252+ BackendRef : gatewayv1.BackendRef {
253+ BackendObjectReference : gatewayv1.BackendObjectReference {
254+ Name : gatewayv1 .ObjectName (name ),
255+ Port : ptr .To (gatewayv1 .PortNumber (port )),
256+ },
257+ },
258+ },
259+ },
260+ Matches : []gatewayv1.HTTPRouteMatch {
261+ {
262+ Path : & gatewayv1.HTTPPathMatch {
263+ Type : ptr .To (gatewayv1 .PathMatchPathPrefix ),
264+ Value : ptr .To ("/" ),
265+ },
266+ },
267+ },
268+ },
269+ },
270+ }
271+ }
272+
273+ func (r * Router ) getHostname (namespace , name string ) string {
274+ return fmt .Sprintf ("%s.%s.%s" , name , namespace , r .HostDomainName )
275+ }
276+
277+ func (r * Router ) GenerateIngressSpec (namespace , name string ) networkingv1.IngressSpec {
278+ if r .Ingress == nil {
279+ return networkingv1.IngressSpec {}
280+ }
281+
282+ ingressSpec := networkingv1.IngressSpec {
283+ IngressClassName : ptr .To (r .Ingress .IngressClass ),
284+ Rules : []networkingv1.IngressRule {
285+ {
286+ Host : r .getHostname (namespace , name ),
287+ IngressRuleValue : networkingv1.IngressRuleValue {
288+ HTTP : & networkingv1.HTTPIngressRuleValue {
289+ Paths : []networkingv1.HTTPIngressPath {
290+ {
291+ Path : "/" ,
292+ PathType : ptr .To (networkingv1 .PathTypePrefix ),
293+ Backend : networkingv1.IngressBackend {
294+ Service : & networkingv1.IngressServiceBackend {
295+ Name : name ,
296+ Port : networkingv1.ServiceBackendPort {
297+ Name : DefaultNamedPortAPI ,
298+ },
299+ },
300+ },
301+ },
302+ },
303+ },
304+ },
305+ },
306+ },
307+ }
308+
309+ if r .Ingress .TLSSecretName != "" {
310+ ingressSpec .TLS = []networkingv1.IngressTLS {
311+ {
312+ Hosts : []string {r .getHostname (namespace , name )},
313+ SecretName : r .Ingress .TLSSecretName ,
314+ },
315+ }
316+ }
317+ return ingressSpec
318+ }
319+
320+ func (r * Expose ) GenerateIngressSpec (name string ) networkingv1.IngressSpec {
321+ if r .Ingress .Enabled == nil || ! * r .Ingress .Enabled {
322+ return networkingv1.IngressSpec {}
323+ }
324+ return r .Ingress .Spec
325+ }
326+
187327type IngressSpec struct {
188328 // +kubebuilder:validation:Pattern=`[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*`
189329 IngressClassName string `json:"ingressClassName"`
0 commit comments