1 /* 2 Copyright 2020 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package v1 18 19 import ( 20 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 ) 22 23 // +genclient 24 // +kubebuilder:object:root=true 25 // +kubebuilder:resource:categories=gateway-api,shortName=gtw 26 // +kubebuilder:subresource:status 27 // +kubebuilder:printcolumn:name="Class",type=string,JSONPath=`.spec.gatewayClassName` 28 // +kubebuilder:printcolumn:name="Address",type=string,JSONPath=`.status.addresses[*].value` 29 // +kubebuilder:printcolumn:name="Programmed",type=string,JSONPath=`.status.conditions[?(@.type=="Programmed")].status` 30 // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` 31 32 // Gateway represents an instance of a service-traffic handling infrastructure 33 // by binding Listeners to a set of IP addresses. 34 type Gateway struct { 35 metav1.TypeMeta `json:",inline"` 36 metav1.ObjectMeta `json:"metadata,omitempty"` 37 38 // Spec defines the desired state of Gateway. 39 Spec GatewaySpec `json:"spec"` 40 41 // Status defines the current state of Gateway. 42 // 43 // +kubebuilder:default={conditions: {{type: "Accepted", status: "Unknown", reason:"Pending", message:"Waiting for controller", lastTransitionTime: "1970-01-01T00:00:00Z"},{type: "Programmed", status: "Unknown", reason:"Pending", message:"Waiting for controller", lastTransitionTime: "1970-01-01T00:00:00Z"}}} 44 Status GatewayStatus `json:"status,omitempty"` 45 } 46 47 // +kubebuilder:object:root=true 48 49 // GatewayList contains a list of Gateways. 50 type GatewayList struct { 51 metav1.TypeMeta `json:",inline"` 52 metav1.ListMeta `json:"metadata,omitempty"` 53 Items []Gateway `json:"items"` 54 } 55 56 // GatewaySpec defines the desired state of Gateway. 57 // 58 // Not all possible combinations of options specified in the Spec are 59 // valid. Some invalid configurations can be caught synchronously via a 60 // webhook, but there are many cases that will require asynchronous 61 // signaling via the GatewayStatus block. 62 type GatewaySpec struct { 63 // GatewayClassName used for this Gateway. This is the name of a 64 // GatewayClass resource. 65 GatewayClassName ObjectName `json:"gatewayClassName"` 66 67 // Listeners associated with this Gateway. Listeners define 68 // logical endpoints that are bound on this Gateway's addresses. 69 // At least one Listener MUST be specified. 70 // 71 // Each Listener in a set of Listeners (for example, in a single Gateway) 72 // MUST be _distinct_, in that a traffic flow MUST be able to be assigned to 73 // exactly one listener. (This section uses "set of Listeners" rather than 74 // "Listeners in a single Gateway" because implementations MAY merge configuration 75 // from multiple Gateways onto a single data plane, and these rules _also_ 76 // apply in that case). 77 // 78 // Practically, this means that each listener in a set MUST have a unique 79 // combination of Port, Protocol, and, if supported by the protocol, Hostname. 80 // 81 // Some combinations of port, protocol, and TLS settings are considered 82 // Core support and MUST be supported by implementations based on their 83 // targeted conformance profile: 84 // 85 // HTTP Profile 86 // 87 // 1. HTTPRoute, Port: 80, Protocol: HTTP 88 // 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate, TLS keypair provided 89 // 90 // TLS Profile 91 // 92 // 1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough 93 // 94 // "Distinct" Listeners have the following property: 95 // 96 // The implementation can match inbound requests to a single distinct 97 // Listener. When multiple Listeners share values for fields (for 98 // example, two Listeners with the same Port value), the implementation 99 // can match requests to only one of the Listeners using other 100 // Listener fields. 101 // 102 // For example, the following Listener scenarios are distinct: 103 // 104 // 1. Multiple Listeners with the same Port that all use the "HTTP" 105 // Protocol that all have unique Hostname values. 106 // 2. Multiple Listeners with the same Port that use either the "HTTPS" or 107 // "TLS" Protocol that all have unique Hostname values. 108 // 3. A mixture of "TCP" and "UDP" Protocol Listeners, where no Listener 109 // with the same Protocol has the same Port value. 110 // 111 // Some fields in the Listener struct have possible values that affect 112 // whether the Listener is distinct. Hostname is particularly relevant 113 // for HTTP or HTTPS protocols. 114 // 115 // When using the Hostname value to select between same-Port, same-Protocol 116 // Listeners, the Hostname value must be different on each Listener for the 117 // Listener to be distinct. 118 // 119 // When the Listeners are distinct based on Hostname, inbound request 120 // hostnames MUST match from the most specific to least specific Hostname 121 // values to choose the correct Listener and its associated set of Routes. 122 // 123 // Exact matches must be processed before wildcard matches, and wildcard 124 // matches must be processed before fallback (empty Hostname value) 125 // matches. For example, `"foo.example.com"` takes precedence over 126 // `"*.example.com"`, and `"*.example.com"` takes precedence over `""`. 127 // 128 // Additionally, if there are multiple wildcard entries, more specific 129 // wildcard entries must be processed before less specific wildcard entries. 130 // For example, `"*.foo.example.com"` takes precedence over `"*.example.com"`. 131 // The precise definition here is that the higher the number of dots in the 132 // hostname to the right of the wildcard character, the higher the precedence. 133 // 134 // The wildcard character will match any number of characters _and dots_ to 135 // the left, however, so `"*.example.com"` will match both 136 // `"foo.bar.example.com"` _and_ `"bar.example.com"`. 137 // 138 // If a set of Listeners contains Listeners that are not distinct, then those 139 // Listeners are Conflicted, and the implementation MUST set the "Conflicted" 140 // condition in the Listener Status to "True". 141 // 142 // Implementations MAY choose to accept a Gateway with some Conflicted 143 // Listeners only if they only accept the partial Listener set that contains 144 // no Conflicted Listeners. To put this another way, implementations may 145 // accept a partial Listener set only if they throw out *all* the conflicting 146 // Listeners. No picking one of the conflicting listeners as the winner. 147 // This also means that the Gateway must have at least one non-conflicting 148 // Listener in this case, otherwise it violates the requirement that at 149 // least one Listener must be present. 150 // 151 // The implementation MUST set a "ListenersNotValid" condition on the 152 // Gateway Status when the Gateway contains Conflicted Listeners whether or 153 // not they accept the Gateway. That Condition SHOULD clearly 154 // indicate in the Message which Listeners are conflicted, and which are 155 // Accepted. Additionally, the Listener status for those listeners SHOULD 156 // indicate which Listeners are conflicted and not Accepted. 157 // 158 // A Gateway's Listeners are considered "compatible" if: 159 // 160 // 1. They are distinct. 161 // 2. The implementation can serve them in compliance with the Addresses 162 // requirement that all Listeners are available on all assigned 163 // addresses. 164 // 165 // Compatible combinations in Extended support are expected to vary across 166 // implementations. A combination that is compatible for one implementation 167 // may not be compatible for another. 168 // 169 // For example, an implementation that cannot serve both TCP and UDP listeners 170 // on the same address, or cannot mix HTTPS and generic TLS listens on the same port 171 // would not consider those cases compatible, even though they are distinct. 172 // 173 // Note that requests SHOULD match at most one Listener. For example, if 174 // Listeners are defined for "foo.example.com" and "*.example.com", a 175 // request to "foo.example.com" SHOULD only be routed using routes attached 176 // to the "foo.example.com" Listener (and not the "*.example.com" Listener). 177 // This concept is known as "Listener Isolation". Implementations that do 178 // not support Listener Isolation MUST clearly document this. 179 // 180 // Implementations MAY merge separate Gateways onto a single set of 181 // Addresses if all Listeners across all Gateways are compatible. 182 // 183 // Support: Core 184 // 185 // +listType=map 186 // +listMapKey=name 187 // +kubebuilder:validation:MinItems=1 188 // +kubebuilder:validation:MaxItems=64 189 // +kubebuilder:validation:XValidation:message="tls must be specified for protocols ['HTTPS', 'TLS']",rule="self.all(l, l.protocol in ['HTTPS', 'TLS'] ? has(l.tls) : true)" 190 // +kubebuilder:validation:XValidation:message="tls must not be specified for protocols ['HTTP', 'TCP', 'UDP']",rule="self.all(l, l.protocol in ['HTTP', 'TCP', 'UDP'] ? !has(l.tls) : true)" 191 // +kubebuilder:validation:XValidation:message="hostname must not be specified for protocols ['TCP', 'UDP']",rule="self.all(l, l.protocol in ['TCP', 'UDP'] ? (!has(l.hostname) || l.hostname == '') : true)" 192 // +kubebuilder:validation:XValidation:message="Listener name must be unique within the Gateway",rule="self.all(l1, self.exists_one(l2, l1.name == l2.name))" 193 // +kubebuilder:validation:XValidation:message="Combination of port, protocol and hostname must be unique for each listener",rule="self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))" 194 Listeners []Listener `json:"listeners"` 195 196 // Addresses requested for this Gateway. This is optional and behavior can 197 // depend on the implementation. If a value is set in the spec and the 198 // requested address is invalid or unavailable, the implementation MUST 199 // indicate this in the associated entry in GatewayStatus.Addresses. 200 // 201 // The Addresses field represents a request for the address(es) on the 202 // "outside of the Gateway", that traffic bound for this Gateway will use. 203 // This could be the IP address or hostname of an external load balancer or 204 // other networking infrastructure, or some other address that traffic will 205 // be sent to. 206 // 207 // If no Addresses are specified, the implementation MAY schedule the 208 // Gateway in an implementation-specific manner, assigning an appropriate 209 // set of Addresses. 210 // 211 // The implementation MUST bind all Listeners to every GatewayAddress that 212 // it assigns to the Gateway and add a corresponding entry in 213 // GatewayStatus.Addresses. 214 // 215 // Support: Extended 216 // 217 // +optional 218 // <gateway:validateIPAddress> 219 // +kubebuilder:validation:MaxItems=16 220 // +kubebuilder:validation:XValidation:message="IPAddress values must be unique",rule="self.all(a1, a1.type == 'IPAddress' ? self.exists_one(a2, a2.type == a1.type && a2.value == a1.value) : true )" 221 // +kubebuilder:validation:XValidation:message="Hostname values must be unique",rule="self.all(a1, a1.type == 'Hostname' ? self.exists_one(a2, a2.type == a1.type && a2.value == a1.value) : true )" 222 Addresses []GatewayAddress `json:"addresses,omitempty"` 223 224 // Infrastructure defines infrastructure level attributes about this Gateway instance. 225 // 226 // Support: Core 227 // 228 // <gateway:experimental> 229 // +optional 230 Infrastructure *GatewayInfrastructure `json:"infrastructure,omitempty"` 231 } 232 233 // Listener embodies the concept of a logical endpoint where a Gateway accepts 234 // network connections. 235 type Listener struct { 236 // Name is the name of the Listener. This name MUST be unique within a 237 // Gateway. 238 // 239 // Support: Core 240 Name SectionName `json:"name"` 241 242 // Hostname specifies the virtual hostname to match for protocol types that 243 // define this concept. When unspecified, all hostnames are matched. This 244 // field is ignored for protocols that don't require hostname based 245 // matching. 246 // 247 // Implementations MUST apply Hostname matching appropriately for each of 248 // the following protocols: 249 // 250 // * TLS: The Listener Hostname MUST match the SNI. 251 // * HTTP: The Listener Hostname MUST match the Host header of the request. 252 // * HTTPS: The Listener Hostname SHOULD match at both the TLS and HTTP 253 // protocol layers as described above. If an implementation does not 254 // ensure that both the SNI and Host header match the Listener hostname, 255 // it MUST clearly document that. 256 // 257 // For HTTPRoute and TLSRoute resources, there is an interaction with the 258 // `spec.hostnames` array. When both listener and route specify hostnames, 259 // there MUST be an intersection between the values for a Route to be 260 // accepted. For more information, refer to the Route specific Hostnames 261 // documentation. 262 // 263 // Hostnames that are prefixed with a wildcard label (`*.`) are interpreted 264 // as a suffix match. That means that a match for `*.example.com` would match 265 // both `test.example.com`, and `foo.test.example.com`, but not `example.com`. 266 // 267 // Support: Core 268 // 269 // +optional 270 Hostname *Hostname `json:"hostname,omitempty"` 271 272 // Port is the network port. Multiple listeners may use the 273 // same port, subject to the Listener compatibility rules. 274 // 275 // Support: Core 276 Port PortNumber `json:"port"` 277 278 // Protocol specifies the network protocol this listener expects to receive. 279 // 280 // Support: Core 281 Protocol ProtocolType `json:"protocol"` 282 283 // TLS is the TLS configuration for the Listener. This field is required if 284 // the Protocol field is "HTTPS" or "TLS". It is invalid to set this field 285 // if the Protocol field is "HTTP", "TCP", or "UDP". 286 // 287 // The association of SNIs to Certificate defined in GatewayTLSConfig is 288 // defined based on the Hostname field for this listener. 289 // 290 // The GatewayClass MUST use the longest matching SNI out of all 291 // available certificates for any TLS handshake. 292 // 293 // Support: Core 294 // 295 // +optional 296 TLS *GatewayTLSConfig `json:"tls,omitempty"` 297 298 // AllowedRoutes defines the types of routes that MAY be attached to a 299 // Listener and the trusted namespaces where those Route resources MAY be 300 // present. 301 // 302 // Although a client request may match multiple route rules, only one rule 303 // may ultimately receive the request. Matching precedence MUST be 304 // determined in order of the following criteria: 305 // 306 // * The most specific match as defined by the Route type. 307 // * The oldest Route based on creation timestamp. For example, a Route with 308 // a creation timestamp of "2020-09-08 01:02:03" is given precedence over 309 // a Route with a creation timestamp of "2020-09-08 01:02:04". 310 // * If everything else is equivalent, the Route appearing first in 311 // alphabetical order (namespace/name) should be given precedence. For 312 // example, foo/bar is given precedence over foo/baz. 313 // 314 // All valid rules within a Route attached to this Listener should be 315 // implemented. Invalid Route rules can be ignored (sometimes that will mean 316 // the full Route). If a Route rule transitions from valid to invalid, 317 // support for that Route rule should be dropped to ensure consistency. For 318 // example, even if a filter specified by a Route rule is invalid, the rest 319 // of the rules within that Route should still be supported. 320 // 321 // Support: Core 322 // +kubebuilder:default={namespaces:{from: Same}} 323 // +optional 324 AllowedRoutes *AllowedRoutes `json:"allowedRoutes,omitempty"` 325 } 326 327 // ProtocolType defines the application protocol accepted by a Listener. 328 // Implementations are not required to accept all the defined protocols. If an 329 // implementation does not support a specified protocol, it MUST set the 330 // "Accepted" condition to False for the affected Listener with a reason of 331 // "UnsupportedProtocol". 332 // 333 // Core ProtocolType values are listed in the table below. 334 // 335 // Implementations can define their own protocols if a core ProtocolType does not 336 // exist. Such definitions must use prefixed name, such as 337 // `mycompany.com/my-custom-protocol`. Un-prefixed names are reserved for core 338 // protocols. Any protocol defined by implementations will fall under 339 // Implementation-specific conformance. 340 // 341 // Valid values include: 342 // 343 // * "HTTP" - Core support 344 // * "example.com/bar" - Implementation-specific support 345 // 346 // Invalid values include: 347 // 348 // * "example.com" - must include path if domain is used 349 // * "foo.example.com" - must include path if domain is used 350 // 351 // +kubebuilder:validation:MinLength=1 352 // +kubebuilder:validation:MaxLength=255 353 // +kubebuilder:validation:Pattern=`^[a-zA-Z0-9]([-a-zSA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9]+$` 354 type ProtocolType string 355 356 const ( 357 // Accepts cleartext HTTP/1.1 sessions over TCP. Implementations MAY also 358 // support HTTP/2 over cleartext. If implementations support HTTP/2 over 359 // cleartext on "HTTP" listeners, that MUST be clearly documented by the 360 // implementation. 361 HTTPProtocolType ProtocolType = "HTTP" 362 363 // Accepts HTTP/1.1 or HTTP/2 sessions over TLS. 364 HTTPSProtocolType ProtocolType = "HTTPS" 365 366 // Accepts TLS sessions over TCP. 367 TLSProtocolType ProtocolType = "TLS" 368 369 // Accepts TCP sessions. 370 TCPProtocolType ProtocolType = "TCP" 371 372 // Accepts UDP packets. 373 UDPProtocolType ProtocolType = "UDP" 374 ) 375 376 // GatewayTLSConfig describes a TLS configuration. 377 // 378 // +kubebuilder:validation:XValidation:message="certificateRefs must be specified when TLSModeType is Terminate",rule="self.mode == 'Terminate' ? size(self.certificateRefs) > 0 : true" 379 type GatewayTLSConfig struct { 380 // Mode defines the TLS behavior for the TLS session initiated by the client. 381 // There are two possible modes: 382 // 383 // - Terminate: The TLS session between the downstream client 384 // and the Gateway is terminated at the Gateway. This mode requires 385 // certificateRefs to be set and contain at least one element. 386 // - Passthrough: The TLS session is NOT terminated by the Gateway. This 387 // implies that the Gateway can't decipher the TLS stream except for 388 // the ClientHello message of the TLS protocol. 389 // CertificateRefs field is ignored in this mode. 390 // 391 // Support: Core 392 // 393 // +optional 394 // +kubebuilder:default=Terminate 395 Mode *TLSModeType `json:"mode,omitempty"` 396 397 // CertificateRefs contains a series of references to Kubernetes objects that 398 // contains TLS certificates and private keys. These certificates are used to 399 // establish a TLS handshake for requests that match the hostname of the 400 // associated listener. 401 // 402 // A single CertificateRef to a Kubernetes Secret has "Core" support. 403 // Implementations MAY choose to support attaching multiple certificates to 404 // a Listener, but this behavior is implementation-specific. 405 // 406 // References to a resource in different namespace are invalid UNLESS there 407 // is a ReferenceGrant in the target namespace that allows the certificate 408 // to be attached. If a ReferenceGrant does not allow this reference, the 409 // "ResolvedRefs" condition MUST be set to False for this listener with the 410 // "RefNotPermitted" reason. 411 // 412 // This field is required to have at least one element when the mode is set 413 // to "Terminate" (default) and is optional otherwise. 414 // 415 // CertificateRefs can reference to standard Kubernetes resources, i.e. 416 // Secret, or implementation-specific custom resources. 417 // 418 // Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls 419 // 420 // Support: Implementation-specific (More than one reference or other resource types) 421 // 422 // +optional 423 // +kubebuilder:validation:MaxItems=64 424 CertificateRefs []SecretObjectReference `json:"certificateRefs,omitempty"` 425 426 // Options are a list of key/value pairs to enable extended TLS 427 // configuration for each implementation. For example, configuring the 428 // minimum TLS version or supported cipher suites. 429 // 430 // A set of common keys MAY be defined by the API in the future. To avoid 431 // any ambiguity, implementation-specific definitions MUST use 432 // domain-prefixed names, such as `example.com/my-custom-option`. 433 // Un-prefixed names are reserved for key names defined by Gateway API. 434 // 435 // Support: Implementation-specific 436 // 437 // +optional 438 // +kubebuilder:validation:MaxProperties=16 439 Options map[AnnotationKey]AnnotationValue `json:"options,omitempty"` 440 } 441 442 // TLSModeType type defines how a Gateway handles TLS sessions. 443 // 444 // +kubebuilder:validation:Enum=Terminate;Passthrough 445 type TLSModeType string 446 447 const ( 448 // In this mode, TLS session between the downstream client 449 // and the Gateway is terminated at the Gateway. 450 TLSModeTerminate TLSModeType = "Terminate" 451 452 // In this mode, the TLS session is NOT terminated by the Gateway. This 453 // implies that the Gateway can't decipher the TLS stream except for 454 // the ClientHello message of the TLS protocol. 455 // 456 // Note that SSL passthrough is only supported by TLSRoute. 457 TLSModePassthrough TLSModeType = "Passthrough" 458 ) 459 460 // AllowedRoutes defines which Routes may be attached to this Listener. 461 type AllowedRoutes struct { 462 // Namespaces indicates namespaces from which Routes may be attached to this 463 // Listener. This is restricted to the namespace of this Gateway by default. 464 // 465 // Support: Core 466 // 467 // +optional 468 // +kubebuilder:default={from: Same} 469 Namespaces *RouteNamespaces `json:"namespaces,omitempty"` 470 471 // Kinds specifies the groups and kinds of Routes that are allowed to bind 472 // to this Gateway Listener. When unspecified or empty, the kinds of Routes 473 // selected are determined using the Listener protocol. 474 // 475 // A RouteGroupKind MUST correspond to kinds of Routes that are compatible 476 // with the application protocol specified in the Listener's Protocol field. 477 // If an implementation does not support or recognize this resource type, it 478 // MUST set the "ResolvedRefs" condition to False for this Listener with the 479 // "InvalidRouteKinds" reason. 480 // 481 // Support: Core 482 // 483 // +optional 484 // +kubebuilder:validation:MaxItems=8 485 Kinds []RouteGroupKind `json:"kinds,omitempty"` 486 } 487 488 // FromNamespaces specifies namespace from which Routes may be attached to a 489 // Gateway. 490 // 491 // +kubebuilder:validation:Enum=All;Selector;Same 492 type FromNamespaces string 493 494 const ( 495 // Routes in all namespaces may be attached to this Gateway. 496 NamespacesFromAll FromNamespaces = "All" 497 // Only Routes in namespaces selected by the selector may be attached to 498 // this Gateway. 499 NamespacesFromSelector FromNamespaces = "Selector" 500 // Only Routes in the same namespace as the Gateway may be attached to this 501 // Gateway. 502 NamespacesFromSame FromNamespaces = "Same" 503 ) 504 505 // RouteNamespaces indicate which namespaces Routes should be selected from. 506 type RouteNamespaces struct { 507 // From indicates where Routes will be selected for this Gateway. Possible 508 // values are: 509 // 510 // * All: Routes in all namespaces may be used by this Gateway. 511 // * Selector: Routes in namespaces selected by the selector may be used by 512 // this Gateway. 513 // * Same: Only Routes in the same namespace may be used by this Gateway. 514 // 515 // Support: Core 516 // 517 // +optional 518 // +kubebuilder:default=Same 519 From *FromNamespaces `json:"from,omitempty"` 520 521 // Selector must be specified when From is set to "Selector". In that case, 522 // only Routes in Namespaces matching this Selector will be selected by this 523 // Gateway. This field is ignored for other values of "From". 524 // 525 // Support: Core 526 // 527 // +optional 528 Selector *metav1.LabelSelector `json:"selector,omitempty"` 529 } 530 531 // RouteGroupKind indicates the group and kind of a Route resource. 532 type RouteGroupKind struct { 533 // Group is the group of the Route. 534 // 535 // +optional 536 // +kubebuilder:default=gateway.networking.k8s.io 537 Group *Group `json:"group,omitempty"` 538 539 // Kind is the kind of the Route. 540 Kind Kind `json:"kind"` 541 } 542 543 // GatewayAddress describes an address that can be bound to a Gateway. 544 // 545 // +kubebuilder:validation:XValidation:message="Hostname value must only contain valid characters (matching ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)",rule="self.type == 'Hostname' ? self.value.matches(r\"\"\"^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\"\"\"): true" 546 type GatewayAddress struct { 547 // Type of the address. 548 // 549 // +optional 550 // +kubebuilder:default=IPAddress 551 Type *AddressType `json:"type,omitempty"` 552 553 // Value of the address. The validity of the values will depend 554 // on the type and support by the controller. 555 // 556 // Examples: `1.2.3.4`, `128::1`, `my-ip-address`. 557 // 558 // +kubebuilder:validation:MinLength=1 559 // +kubebuilder:validation:MaxLength=253 560 Value string `json:"value"` 561 } 562 563 // GatewayStatusAddress describes a network address that is bound to a Gateway. 564 // 565 // +kubebuilder:validation:XValidation:message="Hostname value must only contain valid characters (matching ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)",rule="self.type == 'Hostname' ? self.value.matches(r\"\"\"^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\"\"\"): true" 566 type GatewayStatusAddress struct { 567 // Type of the address. 568 // 569 // +optional 570 // +kubebuilder:default=IPAddress 571 Type *AddressType `json:"type,omitempty"` 572 573 // Value of the address. The validity of the values will depend 574 // on the type and support by the controller. 575 // 576 // Examples: `1.2.3.4`, `128::1`, `my-ip-address`. 577 // 578 // +kubebuilder:validation:MinLength=1 579 // +kubebuilder:validation:MaxLength=253 580 Value string `json:"value"` 581 } 582 583 // GatewayStatus defines the observed state of Gateway. 584 type GatewayStatus struct { 585 // Addresses lists the network addresses that have been bound to the 586 // Gateway. 587 // 588 // This list may differ from the addresses provided in the spec under some 589 // conditions: 590 // 591 // * no addresses are specified, all addresses are dynamically assigned 592 // * a combination of specified and dynamic addresses are assigned 593 // * a specified address was unusable (e.g. already in use) 594 // 595 // +optional 596 // <gateway:validateIPAddress> 597 // +kubebuilder:validation:MaxItems=16 598 Addresses []GatewayStatusAddress `json:"addresses,omitempty"` 599 600 // Conditions describe the current conditions of the Gateway. 601 // 602 // Implementations should prefer to express Gateway conditions 603 // using the `GatewayConditionType` and `GatewayConditionReason` 604 // constants so that operators and tools can converge on a common 605 // vocabulary to describe Gateway state. 606 // 607 // Known condition types are: 608 // 609 // * "Accepted" 610 // * "Programmed" 611 // * "Ready" 612 // 613 // +optional 614 // +listType=map 615 // +listMapKey=type 616 // +kubebuilder:validation:MaxItems=8 617 // +kubebuilder:default={{type: "Accepted", status: "Unknown", reason:"Pending", message:"Waiting for controller", lastTransitionTime: "1970-01-01T00:00:00Z"},{type: "Programmed", status: "Unknown", reason:"Pending", message:"Waiting for controller", lastTransitionTime: "1970-01-01T00:00:00Z"}} 618 Conditions []metav1.Condition `json:"conditions,omitempty"` 619 620 // Listeners provide status for each unique listener port defined in the Spec. 621 // 622 // +optional 623 // +listType=map 624 // +listMapKey=name 625 // +kubebuilder:validation:MaxItems=64 626 Listeners []ListenerStatus `json:"listeners,omitempty"` 627 } 628 629 // GatewayInfrastructure defines infrastructure level attributes about a Gateway instance. 630 type GatewayInfrastructure struct { 631 // Labels that SHOULD be applied to any resources created in response to this Gateway. 632 // 633 // For implementations creating other Kubernetes objects, this should be the `metadata.labels` field on resources. 634 // For other implementations, this refers to any relevant (implementation specific) "labels" concepts. 635 // 636 // An implementation may chose to add additional implementation-specific labels as they see fit. 637 // 638 // Support: Extended 639 // 640 // +optional 641 // +kubebuilder:validation:MaxProperties=8 642 Labels map[AnnotationKey]AnnotationValue `json:"labels,omitempty"` 643 644 // Annotations that SHOULD be applied to any resources created in response to this Gateway. 645 // 646 // For implementations creating other Kubernetes objects, this should be the `metadata.annotations` field on resources. 647 // For other implementations, this refers to any relevant (implementation specific) "annotations" concepts. 648 // 649 // An implementation may chose to add additional implementation-specific annotations as they see fit. 650 // 651 // Support: Extended 652 // 653 // +optional 654 // +kubebuilder:validation:MaxProperties=8 655 Annotations map[AnnotationKey]AnnotationValue `json:"annotations,omitempty"` 656 } 657 658 // GatewayConditionType is a type of condition associated with a 659 // Gateway. This type should be used with the GatewayStatus.Conditions 660 // field. 661 type GatewayConditionType string 662 663 // GatewayConditionReason defines the set of reasons that explain why a 664 // particular Gateway condition type has been raised. 665 type GatewayConditionReason string 666 667 const ( 668 // This condition indicates whether a Gateway has generated some 669 // configuration that is assumed to be ready soon in the underlying data 670 // plane. 671 // 672 // It is a positive-polarity summary condition, and so should always be 673 // present on the resource with ObservedGeneration set. 674 // 675 // It should be set to Unknown if the controller performs updates to the 676 // status before it has all the information it needs to be able to determine 677 // if the condition is true. 678 // 679 // Possible reasons for this condition to be True are: 680 // 681 // * "Programmed" 682 // 683 // Possible reasons for this condition to be False are: 684 // 685 // * "Invalid" 686 // * "Pending" 687 // * "NoResources" 688 // * "AddressNotAssigned" 689 // 690 // Possible reasons for this condition to be Unknown are: 691 // 692 // * "Pending" 693 // 694 // Controllers may raise this condition with other reasons, 695 // but should prefer to use the reasons listed above to improve 696 // interoperability. 697 GatewayConditionProgrammed GatewayConditionType = "Programmed" 698 699 // This reason is used with the "Programmed" condition when the condition is 700 // true. 701 GatewayReasonProgrammed GatewayConditionReason = "Programmed" 702 703 // This reason is used with the "Programmed" and "Accepted" conditions when the Gateway is 704 // syntactically or semantically invalid. 705 GatewayReasonInvalid GatewayConditionReason = "Invalid" 706 707 // This reason is used with the "Programmed" condition when the 708 // Gateway is not scheduled because insufficient infrastructure 709 // resources are available. 710 GatewayReasonNoResources GatewayConditionReason = "NoResources" 711 712 // This reason is used with the "Programmed" condition when the underlying 713 // implementation and network have yet to dynamically assign addresses for a 714 // Gateway. 715 // 716 // Some example situations where this reason can be used: 717 // 718 // * IPAM address exhaustion 719 // * Address not yet allocated 720 // 721 // When this reason is used the implementation SHOULD provide a clear 722 // message explaining the underlying problem, ideally with some hints as to 723 // what actions can be taken that might resolve the problem. 724 GatewayReasonAddressNotAssigned GatewayConditionReason = "AddressNotAssigned" 725 726 // This reason is used with the "Programmed" condition when the underlying 727 // implementation (and possibly, network) are unable to use an address that 728 // was provided in the Gateway specification. 729 // 730 // Some example situations where this reason can be used: 731 // 732 // * a named address not being found 733 // * a provided static address can't be used 734 // * the address is already in use 735 // 736 // When this reason is used the implementation SHOULD provide prescriptive 737 // information on which address is causing the problem and how to resolve it 738 // in the condition message. 739 GatewayReasonAddressNotUsable GatewayConditionReason = "AddressNotUsable" 740 ) 741 742 const ( 743 // This condition is true when the controller managing the Gateway is 744 // syntactically and semantically valid enough to produce some configuration 745 // in the underlying data plane. This does not indicate whether or not the 746 // configuration has been propagated to the data plane. 747 // 748 // Possible reasons for this condition to be True are: 749 // 750 // * "Accepted" 751 // * "ListenersNotValid" 752 // 753 // Possible reasons for this condition to be False are: 754 // 755 // * "Invalid" 756 // * "NotReconciled" 757 // * "UnsupportedAddress" 758 // * "ListenersNotValid" 759 // 760 // Possible reasons for this condition to be Unknown are: 761 // 762 // * "Pending" 763 // 764 // Controllers may raise this condition with other reasons, 765 // but should prefer to use the reasons listed above to improve 766 // interoperability. 767 GatewayConditionAccepted GatewayConditionType = "Accepted" 768 769 // This reason is used with the "Accepted" condition when the condition is 770 // True. 771 GatewayReasonAccepted GatewayConditionReason = "Accepted" 772 773 // This reason is used with the "Accepted" condition when one or 774 // more Listeners have an invalid or unsupported configuration 775 // and cannot be configured on the Gateway. 776 // This can be the reason when "Accepted" is "True" or "False", depending on whether 777 // the listener being invalid causes the entire Gateway to not be accepted. 778 GatewayReasonListenersNotValid GatewayConditionReason = "ListenersNotValid" 779 780 // This reason is used with the "Accepted" and "Programmed" 781 // conditions when the status is "Unknown" and no controller has reconciled 782 // the Gateway. 783 GatewayReasonPending GatewayConditionReason = "Pending" 784 785 // This reason is used with the "Accepted" condition to indicate that the 786 // Gateway could not be accepted because an address that was provided is a 787 // type which is not supported by the implementation. 788 GatewayReasonUnsupportedAddress GatewayConditionReason = "UnsupportedAddress" 789 ) 790 791 const ( 792 // Deprecated: use "Accepted" instead. 793 GatewayConditionScheduled GatewayConditionType = "Scheduled" 794 795 // This reason is used with the "Scheduled" condition when the condition is 796 // True. 797 // 798 // Deprecated: use the "Accepted" condition with reason "Accepted" instead. 799 GatewayReasonScheduled GatewayConditionReason = "Scheduled" 800 801 // Deprecated: Use "Pending" instead. 802 GatewayReasonNotReconciled GatewayConditionReason = "NotReconciled" 803 ) 804 805 const ( 806 // "Ready" is a condition type reserved for future use. It should not be used by implementations. 807 // 808 // If used in the future, "Ready" will represent the final state where all configuration is confirmed good 809 // _and has completely propagated to the data plane_. That is, it is a _guarantee_ that, as soon as something 810 // sees the Condition as `true`, then connections will be correctly routed _immediately_. 811 // 812 // This is a very strong guarantee, and to date no implementation has satisfied it enough to implement it. 813 // This reservation can be discussed in the future if necessary. 814 // 815 // Note: This condition is not really "deprecated", but rather "reserved"; however, deprecated triggers Go linters 816 // to alert about usage. 817 // Deprecated: Ready is reserved for future use 818 GatewayConditionReady GatewayConditionType = "Ready" 819 820 // Deprecated: Ready is reserved for future use 821 GatewayReasonReady GatewayConditionReason = "Ready" 822 823 // Deprecated: Ready is reserved for future use 824 GatewayReasonListenersNotReady GatewayConditionReason = "ListenersNotReady" 825 ) 826 827 // ListenerStatus is the status associated with a Listener. 828 type ListenerStatus struct { 829 // Name is the name of the Listener that this status corresponds to. 830 Name SectionName `json:"name"` 831 832 // SupportedKinds is the list indicating the Kinds supported by this 833 // listener. This MUST represent the kinds an implementation supports for 834 // that Listener configuration. 835 // 836 // If kinds are specified in Spec that are not supported, they MUST NOT 837 // appear in this list and an implementation MUST set the "ResolvedRefs" 838 // condition to "False" with the "InvalidRouteKinds" reason. If both valid 839 // and invalid Route kinds are specified, the implementation MUST 840 // reference the valid Route kinds that have been specified. 841 // 842 // +kubebuilder:validation:MaxItems=8 843 SupportedKinds []RouteGroupKind `json:"supportedKinds"` 844 845 // AttachedRoutes represents the total number of Routes that have been 846 // successfully attached to this Listener. 847 // 848 // Successful attachment of a Route to a Listener is based solely on the 849 // combination of the AllowedRoutes field on the corresponding Listener 850 // and the Route's ParentRefs field. A Route is successfully attached to 851 // a Listener when it is selected by the Listener's AllowedRoutes field 852 // AND the Route has a valid ParentRef selecting the whole Gateway 853 // resource or a specific Listener as a parent resource (more detail on 854 // attachment semantics can be found in the documentation on the various 855 // Route kinds ParentRefs fields). Listener or Route status does not impact 856 // successful attachment, i.e. the AttachedRoutes field count MUST be set 857 // for Listeners with condition Accepted: false and MUST count successfully 858 // attached Routes that may themselves have Accepted: false conditions. 859 // 860 // Uses for this field include troubleshooting Route attachment and 861 // measuring blast radius/impact of changes to a Listener. 862 AttachedRoutes int32 `json:"attachedRoutes"` 863 864 // Conditions describe the current condition of this listener. 865 // 866 // +listType=map 867 // +listMapKey=type 868 // +kubebuilder:validation:MaxItems=8 869 Conditions []metav1.Condition `json:"conditions"` 870 } 871 872 // ListenerConditionType is a type of condition associated with the 873 // listener. This type should be used with the ListenerStatus.Conditions 874 // field. 875 type ListenerConditionType string 876 877 // ListenerConditionReason defines the set of reasons that explain 878 // why a particular Listener condition type has been raised. 879 type ListenerConditionReason string 880 881 const ( 882 // This condition indicates that the controller was unable to resolve 883 // conflicting specification requirements for this Listener. If a 884 // Listener is conflicted, its network port should not be configured 885 // on any network elements. 886 // 887 // Possible reasons for this condition to be true are: 888 // 889 // * "HostnameConflict" 890 // * "ProtocolConflict" 891 // 892 // Possible reasons for this condition to be False are: 893 // 894 // * "NoConflicts" 895 // 896 // Controllers may raise this condition with other reasons, 897 // but should prefer to use the reasons listed above to improve 898 // interoperability. 899 ListenerConditionConflicted ListenerConditionType = "Conflicted" 900 901 // This reason is used with the "Conflicted" condition when 902 // the Listener conflicts with hostnames in other Listeners. For 903 // example, this reason would be used when multiple Listeners on 904 // the same port use `example.com` in the hostname field. 905 ListenerReasonHostnameConflict ListenerConditionReason = "HostnameConflict" 906 907 // This reason is used with the "Conflicted" condition when 908 // multiple Listeners are specified with the same Listener port 909 // number, but have conflicting protocol specifications. 910 ListenerReasonProtocolConflict ListenerConditionReason = "ProtocolConflict" 911 912 // This reason is used with the "Conflicted" condition when the condition 913 // is False. 914 ListenerReasonNoConflicts ListenerConditionReason = "NoConflicts" 915 ) 916 917 const ( 918 // This condition indicates that the listener is syntactically and 919 // semantically valid, and that all features used in the listener's spec are 920 // supported. 921 // 922 // In general, a Listener will be marked as Accepted when the supplied 923 // configuration will generate at least some data plane configuration. 924 // 925 // For example, a Listener with an unsupported protocol will never generate 926 // any data plane config, and so will have Accepted set to `false.` 927 // Conversely, a Listener that does not have any Routes will be able to 928 // generate data plane config, and so will have Accepted set to `true`. 929 // 930 // Possible reasons for this condition to be True are: 931 // 932 // * "Accepted" 933 // 934 // Possible reasons for this condition to be False are: 935 // 936 // * "PortUnavailable" 937 // * "UnsupportedProtocol" 938 // 939 // Possible reasons for this condition to be Unknown are: 940 // 941 // * "Pending" 942 // 943 // Controllers may raise this condition with other reasons, 944 // but should prefer to use the reasons listed above to improve 945 // interoperability. 946 ListenerConditionAccepted ListenerConditionType = "Accepted" 947 948 // Deprecated: use "Accepted" instead. 949 ListenerConditionDetached ListenerConditionType = "Detached" 950 951 // This reason is used with the "Accepted" condition when the condition is 952 // True. 953 ListenerReasonAccepted ListenerConditionReason = "Accepted" 954 955 // This reason is used with the "Detached" condition when the condition is 956 // False. 957 // 958 // Deprecated: use the "Accepted" condition with reason "Accepted" instead. 959 ListenerReasonAttached ListenerConditionReason = "Attached" 960 961 // This reason is used with the "Accepted" condition when the Listener 962 // requests a port that cannot be used on the Gateway. This reason could be 963 // used in a number of instances, including: 964 // 965 // * The port is already in use. 966 // * The port is not supported by the implementation. 967 ListenerReasonPortUnavailable ListenerConditionReason = "PortUnavailable" 968 969 // This reason is used with the "Accepted" condition when the 970 // Listener could not be attached to be Gateway because its 971 // protocol type is not supported. 972 ListenerReasonUnsupportedProtocol ListenerConditionReason = "UnsupportedProtocol" 973 ) 974 975 const ( 976 // This condition indicates whether the controller was able to 977 // resolve all the object references for the Listener. 978 // 979 // Possible reasons for this condition to be true are: 980 // 981 // * "ResolvedRefs" 982 // 983 // Possible reasons for this condition to be False are: 984 // 985 // * "InvalidCertificateRef" 986 // * "InvalidRouteKinds" 987 // * "RefNotPermitted" 988 // 989 // Controllers may raise this condition with other reasons, 990 // but should prefer to use the reasons listed above to improve 991 // interoperability. 992 ListenerConditionResolvedRefs ListenerConditionType = "ResolvedRefs" 993 994 // This reason is used with the "ResolvedRefs" condition when the condition 995 // is true. 996 ListenerReasonResolvedRefs ListenerConditionReason = "ResolvedRefs" 997 998 // This reason is used with the "ResolvedRefs" condition when the 999 // Listener has a TLS configuration with at least one TLS CertificateRef 1000 // that is invalid or does not exist. 1001 // A CertificateRef is considered invalid when it refers to a nonexistent 1002 // or unsupported resource or kind, or when the data within that resource 1003 // is malformed. 1004 // This reason must be used only when the reference is allowed, either by 1005 // referencing an object in the same namespace as the Gateway, or when 1006 // a cross-namespace reference has been explicitly allowed by a ReferenceGrant. 1007 // If the reference is not allowed, the reason RefNotPermitted must be used 1008 // instead. 1009 ListenerReasonInvalidCertificateRef ListenerConditionReason = "InvalidCertificateRef" 1010 1011 // This reason is used with the "ResolvedRefs" condition when an invalid or 1012 // unsupported Route kind is specified by the Listener. 1013 ListenerReasonInvalidRouteKinds ListenerConditionReason = "InvalidRouteKinds" 1014 1015 // This reason is used with the "ResolvedRefs" condition when the 1016 // Listener has a TLS configuration that references an object in another 1017 // namespace, where the object in the other namespace does not have a 1018 // ReferenceGrant explicitly allowing the reference. 1019 ListenerReasonRefNotPermitted ListenerConditionReason = "RefNotPermitted" 1020 ) 1021 1022 const ( 1023 // This condition indicates whether a Listener has generated some 1024 // configuration that will soon be ready in the underlying data plane. 1025 // 1026 // It is a positive-polarity summary condition, and so should always be 1027 // present on the resource with ObservedGeneration set. 1028 // 1029 // It should be set to Unknown if the controller performs updates to the 1030 // status before it has all the information it needs to be able to determine 1031 // if the condition is true. 1032 // 1033 // Possible reasons for this condition to be True are: 1034 // 1035 // * "Programmed" 1036 // 1037 // Possible reasons for this condition to be False are: 1038 // 1039 // * "Invalid" 1040 // * "Pending" 1041 // 1042 // Possible reasons for this condition to be Unknown are: 1043 // 1044 // * "Pending" 1045 // 1046 // Controllers may raise this condition with other reasons, 1047 // but should prefer to use the reasons listed above to improve 1048 // interoperability. 1049 ListenerConditionProgrammed ListenerConditionType = "Programmed" 1050 1051 // This reason is used with the "Programmed" condition when the condition is 1052 // true. 1053 ListenerReasonProgrammed ListenerConditionReason = "Programmed" 1054 1055 // This reason is used with the "Ready" and "Programmed" conditions when the 1056 // Listener is syntactically or semantically invalid. 1057 ListenerReasonInvalid ListenerConditionReason = "Invalid" 1058 1059 // This reason is used with the "Accepted", "Ready" and "Programmed" 1060 // conditions when the Listener is either not yet reconciled or not yet not 1061 // online and ready to accept client traffic. 1062 ListenerReasonPending ListenerConditionReason = "Pending" 1063 ) 1064 1065 const ( 1066 // "Ready" is a condition type reserved for future use. It should not be used by implementations. 1067 // Note: This condition is not really "deprecated", but rather "reserved"; however, deprecated triggers Go linters 1068 // to alert about usage. 1069 // 1070 // If used in the future, "Ready" will represent the final state where all configuration is confirmed good 1071 // _and has completely propagated to the data plane_. That is, it is a _guarantee_ that, as soon as something 1072 // sees the Condition as `true`, then connections will be correctly routed _immediately_. 1073 // 1074 // This is a very strong guarantee, and to date no implementation has satisfied it enough to implement it. 1075 // This reservation can be discussed in the future if necessary. 1076 // 1077 // Deprecated: Ready is reserved for future use 1078 ListenerConditionReady ListenerConditionType = "Ready" 1079 1080 // Deprecated: Ready is reserved for future use 1081 ListenerReasonReady ListenerConditionReason = "Ready" 1082 ) 1083