diff --git a/apis/v1/gateway_types.go b/apis/v1/gateway_types.go index e2cf5967b5..78b0a527f5 100644 --- a/apis/v1/gateway_types.go +++ b/apis/v1/gateway_types.go @@ -264,7 +264,7 @@ type GatewaySpec struct { // +kubebuilder:validation:MaxItems=16 // +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 )" // +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 )" - Addresses []GatewayAddress `json:"addresses,omitempty"` + Addresses []GatewaySpecAddress `json:"addresses,omitempty"` // Infrastructure defines infrastructure level attributes about this Gateway instance. // @@ -724,24 +724,27 @@ type RouteGroupKind struct { Kind Kind `json:"kind"` } -// GatewayAddress describes an address that can be bound to a Gateway. +// GatewaySpecAddress describes an address that can be bound to a Gateway. // // +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" -type GatewayAddress struct { +type GatewaySpecAddress struct { // Type of the address. // // +optional // +kubebuilder:default=IPAddress Type *AddressType `json:"type,omitempty"` - // Value of the address. The validity of the values will depend - // on the type and support by the controller. + // When a value is unspecified, an implementation SHOULD automatically + // assign an address matching the requested type if possible. + // + // If an implementation does not support an empty value, they MUST set the + // "Programmed" condition in status to False with a reason of "AddressNotAssigned". // // Examples: `1.2.3.4`, `128::1`, `my-ip-address`. // - // +kubebuilder:validation:MinLength=1 + // +optional // +kubebuilder:validation:MaxLength=253 - Value string `json:"value"` + Value string `json:"value,omitempty"` } // GatewayStatusAddress describes a network address that is bound to a Gateway. diff --git a/apis/v1/zz_generated.deepcopy.go b/apis/v1/zz_generated.deepcopy.go index 68aa5e1a61..6b8a13485a 100644 --- a/apis/v1/zz_generated.deepcopy.go +++ b/apis/v1/zz_generated.deepcopy.go @@ -523,26 +523,6 @@ func (in *Gateway) DeepCopyObject() runtime.Object { return nil } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GatewayAddress) DeepCopyInto(out *GatewayAddress) { - *out = *in - if in.Type != nil { - in, out := &in.Type, &out.Type - *out = new(AddressType) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayAddress. -func (in *GatewayAddress) DeepCopy() *GatewayAddress { - if in == nil { - return nil - } - out := new(GatewayAddress) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GatewayBackendTLS) DeepCopyInto(out *GatewayBackendTLS) { *out = *in @@ -752,7 +732,7 @@ func (in *GatewaySpec) DeepCopyInto(out *GatewaySpec) { } if in.Addresses != nil { in, out := &in.Addresses, &out.Addresses - *out = make([]GatewayAddress, len(*in)) + *out = make([]GatewaySpecAddress, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -784,6 +764,26 @@ func (in *GatewaySpec) DeepCopy() *GatewaySpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GatewaySpecAddress) DeepCopyInto(out *GatewaySpecAddress) { + *out = *in + if in.Type != nil { + in, out := &in.Type, &out.Type + *out = new(AddressType) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewaySpecAddress. +func (in *GatewaySpecAddress) DeepCopy() *GatewaySpecAddress { + if in == nil { + return nil + } + out := new(GatewaySpecAddress) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GatewayStatus) DeepCopyInto(out *GatewayStatus) { *out = *in diff --git a/apis/v1beta1/gateway_types.go b/apis/v1beta1/gateway_types.go index 2834915ca7..80c746fcdd 100644 --- a/apis/v1beta1/gateway_types.go +++ b/apis/v1beta1/gateway_types.go @@ -133,7 +133,7 @@ type RouteGroupKind = v1.RouteGroupKind // GatewayAddress describes an address that can be bound to a Gateway. // +k8s:deepcopy-gen=false -type GatewayAddress = v1.GatewayAddress +type GatewaySpecAddress = v1.GatewaySpecAddress // GatewayStatus defines the observed state of Gateway. // +k8s:deepcopy-gen=false diff --git a/applyconfiguration/apis/v1/gatewayspec.go b/applyconfiguration/apis/v1/gatewayspec.go index 9ba7ecb20d..65e3e1991d 100644 --- a/applyconfiguration/apis/v1/gatewayspec.go +++ b/applyconfiguration/apis/v1/gatewayspec.go @@ -27,7 +27,7 @@ import ( type GatewaySpecApplyConfiguration struct { GatewayClassName *v1.ObjectName `json:"gatewayClassName,omitempty"` Listeners []ListenerApplyConfiguration `json:"listeners,omitempty"` - Addresses []GatewayAddressApplyConfiguration `json:"addresses,omitempty"` + Addresses []GatewaySpecAddressApplyConfiguration `json:"addresses,omitempty"` Infrastructure *GatewayInfrastructureApplyConfiguration `json:"infrastructure,omitempty"` BackendTLS *GatewayBackendTLSApplyConfiguration `json:"backendTLS,omitempty"` AllowedListeners *AllowedListenersApplyConfiguration `json:"allowedListeners,omitempty"` @@ -63,7 +63,7 @@ func (b *GatewaySpecApplyConfiguration) WithListeners(values ...*ListenerApplyCo // WithAddresses adds the given value to the Addresses field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the Addresses field. -func (b *GatewaySpecApplyConfiguration) WithAddresses(values ...*GatewayAddressApplyConfiguration) *GatewaySpecApplyConfiguration { +func (b *GatewaySpecApplyConfiguration) WithAddresses(values ...*GatewaySpecAddressApplyConfiguration) *GatewaySpecApplyConfiguration { for i := range values { if values[i] == nil { panic("nil value passed to WithAddresses") diff --git a/applyconfiguration/apis/v1/gatewayspecaddress.go b/applyconfiguration/apis/v1/gatewayspecaddress.go new file mode 100644 index 0000000000..f633012fbd --- /dev/null +++ b/applyconfiguration/apis/v1/gatewayspecaddress.go @@ -0,0 +1,52 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "sigs.k8s.io/gateway-api/apis/v1" +) + +// GatewaySpecAddressApplyConfiguration represents a declarative configuration of the GatewaySpecAddress type for use +// with apply. +type GatewaySpecAddressApplyConfiguration struct { + Type *v1.AddressType `json:"type,omitempty"` + Value *string `json:"value,omitempty"` +} + +// GatewaySpecAddressApplyConfiguration constructs a declarative configuration of the GatewaySpecAddress type for use with +// apply. +func GatewaySpecAddress() *GatewaySpecAddressApplyConfiguration { + return &GatewaySpecAddressApplyConfiguration{} +} + +// WithType sets the Type field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Type field is set to the value of the last call. +func (b *GatewaySpecAddressApplyConfiguration) WithType(value v1.AddressType) *GatewaySpecAddressApplyConfiguration { + b.Type = &value + return b +} + +// WithValue sets the Value field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Value field is set to the value of the last call. +func (b *GatewaySpecAddressApplyConfiguration) WithValue(value string) *GatewaySpecAddressApplyConfiguration { + b.Value = &value + return b +} diff --git a/applyconfiguration/internal/internal.go b/applyconfiguration/internal/internal.go index e92cf26573..2474806fc2 100644 --- a/applyconfiguration/internal/internal.go +++ b/applyconfiguration/internal/internal.go @@ -493,16 +493,6 @@ var schemaYAML = typed.YAMLObject(`types: type: namedType: io.k8s.sigs.gateway-api.apis.v1.GatewayStatus default: {} -- name: io.k8s.sigs.gateway-api.apis.v1.GatewayAddress - map: - fields: - - name: type - type: - scalar: string - - name: value - type: - scalar: string - default: "" - name: io.k8s.sigs.gateway-api.apis.v1.GatewayBackendTLS map: fields: @@ -585,7 +575,7 @@ var schemaYAML = typed.YAMLObject(`types: type: list: elementType: - namedType: io.k8s.sigs.gateway-api.apis.v1.GatewayAddress + namedType: io.k8s.sigs.gateway-api.apis.v1.GatewaySpecAddress elementRelationship: atomic - name: allowedListeners type: @@ -608,6 +598,15 @@ var schemaYAML = typed.YAMLObject(`types: elementRelationship: associative keys: - name +- name: io.k8s.sigs.gateway-api.apis.v1.GatewaySpecAddress + map: + fields: + - name: type + type: + scalar: string + - name: value + type: + scalar: string - name: io.k8s.sigs.gateway-api.apis.v1.GatewayStatus map: fields: diff --git a/applyconfiguration/utils.go b/applyconfiguration/utils.go index 4f424a73b2..3219d6482e 100644 --- a/applyconfiguration/utils.go +++ b/applyconfiguration/utils.go @@ -58,8 +58,6 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &apisv1.FrontendTLSValidationApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("Gateway"): return &apisv1.GatewayApplyConfiguration{} - case v1.SchemeGroupVersion.WithKind("GatewayAddress"): - return &apisv1.GatewayAddressApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("GatewayBackendTLS"): return &apisv1.GatewayBackendTLSApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("GatewayClass"): @@ -72,6 +70,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &apisv1.GatewayInfrastructureApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("GatewaySpec"): return &apisv1.GatewaySpecApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("GatewaySpecAddress"): + return &apisv1.GatewaySpecAddressApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("GatewayStatus"): return &apisv1.GatewayStatusApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("GatewayStatusAddress"): diff --git a/config/crd/experimental/gateway.networking.k8s.io_gateways.yaml b/config/crd/experimental/gateway.networking.k8s.io_gateways.yaml index a8e07236a7..bcb7044ad8 100644 --- a/config/crd/experimental/gateway.networking.k8s.io_gateways.yaml +++ b/config/crd/experimental/gateway.networking.k8s.io_gateways.yaml @@ -83,8 +83,8 @@ spec: Support: Extended items: - description: GatewayAddress describes an address that can be bound - to a Gateway. + description: GatewaySpecAddress describes an address that can be + bound to a Gateway. oneOf: - properties: type: @@ -109,15 +109,15 @@ spec: type: string value: description: |- - Value of the address. The validity of the values will depend - on the type and support by the controller. + When a value is unspecified, an implementation SHOULD automatically + assign an address matching the requested type if possible. + + If an implementation does not support an empty value, they MUST set the + "Programmed" condition in status to False with a reason of "AddressNotAssigned". Examples: `1.2.3.4`, `128::1`, `my-ip-address`. maxLength: 253 - minLength: 1 type: string - required: - - value type: object x-kubernetes-validations: - message: Hostname value must only contain valid characters (matching @@ -1422,8 +1422,8 @@ spec: Support: Extended items: - description: GatewayAddress describes an address that can be bound - to a Gateway. + description: GatewaySpecAddress describes an address that can be + bound to a Gateway. oneOf: - properties: type: @@ -1448,15 +1448,15 @@ spec: type: string value: description: |- - Value of the address. The validity of the values will depend - on the type and support by the controller. + When a value is unspecified, an implementation SHOULD automatically + assign an address matching the requested type if possible. + + If an implementation does not support an empty value, they MUST set the + "Programmed" condition in status to False with a reason of "AddressNotAssigned". Examples: `1.2.3.4`, `128::1`, `my-ip-address`. maxLength: 253 - minLength: 1 type: string - required: - - value type: object x-kubernetes-validations: - message: Hostname value must only contain valid characters (matching diff --git a/config/crd/standard/gateway.networking.k8s.io_gateways.yaml b/config/crd/standard/gateway.networking.k8s.io_gateways.yaml index 15cbc96b81..e9f724a7e5 100644 --- a/config/crd/standard/gateway.networking.k8s.io_gateways.yaml +++ b/config/crd/standard/gateway.networking.k8s.io_gateways.yaml @@ -83,8 +83,8 @@ spec: Support: Extended items: - description: GatewayAddress describes an address that can be bound - to a Gateway. + description: GatewaySpecAddress describes an address that can be + bound to a Gateway. oneOf: - properties: type: @@ -109,15 +109,15 @@ spec: type: string value: description: |- - Value of the address. The validity of the values will depend - on the type and support by the controller. + When a value is unspecified, an implementation SHOULD automatically + assign an address matching the requested type if possible. + + If an implementation does not support an empty value, they MUST set the + "Programmed" condition in status to False with a reason of "AddressNotAssigned". Examples: `1.2.3.4`, `128::1`, `my-ip-address`. maxLength: 253 - minLength: 1 type: string - required: - - value type: object x-kubernetes-validations: - message: Hostname value must only contain valid characters (matching @@ -1190,8 +1190,8 @@ spec: Support: Extended items: - description: GatewayAddress describes an address that can be bound - to a Gateway. + description: GatewaySpecAddress describes an address that can be + bound to a Gateway. oneOf: - properties: type: @@ -1216,15 +1216,15 @@ spec: type: string value: description: |- - Value of the address. The validity of the values will depend - on the type and support by the controller. + When a value is unspecified, an implementation SHOULD automatically + assign an address matching the requested type if possible. + + If an implementation does not support an empty value, they MUST set the + "Programmed" condition in status to False with a reason of "AddressNotAssigned". Examples: `1.2.3.4`, `128::1`, `my-ip-address`. maxLength: 253 - minLength: 1 type: string - required: - - value type: object x-kubernetes-validations: - message: Hostname value must only contain valid characters (matching diff --git a/conformance/tests/gateway-static-addresses.go b/conformance/tests/gateway-static-addresses.go index 150975dfa8..fcee1b3f99 100644 --- a/conformance/tests/gateway-static-addresses.go +++ b/conformance/tests/gateway-static-addresses.go @@ -160,7 +160,7 @@ func extractStatusAddresses(addresses []v1.GatewayStatusAddress) []string { // Private Helper Functions // ----------------------------------------------------------------------------- -func filterAddr(addrs []v1.GatewayAddress, filter v1.GatewayAddress) (newAddrs []v1.GatewayAddress) { +func filterAddr(addrs []v1.GatewaySpecAddress, filter v1.GatewaySpecAddress) (newAddrs []v1.GatewaySpecAddress) { for _, addr := range addrs { if addr.Value != filter.Value { newAddrs = append(newAddrs, addr) diff --git a/conformance/utils/kubernetes/apply.go b/conformance/utils/kubernetes/apply.go index 983e0715e1..1b3b01d5aa 100644 --- a/conformance/utils/kubernetes/apply.go +++ b/conformance/utils/kubernetes/apply.go @@ -49,6 +49,10 @@ type Applier struct { // GatewayClass will be used as the spec.gatewayClassName when applying Gateway resources GatewayClass string + // AddressType is a type that is expected to be supported AND usable + // for Gateways in the underlying implementation + AddressType string + // ControllerName will be used as the spec.controllerName when applying GatewayClass resources ControllerName string @@ -57,11 +61,11 @@ type Applier struct { // UsableNetworkAddresses is a list of addresses that are expected to be // supported AND usable for Gateways in the underlying implementation. - UsableNetworkAddresses []v1beta1.GatewayAddress + UsableNetworkAddresses []v1beta1.GatewaySpecAddress // UnusableNetworkAddresses is a list of addresses that are expected to be // supported, but not usable for Gateways in the underlying implementation. - UnusableNetworkAddresses []v1beta1.GatewayAddress + UnusableNetworkAddresses []v1beta1.GatewaySpecAddress } // prepareGateway adjusts the gatewayClassName. @@ -104,7 +108,7 @@ func (a Applier) prepareGateway(t *testing.T, uObj *unstructured.Unstructured) { // Note: I would really love to find a better way to do this kind of // thing in the future. var overlayUsable, overlayUnusable bool - var specialAddrs []v1beta1.GatewayAddress + var specialAddrs []v1beta1.GatewaySpecAddress for _, addr := range gwspec.Addresses { switch addr.Value { case "PLACEHOLDER_USABLE_ADDRS": @@ -353,7 +357,7 @@ func getContentsFromPathOrURL(manifestFS []fs.FS, location string, timeoutConfig // convertGatewayAddrsToPrimitives converts a slice of Gateway addresses // to a slice of primitive types and then returns them as a []interface{} so that // they can be applied back to an unstructured Gateway. -func convertGatewayAddrsToPrimitives(gwaddrs []v1beta1.GatewayAddress) (raw []interface{}) { +func convertGatewayAddrsToPrimitives(gwaddrs []v1beta1.GatewaySpecAddress) (raw []interface{}) { for _, addr := range gwaddrs { addrType := string(v1beta1.IPAddressType) if addr.Type != nil { diff --git a/conformance/utils/suite/suite.go b/conformance/utils/suite/suite.go index dad285050d..81599a8d4c 100644 --- a/conformance/utils/suite/suite.go +++ b/conformance/utils/suite/suite.go @@ -75,8 +75,8 @@ type ConformanceTestSuite struct { SkipProvisionalTests bool RunTest string ManifestFS []fs.FS - UsableNetworkAddresses []v1beta1.GatewayAddress - UnusableNetworkAddresses []v1beta1.GatewayAddress + UsableNetworkAddresses []v1beta1.GatewaySpecAddress + UnusableNetworkAddresses []v1beta1.GatewaySpecAddress // mode is the operating mode of the implementation. // The default value for it is "default". @@ -128,6 +128,7 @@ type ConformanceOptions struct { Clientset clientset.Interface RestConfig *rest.Config GatewayClassName string + AddressType string Debug bool RoundTripper roundtripper.RoundTripper GRPCClient grpc.Client @@ -156,12 +157,12 @@ type ConformanceOptions struct { // UsableNetworkAddresses is an optional pool of usable addresses for // Gateways for tests which need to test manual address assignments. - UsableNetworkAddresses []v1beta1.GatewayAddress + UsableNetworkAddresses []v1beta1.GatewaySpecAddress // UnusableNetworkAddresses is an optional pool of unusable addresses for // Gateways for tests which need to test failures with manual Gateway // address assignment. - UnusableNetworkAddresses []v1beta1.GatewayAddress + UnusableNetworkAddresses []v1beta1.GatewaySpecAddress Mode string AllowCRDsMismatch bool @@ -249,6 +250,7 @@ func NewConformanceTestSuite(options ConformanceOptions) (*ConformanceTestSuite, Applier: kubernetes.Applier{ NamespaceLabels: options.NamespaceLabels, NamespaceAnnotations: options.NamespaceAnnotations, + AddressType: options.AddressType, }, SupportedFeatures: options.SupportedFeatures, TimeoutConfig: options.TimeoutConfig, diff --git a/pkg/features/gateway.go b/pkg/features/gateway.go index 7fc1a20db0..8def8db568 100644 --- a/pkg/features/gateway.go +++ b/pkg/features/gateway.go @@ -60,6 +60,10 @@ const ( // SupportGatewayInfrastructureAnnotations option indicates support for // spec.infrastructure.annotations and spec.infrastructure.labels SupportGatewayInfrastructurePropagation FeatureName = "GatewayInfrastructurePropagation" + + // SupportGatewayAddressEmpty option indicates support for an empty + // spec.addresses.value field + SupportGatewayAddressEmpty FeatureName = "GatewayAddressEmpty" ) var ( @@ -83,6 +87,12 @@ var ( Name: SupportGatewayInfrastructurePropagation, Channel: FeatureChannelExperimental, } + + // GatewayAddressEmptyFeature contains metadata for the SupportGatewayAddressEmpty feature. + GatewayEmptyAddressFeature = Feature{ + Name: SupportGatewayAddressEmpty, + Channel: FeatureChannelExperimental, + } ) // GatewayExtendedFeatures are extra generic features that implementations may @@ -92,4 +102,5 @@ var GatewayExtendedFeatures = sets.New( GatewayStaticAddressesFeature, GatewayHTTPListenerIsolationFeature, GatewayInfrastructurePropagationFeature, + GatewayEmptyAddressFeature, ) diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index 03801655f7..13d0d7ab2d 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -101,7 +101,6 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "sigs.k8s.io/gateway-api/apis/v1.GRPCRouteSpec": schema_sigsk8sio_gateway_api_apis_v1_GRPCRouteSpec(ref), "sigs.k8s.io/gateway-api/apis/v1.GRPCRouteStatus": schema_sigsk8sio_gateway_api_apis_v1_GRPCRouteStatus(ref), "sigs.k8s.io/gateway-api/apis/v1.Gateway": schema_sigsk8sio_gateway_api_apis_v1_Gateway(ref), - "sigs.k8s.io/gateway-api/apis/v1.GatewayAddress": schema_sigsk8sio_gateway_api_apis_v1_GatewayAddress(ref), "sigs.k8s.io/gateway-api/apis/v1.GatewayBackendTLS": schema_sigsk8sio_gateway_api_apis_v1_GatewayBackendTLS(ref), "sigs.k8s.io/gateway-api/apis/v1.GatewayClass": schema_sigsk8sio_gateway_api_apis_v1_GatewayClass(ref), "sigs.k8s.io/gateway-api/apis/v1.GatewayClassList": schema_sigsk8sio_gateway_api_apis_v1_GatewayClassList(ref), @@ -110,6 +109,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "sigs.k8s.io/gateway-api/apis/v1.GatewayInfrastructure": schema_sigsk8sio_gateway_api_apis_v1_GatewayInfrastructure(ref), "sigs.k8s.io/gateway-api/apis/v1.GatewayList": schema_sigsk8sio_gateway_api_apis_v1_GatewayList(ref), "sigs.k8s.io/gateway-api/apis/v1.GatewaySpec": schema_sigsk8sio_gateway_api_apis_v1_GatewaySpec(ref), + "sigs.k8s.io/gateway-api/apis/v1.GatewaySpecAddress": schema_sigsk8sio_gateway_api_apis_v1_GatewaySpecAddress(ref), "sigs.k8s.io/gateway-api/apis/v1.GatewayStatus": schema_sigsk8sio_gateway_api_apis_v1_GatewayStatus(ref), "sigs.k8s.io/gateway-api/apis/v1.GatewayStatusAddress": schema_sigsk8sio_gateway_api_apis_v1_GatewayStatusAddress(ref), "sigs.k8s.io/gateway-api/apis/v1.GatewayTLSConfig": schema_sigsk8sio_gateway_api_apis_v1_GatewayTLSConfig(ref), @@ -3598,35 +3598,6 @@ func schema_sigsk8sio_gateway_api_apis_v1_Gateway(ref common.ReferenceCallback) } } -func schema_sigsk8sio_gateway_api_apis_v1_GatewayAddress(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "GatewayAddress describes an address that can be bound to a Gateway.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "type": { - SchemaProps: spec.SchemaProps{ - Description: "Type of the address.", - Type: []string{"string"}, - Format: "", - }, - }, - "value": { - SchemaProps: spec.SchemaProps{ - Description: "Value of the address. The validity of the values will depend on the type and support by the controller.\n\nExamples: `1.2.3.4`, `128::1`, `my-ip-address`.", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"value"}, - }, - }, - } -} - func schema_sigsk8sio_gateway_api_apis_v1_GatewayBackendTLS(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -3989,7 +3960,7 @@ func schema_sigsk8sio_gateway_api_apis_v1_GatewaySpec(ref common.ReferenceCallba Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ Default: map[string]interface{}{}, - Ref: ref("sigs.k8s.io/gateway-api/apis/v1.GatewayAddress"), + Ref: ref("sigs.k8s.io/gateway-api/apis/v1.GatewaySpecAddress"), }, }, }, @@ -4018,7 +3989,34 @@ func schema_sigsk8sio_gateway_api_apis_v1_GatewaySpec(ref common.ReferenceCallba }, }, Dependencies: []string{ - "sigs.k8s.io/gateway-api/apis/v1.AllowedListeners", "sigs.k8s.io/gateway-api/apis/v1.GatewayAddress", "sigs.k8s.io/gateway-api/apis/v1.GatewayBackendTLS", "sigs.k8s.io/gateway-api/apis/v1.GatewayInfrastructure", "sigs.k8s.io/gateway-api/apis/v1.Listener"}, + "sigs.k8s.io/gateway-api/apis/v1.AllowedListeners", "sigs.k8s.io/gateway-api/apis/v1.GatewayBackendTLS", "sigs.k8s.io/gateway-api/apis/v1.GatewayInfrastructure", "sigs.k8s.io/gateway-api/apis/v1.GatewaySpecAddress", "sigs.k8s.io/gateway-api/apis/v1.Listener"}, + } +} + +func schema_sigsk8sio_gateway_api_apis_v1_GatewaySpecAddress(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "GatewayAddress describes an address that can be bound to a Gateway.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "type": { + SchemaProps: spec.SchemaProps{ + Description: "Type of the address.", + Type: []string{"string"}, + Format: "", + }, + }, + "value": { + SchemaProps: spec.SchemaProps{ + Description: "When a value is unspecified, an implementation SHOULD automatically assign an address matching the requested type if possible.\n\nIf an implementation does not support an empty value, they MUST set the \"Programmed\" condition in status to False with a reason of \"AddressNotAssigned\".\n\nExamples: `1.2.3.4`, `128::1`, `my-ip-address`.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, } } diff --git a/pkg/test/cel/gateway_test.go b/pkg/test/cel/gateway_test.go index 4c24020ead..7f8d867642 100644 --- a/pkg/test/cel/gateway_test.go +++ b/pkg/test/cel/gateway_test.go @@ -485,7 +485,7 @@ func TestValidateGateway(t *testing.T) { { desc: "ip address and hostname in addresses are valid", mutate: func(gw *gatewayv1.Gateway) { - gw.Spec.Addresses = []gatewayv1.GatewayAddress{ + gw.Spec.Addresses = []gatewayv1.GatewaySpecAddress{ { Type: ptrTo(gatewayv1.IPAddressType), Value: "1.2.3.4", @@ -504,7 +504,7 @@ func TestValidateGateway(t *testing.T) { { desc: "ip address and hostname in addresses are invalid", mutate: func(gw *gatewayv1.Gateway) { - gw.Spec.Addresses = []gatewayv1.GatewayAddress{ + gw.Spec.Addresses = []gatewayv1.GatewaySpecAddress{ { Type: ptrTo(gatewayv1.IPAddressType), Value: "1.2.3.4:8080", @@ -563,7 +563,7 @@ func TestValidateGateway(t *testing.T) { { desc: "duplicate ip address or hostname", mutate: func(gw *gatewayv1.Gateway) { - gw.Spec.Addresses = []gatewayv1.GatewayAddress{ + gw.Spec.Addresses = []gatewayv1.GatewaySpecAddress{ { Type: ptrTo(gatewayv1.IPAddressType), Value: "1.2.3.4",