diff --git a/apis/applyconfiguration/apis/v1/grpcrouterule.go b/apis/applyconfiguration/apis/v1/grpcrouterule.go index 367fe37260..6281e3aaaf 100644 --- a/apis/applyconfiguration/apis/v1/grpcrouterule.go +++ b/apis/applyconfiguration/apis/v1/grpcrouterule.go @@ -18,9 +18,14 @@ limitations under the License. package v1 +import ( + v1 "sigs.k8s.io/gateway-api/apis/v1" +) + // GRPCRouteRuleApplyConfiguration represents an declarative configuration of the GRPCRouteRule type for use // with apply. type GRPCRouteRuleApplyConfiguration struct { + Name *v1.SectionName `json:"name,omitempty"` Matches []GRPCRouteMatchApplyConfiguration `json:"matches,omitempty"` Filters []GRPCRouteFilterApplyConfiguration `json:"filters,omitempty"` BackendRefs []GRPCBackendRefApplyConfiguration `json:"backendRefs,omitempty"` @@ -33,6 +38,14 @@ func GRPCRouteRule() *GRPCRouteRuleApplyConfiguration { return &GRPCRouteRuleApplyConfiguration{} } +// WithName sets the Name 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 Name field is set to the value of the last call. +func (b *GRPCRouteRuleApplyConfiguration) WithName(value v1.SectionName) *GRPCRouteRuleApplyConfiguration { + b.Name = &value + return b +} + // WithMatches adds the given value to the Matches 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 Matches field. diff --git a/apis/applyconfiguration/apis/v1/httprouterule.go b/apis/applyconfiguration/apis/v1/httprouterule.go index dcef6b12e2..7e9f4d8239 100644 --- a/apis/applyconfiguration/apis/v1/httprouterule.go +++ b/apis/applyconfiguration/apis/v1/httprouterule.go @@ -18,9 +18,14 @@ limitations under the License. package v1 +import ( + v1 "sigs.k8s.io/gateway-api/apis/v1" +) + // HTTPRouteRuleApplyConfiguration represents an declarative configuration of the HTTPRouteRule type for use // with apply. type HTTPRouteRuleApplyConfiguration struct { + Name *v1.SectionName `json:"name,omitempty"` Matches []HTTPRouteMatchApplyConfiguration `json:"matches,omitempty"` Filters []HTTPRouteFilterApplyConfiguration `json:"filters,omitempty"` BackendRefs []HTTPBackendRefApplyConfiguration `json:"backendRefs,omitempty"` @@ -34,6 +39,14 @@ func HTTPRouteRule() *HTTPRouteRuleApplyConfiguration { return &HTTPRouteRuleApplyConfiguration{} } +// WithName sets the Name 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 Name field is set to the value of the last call. +func (b *HTTPRouteRuleApplyConfiguration) WithName(value v1.SectionName) *HTTPRouteRuleApplyConfiguration { + b.Name = &value + return b +} + // WithMatches adds the given value to the Matches 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 Matches field. diff --git a/apis/applyconfiguration/apis/v1alpha2/tcprouterule.go b/apis/applyconfiguration/apis/v1alpha2/tcprouterule.go index 3c6e418c2f..711556120c 100644 --- a/apis/applyconfiguration/apis/v1alpha2/tcprouterule.go +++ b/apis/applyconfiguration/apis/v1alpha2/tcprouterule.go @@ -19,13 +19,15 @@ limitations under the License. package v1alpha2 import ( - v1 "sigs.k8s.io/gateway-api/apis/applyconfiguration/apis/v1" + apisv1 "sigs.k8s.io/gateway-api/apis/applyconfiguration/apis/v1" + v1 "sigs.k8s.io/gateway-api/apis/v1" ) // TCPRouteRuleApplyConfiguration represents an declarative configuration of the TCPRouteRule type for use // with apply. type TCPRouteRuleApplyConfiguration struct { - BackendRefs []v1.BackendRefApplyConfiguration `json:"backendRefs,omitempty"` + Name *v1.SectionName `json:"name,omitempty"` + BackendRefs []apisv1.BackendRefApplyConfiguration `json:"backendRefs,omitempty"` } // TCPRouteRuleApplyConfiguration constructs an declarative configuration of the TCPRouteRule type for use with @@ -34,10 +36,18 @@ func TCPRouteRule() *TCPRouteRuleApplyConfiguration { return &TCPRouteRuleApplyConfiguration{} } +// WithName sets the Name 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 Name field is set to the value of the last call. +func (b *TCPRouteRuleApplyConfiguration) WithName(value v1.SectionName) *TCPRouteRuleApplyConfiguration { + b.Name = &value + return b +} + // WithBackendRefs adds the given value to the BackendRefs 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 BackendRefs field. -func (b *TCPRouteRuleApplyConfiguration) WithBackendRefs(values ...*v1.BackendRefApplyConfiguration) *TCPRouteRuleApplyConfiguration { +func (b *TCPRouteRuleApplyConfiguration) WithBackendRefs(values ...*apisv1.BackendRefApplyConfiguration) *TCPRouteRuleApplyConfiguration { for i := range values { if values[i] == nil { panic("nil value passed to WithBackendRefs") diff --git a/apis/applyconfiguration/apis/v1alpha2/tlsrouterule.go b/apis/applyconfiguration/apis/v1alpha2/tlsrouterule.go index a2dacdf9b8..d57b6d91f5 100644 --- a/apis/applyconfiguration/apis/v1alpha2/tlsrouterule.go +++ b/apis/applyconfiguration/apis/v1alpha2/tlsrouterule.go @@ -19,13 +19,15 @@ limitations under the License. package v1alpha2 import ( - v1 "sigs.k8s.io/gateway-api/apis/applyconfiguration/apis/v1" + apisv1 "sigs.k8s.io/gateway-api/apis/applyconfiguration/apis/v1" + v1 "sigs.k8s.io/gateway-api/apis/v1" ) // TLSRouteRuleApplyConfiguration represents an declarative configuration of the TLSRouteRule type for use // with apply. type TLSRouteRuleApplyConfiguration struct { - BackendRefs []v1.BackendRefApplyConfiguration `json:"backendRefs,omitempty"` + Name *v1.SectionName `json:"name,omitempty"` + BackendRefs []apisv1.BackendRefApplyConfiguration `json:"backendRefs,omitempty"` } // TLSRouteRuleApplyConfiguration constructs an declarative configuration of the TLSRouteRule type for use with @@ -34,10 +36,18 @@ func TLSRouteRule() *TLSRouteRuleApplyConfiguration { return &TLSRouteRuleApplyConfiguration{} } +// WithName sets the Name 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 Name field is set to the value of the last call. +func (b *TLSRouteRuleApplyConfiguration) WithName(value v1.SectionName) *TLSRouteRuleApplyConfiguration { + b.Name = &value + return b +} + // WithBackendRefs adds the given value to the BackendRefs 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 BackendRefs field. -func (b *TLSRouteRuleApplyConfiguration) WithBackendRefs(values ...*v1.BackendRefApplyConfiguration) *TLSRouteRuleApplyConfiguration { +func (b *TLSRouteRuleApplyConfiguration) WithBackendRefs(values ...*apisv1.BackendRefApplyConfiguration) *TLSRouteRuleApplyConfiguration { for i := range values { if values[i] == nil { panic("nil value passed to WithBackendRefs") diff --git a/apis/applyconfiguration/apis/v1alpha2/udprouterule.go b/apis/applyconfiguration/apis/v1alpha2/udprouterule.go index 8cc077ecc9..0fdf1bf95d 100644 --- a/apis/applyconfiguration/apis/v1alpha2/udprouterule.go +++ b/apis/applyconfiguration/apis/v1alpha2/udprouterule.go @@ -19,13 +19,15 @@ limitations under the License. package v1alpha2 import ( - v1 "sigs.k8s.io/gateway-api/apis/applyconfiguration/apis/v1" + apisv1 "sigs.k8s.io/gateway-api/apis/applyconfiguration/apis/v1" + v1 "sigs.k8s.io/gateway-api/apis/v1" ) // UDPRouteRuleApplyConfiguration represents an declarative configuration of the UDPRouteRule type for use // with apply. type UDPRouteRuleApplyConfiguration struct { - BackendRefs []v1.BackendRefApplyConfiguration `json:"backendRefs,omitempty"` + Name *v1.SectionName `json:"name,omitempty"` + BackendRefs []apisv1.BackendRefApplyConfiguration `json:"backendRefs,omitempty"` } // UDPRouteRuleApplyConfiguration constructs an declarative configuration of the UDPRouteRule type for use with @@ -34,10 +36,18 @@ func UDPRouteRule() *UDPRouteRuleApplyConfiguration { return &UDPRouteRuleApplyConfiguration{} } +// WithName sets the Name 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 Name field is set to the value of the last call. +func (b *UDPRouteRuleApplyConfiguration) WithName(value v1.SectionName) *UDPRouteRuleApplyConfiguration { + b.Name = &value + return b +} + // WithBackendRefs adds the given value to the BackendRefs 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 BackendRefs field. -func (b *UDPRouteRuleApplyConfiguration) WithBackendRefs(values ...*v1.BackendRefApplyConfiguration) *UDPRouteRuleApplyConfiguration { +func (b *UDPRouteRuleApplyConfiguration) WithBackendRefs(values ...*apisv1.BackendRefApplyConfiguration) *UDPRouteRuleApplyConfiguration { for i := range values { if values[i] == nil { panic("nil value passed to WithBackendRefs") diff --git a/apis/applyconfiguration/internal/internal.go b/apis/applyconfiguration/internal/internal.go index 1cec2ab72a..31e4bb33e6 100644 --- a/apis/applyconfiguration/internal/internal.go +++ b/apis/applyconfiguration/internal/internal.go @@ -420,6 +420,9 @@ var schemaYAML = typed.YAMLObject(`types: elementType: namedType: io.k8s.sigs.gateway-api.apis.v1.GRPCRouteMatch elementRelationship: atomic + - name: name + type: + scalar: string - name: sessionPersistence type: namedType: io.k8s.sigs.gateway-api.apis.v1.SessionPersistence @@ -863,6 +866,9 @@ var schemaYAML = typed.YAMLObject(`types: elementType: namedType: io.k8s.sigs.gateway-api.apis.v1.HTTPRouteMatch elementRelationship: atomic + - name: name + type: + scalar: string - name: sessionPersistence type: namedType: io.k8s.sigs.gateway-api.apis.v1.SessionPersistence @@ -1299,6 +1305,9 @@ var schemaYAML = typed.YAMLObject(`types: elementType: namedType: io.k8s.sigs.gateway-api.apis.v1.BackendRef elementRelationship: atomic + - name: name + type: + scalar: string - name: io.k8s.sigs.gateway-api.apis.v1alpha2.TCPRouteSpec map: fields: @@ -1353,6 +1362,9 @@ var schemaYAML = typed.YAMLObject(`types: elementType: namedType: io.k8s.sigs.gateway-api.apis.v1.BackendRef elementRelationship: atomic + - name: name + type: + scalar: string - name: io.k8s.sigs.gateway-api.apis.v1alpha2.TLSRouteSpec map: fields: @@ -1413,6 +1425,9 @@ var schemaYAML = typed.YAMLObject(`types: elementType: namedType: io.k8s.sigs.gateway-api.apis.v1.BackendRef elementRelationship: atomic + - name: name + type: + scalar: string - name: io.k8s.sigs.gateway-api.apis.v1alpha2.UDPRouteSpec map: fields: diff --git a/apis/v1/grpcroute_types.go b/apis/v1/grpcroute_types.go index 18fc2e5eb9..543b34644f 100644 --- a/apis/v1/grpcroute_types.go +++ b/apis/v1/grpcroute_types.go @@ -144,6 +144,7 @@ type GRPCRouteSpec struct { // +optional // +kubebuilder:validation:MaxItems=16 // +kubebuilder:validation:XValidation:message="While 16 rules and 64 matches per rule are allowed, the total number of matches across all rules in a route must be less than 128",rule="(self.size() > 0 ? (has(self[0].matches) ? self[0].matches.size() : 0) : 0) + (self.size() > 1 ? (has(self[1].matches) ? self[1].matches.size() : 0) : 0) + (self.size() > 2 ? (has(self[2].matches) ? self[2].matches.size() : 0) : 0) + (self.size() > 3 ? (has(self[3].matches) ? self[3].matches.size() : 0) : 0) + (self.size() > 4 ? (has(self[4].matches) ? self[4].matches.size() : 0) : 0) + (self.size() > 5 ? (has(self[5].matches) ? self[5].matches.size() : 0) : 0) + (self.size() > 6 ? (has(self[6].matches) ? self[6].matches.size() : 0) : 0) + (self.size() > 7 ? (has(self[7].matches) ? self[7].matches.size() : 0) : 0) + (self.size() > 8 ? (has(self[8].matches) ? self[8].matches.size() : 0) : 0) + (self.size() > 9 ? (has(self[9].matches) ? self[9].matches.size() : 0) : 0) + (self.size() > 10 ? (has(self[10].matches) ? self[10].matches.size() : 0) : 0) + (self.size() > 11 ? (has(self[11].matches) ? self[11].matches.size() : 0) : 0) + (self.size() > 12 ? (has(self[12].matches) ? self[12].matches.size() : 0) : 0) + (self.size() > 13 ? (has(self[13].matches) ? self[13].matches.size() : 0) : 0) + (self.size() > 14 ? (has(self[14].matches) ? self[14].matches.size() : 0) : 0) + (self.size() > 15 ? (has(self[15].matches) ? self[15].matches.size() : 0) : 0) <= 128" + // Rules []GRPCRouteRule `json:"rules,omitempty"` } @@ -151,6 +152,13 @@ type GRPCRouteSpec struct { // conditions (matches), processing it (filters), and forwarding the request to // an API object (backendRefs). type GRPCRouteRule struct { + // Name is the name of the route rule. This name MUST be unique within a Route if it is set. + // + // Support: Extended + // +optional + // + Name *SectionName `json:"name,omitempty"` + // Matches define conditions used for matching the rule against incoming // gRPC requests. Each match is independent, i.e. this rule will be matched // if **any** one of the matches is satisfied. diff --git a/apis/v1/httproute_types.go b/apis/v1/httproute_types.go index 698d2a480f..b6c2e936ef 100644 --- a/apis/v1/httproute_types.go +++ b/apis/v1/httproute_types.go @@ -117,6 +117,7 @@ type HTTPRouteSpec struct { // Rules are a list of HTTP matchers, filters and actions. // // +optional + // // +kubebuilder:validation:MaxItems=16 // +kubebuilder:default={{matches: {{path: {type: "PathPrefix", value: "/"}}}}} // +kubebuilder:validation:XValidation:message="While 16 rules and 64 matches per rule are allowed, the total number of matches across all rules in a route must be less than 128",rule="(self.size() > 0 ? self[0].matches.size() : 0) + (self.size() > 1 ? self[1].matches.size() : 0) + (self.size() > 2 ? self[2].matches.size() : 0) + (self.size() > 3 ? self[3].matches.size() : 0) + (self.size() > 4 ? self[4].matches.size() : 0) + (self.size() > 5 ? self[5].matches.size() : 0) + (self.size() > 6 ? self[6].matches.size() : 0) + (self.size() > 7 ? self[7].matches.size() : 0) + (self.size() > 8 ? self[8].matches.size() : 0) + (self.size() > 9 ? self[9].matches.size() : 0) + (self.size() > 10 ? self[10].matches.size() : 0) + (self.size() > 11 ? self[11].matches.size() : 0) + (self.size() > 12 ? self[12].matches.size() : 0) + (self.size() > 13 ? self[13].matches.size() : 0) + (self.size() > 14 ? self[14].matches.size() : 0) + (self.size() > 15 ? self[15].matches.size() : 0) <= 128" @@ -133,6 +134,13 @@ type HTTPRouteSpec struct { // +kubebuilder:validation:XValidation:message="Within backendRefs, when using RequestRedirect filter with path.replacePrefixMatch, exactly one PathPrefix match must be specified",rule="(has(self.backendRefs) && self.backendRefs.exists_one(b, (has(b.filters) && b.filters.exists_one(f, has(f.requestRedirect) && has(f.requestRedirect.path) && f.requestRedirect.path.type == 'ReplacePrefixMatch' && has(f.requestRedirect.path.replacePrefixMatch))) )) ? ((size(self.matches) != 1 || !has(self.matches[0].path) || self.matches[0].path.type != 'PathPrefix') ? false : true) : true" // +kubebuilder:validation:XValidation:message="Within backendRefs, When using URLRewrite filter with path.replacePrefixMatch, exactly one PathPrefix match must be specified",rule="(has(self.backendRefs) && self.backendRefs.exists_one(b, (has(b.filters) && b.filters.exists_one(f, has(f.urlRewrite) && has(f.urlRewrite.path) && f.urlRewrite.path.type == 'ReplacePrefixMatch' && has(f.urlRewrite.path.replacePrefixMatch))) )) ? ((size(self.matches) != 1 || !has(self.matches[0].path) || self.matches[0].path.type != 'PathPrefix') ? false : true) : true" type HTTPRouteRule struct { + // Name is the name of the route rule. This name MUST be unique within a Route if it is set. + // + // Support: Extended + // +optional + // + Name *SectionName `json:"name,omitempty"` + // Matches define conditions used for matching the rule against incoming // HTTP requests. Each match is independent, i.e. this rule will be matched // if **any** one of the matches is satisfied. diff --git a/apis/v1/zz_generated.deepcopy.go b/apis/v1/zz_generated.deepcopy.go index c7ceaf0dfa..02906dc1a6 100644 --- a/apis/v1/zz_generated.deepcopy.go +++ b/apis/v1/zz_generated.deepcopy.go @@ -369,6 +369,11 @@ func (in *GRPCRouteMatch) DeepCopy() *GRPCRouteMatch { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GRPCRouteRule) DeepCopyInto(out *GRPCRouteRule) { *out = *in + if in.Name != nil { + in, out := &in.Name, &out.Name + *out = new(SectionName) + **out = **in + } if in.Matches != nil { in, out := &in.Matches, &out.Matches *out = make([]GRPCRouteMatch, len(*in)) @@ -1164,6 +1169,11 @@ func (in *HTTPRouteMatch) DeepCopy() *HTTPRouteMatch { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HTTPRouteRule) DeepCopyInto(out *HTTPRouteRule) { *out = *in + if in.Name != nil { + in, out := &in.Name, &out.Name + *out = new(SectionName) + **out = **in + } if in.Matches != nil { in, out := &in.Matches, &out.Matches *out = make([]HTTPRouteMatch, len(*in)) diff --git a/apis/v1alpha2/tcproute_types.go b/apis/v1alpha2/tcproute_types.go index fe927ab8d4..b79253dd33 100644 --- a/apis/v1alpha2/tcproute_types.go +++ b/apis/v1alpha2/tcproute_types.go @@ -49,6 +49,7 @@ type TCPRouteSpec struct { // // +kubebuilder:validation:MinItems=1 // +kubebuilder:validation:MaxItems=16 + // Rules []TCPRouteRule `json:"rules"` } @@ -59,6 +60,12 @@ type TCPRouteStatus struct { // TCPRouteRule is the configuration for a given rule. type TCPRouteRule struct { + // Name is the name of the route rule. This name MUST be unique within a Route if it is set. + // + // Support: Extended + // +optional + Name *SectionName `json:"name,omitempty"` + // BackendRefs defines the backend(s) where matching requests should be // sent. If unspecified or invalid (refers to a non-existent resource or a // Service with no endpoints), the underlying implementation MUST actively diff --git a/apis/v1alpha2/tlsroute_types.go b/apis/v1alpha2/tlsroute_types.go index afe34d82d6..26dfde77c7 100644 --- a/apis/v1alpha2/tlsroute_types.go +++ b/apis/v1alpha2/tlsroute_types.go @@ -90,6 +90,7 @@ type TLSRouteSpec struct { // // +kubebuilder:validation:MinItems=1 // +kubebuilder:validation:MaxItems=16 + // Rules []TLSRouteRule `json:"rules"` } @@ -100,6 +101,12 @@ type TLSRouteStatus struct { // TLSRouteRule is the configuration for a given rule. type TLSRouteRule struct { + // Name is the name of the route rule. This name MUST be unique within a Route if it is set. + // + // Support: Extended + // +optional + Name *SectionName `json:"name,omitempty"` + // BackendRefs defines the backend(s) where matching requests should be // sent. If unspecified or invalid (refers to a non-existent resource or // a Service with no endpoints), the rule performs no forwarding; if no diff --git a/apis/v1alpha2/udproute_types.go b/apis/v1alpha2/udproute_types.go index 9e3770c293..9e7fe3ff80 100644 --- a/apis/v1alpha2/udproute_types.go +++ b/apis/v1alpha2/udproute_types.go @@ -49,6 +49,7 @@ type UDPRouteSpec struct { // // +kubebuilder:validation:MinItems=1 // +kubebuilder:validation:MaxItems=16 + // Rules []UDPRouteRule `json:"rules"` } @@ -59,6 +60,12 @@ type UDPRouteStatus struct { // UDPRouteRule is the configuration for a given rule. type UDPRouteRule struct { + // Name is the name of the route rule. This name MUST be unique within a Route if it is set. + // + // Support: Extended + // +optional + Name *SectionName `json:"name,omitempty"` + // BackendRefs defines the backend(s) where matching requests should be // sent. If unspecified or invalid (refers to a non-existent resource or a // Service with no endpoints), the underlying implementation MUST actively diff --git a/apis/v1alpha2/zz_generated.deepcopy.go b/apis/v1alpha2/zz_generated.deepcopy.go index 3bf9f0fbe6..5306ca135d 100644 --- a/apis/v1alpha2/zz_generated.deepcopy.go +++ b/apis/v1alpha2/zz_generated.deepcopy.go @@ -390,6 +390,11 @@ func (in *TCPRouteList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TCPRouteRule) DeepCopyInto(out *TCPRouteRule) { *out = *in + if in.Name != nil { + in, out := &in.Name, &out.Name + *out = new(v1.SectionName) + **out = **in + } if in.BackendRefs != nil { in, out := &in.BackendRefs, &out.BackendRefs *out = make([]v1.BackendRef, len(*in)) @@ -510,6 +515,11 @@ func (in *TLSRouteList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TLSRouteRule) DeepCopyInto(out *TLSRouteRule) { *out = *in + if in.Name != nil { + in, out := &in.Name, &out.Name + *out = new(v1.SectionName) + **out = **in + } if in.BackendRefs != nil { in, out := &in.BackendRefs, &out.BackendRefs *out = make([]v1.BackendRef, len(*in)) @@ -635,6 +645,11 @@ func (in *UDPRouteList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *UDPRouteRule) DeepCopyInto(out *UDPRouteRule) { *out = *in + if in.Name != nil { + in, out := &in.Name, &out.Name + *out = new(v1.SectionName) + **out = **in + } if in.BackendRefs != nil { in, out := &in.BackendRefs, &out.BackendRefs *out = make([]v1.BackendRef, len(*in)) diff --git a/config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml b/config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml index ceb4a0d05c..e47547eac1 100644 --- a/config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml +++ b/config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml @@ -441,7 +441,10 @@ spec: || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port)))) rules: - description: Rules are a list of GRPC matchers, filters and actions. + description: |+ + Rules are a list of GRPC matchers, filters and actions. + + items: description: |- GRPCRouteRule defines the semantics for matching a gRPC request based on @@ -1927,6 +1930,16 @@ spec: type: object maxItems: 8 type: array + name: + description: | + Name is the name of the route rule. This name MUST be unique within a Route if it is set. + + + Support: Extended + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string sessionPersistence: description: |+ SessionPersistence defines and configures session persistence @@ -2051,6 +2064,9 @@ spec: : 0) : 0) + (self.size() > 14 ? (has(self[14].matches) ? self[14].matches.size() : 0) : 0) + (self.size() > 15 ? (has(self[15].matches) ? self[15].matches.size() : 0) : 0) <= 128' + - message: Rule name must be unique within the route + rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) + && l1.name == l2.name)) type: object status: description: Status defines the current state of GRPCRoute. @@ -2789,7 +2805,10 @@ spec: || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port)))) rules: - description: Rules are a list of GRPC matchers, filters and actions. + description: |+ + Rules are a list of GRPC matchers, filters and actions. + + items: description: |- GRPCRouteRule defines the semantics for matching a gRPC request based on @@ -4275,6 +4294,16 @@ spec: type: object maxItems: 8 type: array + name: + description: | + Name is the name of the route rule. This name MUST be unique within a Route if it is set. + + + Support: Extended + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string sessionPersistence: description: |+ SessionPersistence defines and configures session persistence @@ -4399,6 +4428,9 @@ spec: : 0) : 0) + (self.size() > 14 ? (has(self[14].matches) ? self[14].matches.size() : 0) : 0) + (self.size() > 15 ? (has(self[15].matches) ? self[15].matches.size() : 0) : 0) <= 128' + - message: Rule name must be unique within the route + rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) + && l1.name == l2.name)) type: object status: description: Status defines the current state of GRPCRoute. diff --git a/config/crd/experimental/gateway.networking.k8s.io_httproutes.yaml b/config/crd/experimental/gateway.networking.k8s.io_httproutes.yaml index e10f21893c..18ace973b6 100644 --- a/config/crd/experimental/gateway.networking.k8s.io_httproutes.yaml +++ b/config/crd/experimental/gateway.networking.k8s.io_httproutes.yaml @@ -424,7 +424,10 @@ spec: - path: type: PathPrefix value: / - description: Rules are a list of HTTP matchers, filters and actions. + description: |+ + Rules are a list of HTTP matchers, filters and actions. + + items: description: |- HTTPRouteRule defines semantics for matching an HTTP request based on @@ -2714,6 +2717,16 @@ spec: type: object maxItems: 64 type: array + name: + description: | + Name is the name of the route rule. This name MUST be unique within a Route if it is set. + + + Support: Extended + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string sessionPersistence: description: |+ SessionPersistence defines and configures session persistence @@ -2944,6 +2957,9 @@ spec: : 0) + (self.size() > 12 ? self[12].matches.size() : 0) + (self.size() > 13 ? self[13].matches.size() : 0) + (self.size() > 14 ? self[14].matches.size() : 0) + (self.size() > 15 ? self[15].matches.size() : 0) <= 128' + - message: Rule name must be unique within the route + rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) + && l1.name == l2.name)) type: object status: description: Status defines the current state of HTTPRoute. @@ -3671,7 +3687,10 @@ spec: - path: type: PathPrefix value: / - description: Rules are a list of HTTP matchers, filters and actions. + description: |+ + Rules are a list of HTTP matchers, filters and actions. + + items: description: |- HTTPRouteRule defines semantics for matching an HTTP request based on @@ -5961,6 +5980,16 @@ spec: type: object maxItems: 64 type: array + name: + description: | + Name is the name of the route rule. This name MUST be unique within a Route if it is set. + + + Support: Extended + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string sessionPersistence: description: |+ SessionPersistence defines and configures session persistence @@ -6191,6 +6220,9 @@ spec: : 0) + (self.size() > 12 ? self[12].matches.size() : 0) + (self.size() > 13 ? self[13].matches.size() : 0) + (self.size() > 14 ? self[14].matches.size() : 0) + (self.size() > 15 ? self[15].matches.size() : 0) <= 128' + - message: Rule name must be unique within the route + rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) + && l1.name == l2.name)) type: object status: description: Status defines the current state of HTTPRoute. diff --git a/config/crd/experimental/gateway.networking.k8s.io_tcproutes.yaml b/config/crd/experimental/gateway.networking.k8s.io_tcproutes.yaml index 35917cfbd9..81ae85c566 100644 --- a/config/crd/experimental/gateway.networking.k8s.io_tcproutes.yaml +++ b/config/crd/experimental/gateway.networking.k8s.io_tcproutes.yaml @@ -324,7 +324,10 @@ spec: || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port)))) rules: - description: Rules are a list of TCP matchers and actions. + description: |+ + Rules are a list of TCP matchers and actions. + + items: description: TCPRouteRule is the configuration for a given rule. properties: @@ -486,10 +489,24 @@ spec: maxItems: 16 minItems: 1 type: array + name: + description: |- + Name is the name of the route rule. This name MUST be unique within a Route if it is set. + + + Support: Extended + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string type: object maxItems: 16 minItems: 1 type: array + x-kubernetes-validations: + - message: Rule name must be unique within the route + rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) + && l1.name == l2.name)) required: - rules type: object diff --git a/config/crd/experimental/gateway.networking.k8s.io_tlsroutes.yaml b/config/crd/experimental/gateway.networking.k8s.io_tlsroutes.yaml index 47bbd3a7d6..aadc14594c 100644 --- a/config/crd/experimental/gateway.networking.k8s.io_tlsroutes.yaml +++ b/config/crd/experimental/gateway.networking.k8s.io_tlsroutes.yaml @@ -394,7 +394,10 @@ spec: || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port)))) rules: - description: Rules are a list of TLS matchers and actions. + description: |+ + Rules are a list of TLS matchers and actions. + + items: description: TLSRouteRule is the configuration for a given rule. properties: @@ -559,10 +562,24 @@ spec: maxItems: 16 minItems: 1 type: array + name: + description: |- + Name is the name of the route rule. This name MUST be unique within a Route if it is set. + + + Support: Extended + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string type: object maxItems: 16 minItems: 1 type: array + x-kubernetes-validations: + - message: Rule name must be unique within the route + rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) + && l1.name == l2.name)) required: - rules type: object diff --git a/config/crd/experimental/gateway.networking.k8s.io_udproutes.yaml b/config/crd/experimental/gateway.networking.k8s.io_udproutes.yaml index d399e27c0e..45e28da0bb 100644 --- a/config/crd/experimental/gateway.networking.k8s.io_udproutes.yaml +++ b/config/crd/experimental/gateway.networking.k8s.io_udproutes.yaml @@ -324,7 +324,10 @@ spec: || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port)))) rules: - description: Rules are a list of UDP matchers and actions. + description: |+ + Rules are a list of UDP matchers and actions. + + items: description: UDPRouteRule is the configuration for a given rule. properties: @@ -486,10 +489,24 @@ spec: maxItems: 16 minItems: 1 type: array + name: + description: |- + Name is the name of the route rule. This name MUST be unique within a Route if it is set. + + + Support: Extended + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string type: object maxItems: 16 minItems: 1 type: array + x-kubernetes-validations: + - message: Rule name must be unique within the route + rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) + && l1.name == l2.name)) required: - rules type: object diff --git a/config/crd/standard/gateway.networking.k8s.io_grpcroutes.yaml b/config/crd/standard/gateway.networking.k8s.io_grpcroutes.yaml index 4763f3c94b..01fc863825 100644 --- a/config/crd/standard/gateway.networking.k8s.io_grpcroutes.yaml +++ b/config/crd/standard/gateway.networking.k8s.io_grpcroutes.yaml @@ -412,7 +412,10 @@ spec: == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)))) rules: - description: Rules are a list of GRPC matchers, filters and actions. + description: |+ + Rules are a list of GRPC matchers, filters and actions. + + items: description: |- GRPCRouteRule defines the semantics for matching a gRPC request based on @@ -2616,7 +2619,10 @@ spec: == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)))) rules: - description: Rules are a list of GRPC matchers, filters and actions. + description: |+ + Rules are a list of GRPC matchers, filters and actions. + + items: description: |- GRPCRouteRule defines the semantics for matching a gRPC request based on diff --git a/config/crd/standard/gateway.networking.k8s.io_httproutes.yaml b/config/crd/standard/gateway.networking.k8s.io_httproutes.yaml index dcbae42b7e..6a4a9b6fe1 100644 --- a/config/crd/standard/gateway.networking.k8s.io_httproutes.yaml +++ b/config/crd/standard/gateway.networking.k8s.io_httproutes.yaml @@ -395,7 +395,10 @@ spec: - path: type: PathPrefix value: / - description: Rules are a list of HTTP matchers, filters and actions. + description: |+ + Rules are a list of HTTP matchers, filters and actions. + + items: description: |- HTTPRouteRule defines semantics for matching an HTTP request based on @@ -3498,7 +3501,10 @@ spec: - path: type: PathPrefix value: / - description: Rules are a list of HTTP matchers, filters and actions. + description: |+ + Rules are a list of HTTP matchers, filters and actions. + + items: description: |- HTTPRouteRule defines semantics for matching an HTTP request based on diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index aa573c1ba5..b57c621df3 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -3285,6 +3285,13 @@ func schema_sigsk8sio_gateway_api_apis_v1_GRPCRouteRule(ref common.ReferenceCall Description: "GRPCRouteRule defines the semantics for matching a gRPC request based on conditions (matches), processing it (filters), and forwarding the request to an API object (backendRefs).", Type: []string{"object"}, Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Name is the name of the route rule. This name MUST be unique within a Route if it is set.\n\nSupport: Extended ", + Type: []string{"string"}, + Format: "", + }, + }, "matches": { SchemaProps: spec.SchemaProps{ Description: "Matches define conditions used for matching the rule against incoming gRPC requests. Each match is independent, i.e. this rule will be matched if **any** one of the matches is satisfied.\n\nFor example, take the following matches configuration:\n\n``` matches: - method:\n service: foo.bar\n headers:\n values:\n version: 2\n- method:\n service: foo.bar.v2\n```\n\nFor a request to match against this rule, it MUST satisfy EITHER of the two conditions:\n\n- service of foo.bar AND contains the header `version: 2` - service of foo.bar.v2\n\nSee the documentation for GRPCRouteMatch on how to specify multiple match conditions to be ANDed together.\n\nIf no matches are specified, the implementation MUST match every gRPC request.\n\nProxy or Load Balancer routing configuration generated from GRPCRoutes MUST prioritize rules based on the following criteria, continuing on ties. Merging MUST not be done between GRPCRoutes and HTTPRoutes. Precedence MUST be given to the rule with the largest number of:\n\n* Characters in a matching non-wildcard hostname. * Characters in a matching hostname. * Characters in a matching service. * Characters in a matching method. * Header matches.\n\nIf ties still exist across multiple Routes, matching precedence MUST be determined in order of the following criteria, continuing on ties:\n\n* The oldest Route based on creation timestamp. * The Route appearing first in alphabetical order by\n \"{namespace}/{name}\".\n\nIf ties still exist within the Route that has been given precedence, matching precedence MUST be granted to the first matching rule meeting the above criteria.", @@ -3379,7 +3386,7 @@ func schema_sigsk8sio_gateway_api_apis_v1_GRPCRouteSpec(ref common.ReferenceCall }, "rules": { SchemaProps: spec.SchemaProps{ - Description: "Rules are a list of GRPC matchers, filters and actions.", + Description: "Rules are a list of GRPC matchers, filters and actions.\n\n", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -4660,6 +4667,13 @@ func schema_sigsk8sio_gateway_api_apis_v1_HTTPRouteRule(ref common.ReferenceCall Description: "HTTPRouteRule defines semantics for matching an HTTP request based on conditions (matches), processing it (filters), and forwarding the request to an API object (backendRefs).", Type: []string{"object"}, Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Name is the name of the route rule. This name MUST be unique within a Route if it is set.\n\nSupport: Extended ", + Type: []string{"string"}, + Format: "", + }, + }, "matches": { SchemaProps: spec.SchemaProps{ Description: "Matches define conditions used for matching the rule against incoming HTTP requests. Each match is independent, i.e. this rule will be matched if **any** one of the matches is satisfied.\n\nFor example, take the following matches configuration:\n\n``` matches: - path:\n value: \"/foo\"\n headers:\n - name: \"version\"\n value: \"v2\"\n- path:\n value: \"/v2/foo\"\n```\n\nFor a request to match against this rule, a request must satisfy EITHER of the two conditions:\n\n- path prefixed with `/foo` AND contains the header `version: v2` - path prefix of `/v2/foo`\n\nSee the documentation for HTTPRouteMatch on how to specify multiple match conditions that should be ANDed together.\n\nIf no matches are specified, the default is a prefix path match on \"/\", which has the effect of matching every HTTP request.\n\nProxy or Load Balancer routing configuration generated from HTTPRoutes MUST prioritize matches based on the following criteria, continuing on ties. Across all rules specified on applicable Routes, precedence must be given to the match having:\n\n* \"Exact\" path match. * \"Prefix\" path match with largest number of characters. * Method match. * Largest number of header matches. * Largest number of query param matches.\n\nNote: The precedence of RegularExpression path matches are implementation-specific.\n\nIf ties still exist across multiple Routes, matching precedence MUST be determined in order of the following criteria, continuing on ties:\n\n* The oldest Route based on creation timestamp. * The Route appearing first in alphabetical order by\n \"{namespace}/{name}\".\n\nIf ties still exist within an HTTPRoute, matching precedence MUST be granted to the FIRST matching rule (in list order) with a match meeting the above criteria.\n\nWhen no rules matching a request have been successfully attached to the parent a request is coming from, a HTTP 404 status code MUST be returned.", @@ -4760,7 +4774,7 @@ func schema_sigsk8sio_gateway_api_apis_v1_HTTPRouteSpec(ref common.ReferenceCall }, "rules": { SchemaProps: spec.SchemaProps{ - Description: "Rules are a list of HTTP matchers, filters and actions.", + Description: "Rules are a list of HTTP matchers, filters and actions.\n\n", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -6116,6 +6130,13 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_TCPRouteRule(ref common.Referenc Description: "TCPRouteRule is the configuration for a given rule.", Type: []string{"object"}, Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Name is the name of the route rule. This name MUST be unique within a Route if it is set.\n\nSupport: Extended", + Type: []string{"string"}, + Format: "", + }, + }, "backendRefs": { SchemaProps: spec.SchemaProps{ Description: "BackendRefs defines the backend(s) where matching requests should be sent. If unspecified or invalid (refers to a non-existent resource or a Service with no endpoints), the underlying implementation MUST actively reject connection attempts to this backend. Connection rejections must respect weight; if an invalid backend is requested to have 80% of connections, then 80% of connections must be rejected instead.\n\nSupport: Core for Kubernetes Service\n\nSupport: Extended for Kubernetes ServiceImport\n\nSupport: Implementation-specific for any other resource\n\nSupport for weight: Extended", @@ -6161,7 +6182,7 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_TCPRouteSpec(ref common.Referenc }, "rules": { SchemaProps: spec.SchemaProps{ - Description: "Rules are a list of TCP matchers and actions.", + Description: "Rules are a list of TCP matchers and actions.\n\n", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -6318,6 +6339,13 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_TLSRouteRule(ref common.Referenc Description: "TLSRouteRule is the configuration for a given rule.", Type: []string{"object"}, Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Name is the name of the route rule. This name MUST be unique within a Route if it is set.\n\nSupport: Extended", + Type: []string{"string"}, + Format: "", + }, + }, "backendRefs": { SchemaProps: spec.SchemaProps{ Description: "BackendRefs defines the backend(s) where matching requests should be sent. If unspecified or invalid (refers to a non-existent resource or a Service with no endpoints), the rule performs no forwarding; if no filters are specified that would result in a response being sent, the underlying implementation must actively reject request attempts to this backend, by rejecting the connection or returning a 500 status code. Request rejections must respect weight; if an invalid backend is requested to have 80% of requests, then 80% of requests must be rejected instead.\n\nSupport: Core for Kubernetes Service\n\nSupport: Extended for Kubernetes ServiceImport\n\nSupport: Implementation-specific for any other resource\n\nSupport for weight: Extended", @@ -6378,7 +6406,7 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_TLSRouteSpec(ref common.Referenc }, "rules": { SchemaProps: spec.SchemaProps{ - Description: "Rules are a list of TLS matchers and actions.", + Description: "Rules are a list of TLS matchers and actions.\n\n", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -6535,6 +6563,13 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_UDPRouteRule(ref common.Referenc Description: "UDPRouteRule is the configuration for a given rule.", Type: []string{"object"}, Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Name is the name of the route rule. This name MUST be unique within a Route if it is set.\n\nSupport: Extended", + Type: []string{"string"}, + Format: "", + }, + }, "backendRefs": { SchemaProps: spec.SchemaProps{ Description: "BackendRefs defines the backend(s) where matching requests should be sent. If unspecified or invalid (refers to a non-existent resource or a Service with no endpoints), the underlying implementation MUST actively reject connection attempts to this backend. Packet drops must respect weight; if an invalid backend is requested to have 80% of the packets, then 80% of packets must be dropped instead.\n\nSupport: Core for Kubernetes Service\n\nSupport: Extended for Kubernetes ServiceImport\n\nSupport: Implementation-specific for any other resource\n\nSupport for weight: Extended", @@ -6580,7 +6615,7 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_UDPRouteSpec(ref common.Referenc }, "rules": { SchemaProps: spec.SchemaProps{ - Description: "Rules are a list of UDP matchers and actions.", + Description: "Rules are a list of UDP matchers and actions.\n\n", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ diff --git a/pkg/test/cel/httproute_experimental_test.go b/pkg/test/cel/httproute_experimental_test.go index 0e9c3c4cee..e46ee9299f 100644 --- a/pkg/test/cel/httproute_experimental_test.go +++ b/pkg/test/cel/httproute_experimental_test.go @@ -372,3 +372,63 @@ func TestHTTPRouteTimeouts(t *testing.T) { }) } } + +func TestHTTPRouteRuleExperimental(t *testing.T) { + tests := []struct { + name string + wantErrors []string + rules []gatewayv1.HTTPRouteRule + }{ + { + name: "invalid because multiple names are repeated", + wantErrors: []string{"Rule name must be unique within the route"}, + rules: []gatewayv1.HTTPRouteRule{ + { + Name: ptrTo(gatewayv1.SectionName("name1")), + }, + { + Name: ptrTo(gatewayv1.SectionName("name1")), + }, + }, + }, + { + name: "invalid because multiple names are repeated with others", + wantErrors: []string{"Rule name must be unique within the route"}, + rules: []gatewayv1.HTTPRouteRule{ + { + Name: ptrTo(gatewayv1.SectionName("name1")), + }, + { + Name: ptrTo(gatewayv1.SectionName("not-name1")), + }, + { + Name: ptrTo(gatewayv1.SectionName("name1")), + }, + }, + }, + { + name: "valid because names are unique", + wantErrors: nil, + rules: []gatewayv1.HTTPRouteRule{ + // Ok to have multiple nil + {Name: nil}, + {Name: nil}, + {Name: ptrTo(gatewayv1.SectionName("name1"))}, + {Name: ptrTo(gatewayv1.SectionName("name2"))}, + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + route := &gatewayv1.HTTPRoute{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("foo-%v", time.Now().UnixNano()), + Namespace: metav1.NamespaceDefault, + }, + Spec: gatewayv1.HTTPRouteSpec{Rules: tc.rules}, + } + validateHTTPRoute(t, route, tc.wantErrors) + }) + } +} diff --git a/pkg/test/cel/httproute_test.go b/pkg/test/cel/httproute_test.go index 63b32ca3c5..a20a70cf27 100644 --- a/pkg/test/cel/httproute_test.go +++ b/pkg/test/cel/httproute_test.go @@ -23,9 +23,9 @@ import ( "testing" "time" - gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" ) ////////////////////////////////////////////////////////////////////////////////