diff --git a/api/v1alpha1/loadbalancer_types.go b/api/v1alpha1/loadbalancer_types.go index 3bd4d9c4e54..2a0fb21e515 100644 --- a/api/v1alpha1/loadbalancer_types.go +++ b/api/v1alpha1/loadbalancer_types.go @@ -18,7 +18,7 @@ type LoadBalancer struct { // "ConsistentHash", // "LeastRequest", // "Random", - // "RoundRobin", + // "RoundRobin". // // +unionDiscriminator Type LoadBalancerType `json:"type"` @@ -52,18 +52,39 @@ const ( ) // ConsistentHash defines the configuration related to the consistent hash -// load balancer policy +// load balancer policy. +// +union +// +// +kubebuilder:validation:XValidation:rule="self.type == 'Header' ? has(self.header) : !has(self.header)",message="If consistent hash type is header, the header field must be set." type ConsistentHash struct { + // Valid Type values are "SourceIP". + // + // +unionDiscriminator Type ConsistentHashType `json:"type"` + + // Header configures the header hash policy when the consistent hash type is set to Header. + // + // +optional + // +notImplementedHide + Header *Header `json:"header,omitempty"` +} + +// Header defines the header hashing configuration for consistent hash based +// load balancing. +type Header struct { + // Name of the header to hash. + Name string `json:"name"` } // ConsistentHashType defines the type of input to hash on. -// +kubebuilder:validation:Enum=SourceIP +// +kubebuilder:validation:Enum=SourceIP;Header type ConsistentHashType string const ( // SourceIPConsistentHashType hashes based on the source IP address. SourceIPConsistentHashType ConsistentHashType = "SourceIP" + // HeaderConsistentHashType hashes based on a request header. + HeaderConsistentHashType ConsistentHashType = "Header" ) // SlowStart defines the configuration related to the slow start load balancer policy. diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 8ebd4453c5c..71f09022f35 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -751,6 +751,11 @@ func (in *ConnectionLimit) DeepCopy() *ConnectionLimit { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ConsistentHash) DeepCopyInto(out *ConsistentHash) { *out = *in + if in.Header != nil { + in, out := &in.Header, &out.Header + *out = new(Header) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConsistentHash. @@ -2225,6 +2230,21 @@ func (in *HTTPWasmCodeSource) DeepCopy() *HTTPWasmCodeSource { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Header) DeepCopyInto(out *Header) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Header. +func (in *Header) DeepCopy() *Header { + if in == nil { + return nil + } + out := new(Header) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HeaderMatch) DeepCopyInto(out *HeaderMatch) { *out = *in @@ -2865,7 +2885,7 @@ func (in *LoadBalancer) DeepCopyInto(out *LoadBalancer) { if in.ConsistentHash != nil { in, out := &in.ConsistentHash, &out.ConsistentHash *out = new(ConsistentHash) - **out = **in + (*in).DeepCopyInto(*out) } if in.SlowStart != nil { in, out := &in.SlowStart, &out.SlowStart diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml index eb8457a116b..ba195c65408 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml @@ -412,15 +412,29 @@ spec: ConsistentHash defines the configuration when the load balancer type is set to ConsistentHash properties: + header: + description: Header configures the header hash policy when + the consistent hash type is set to Header. + properties: + name: + description: Name of the header to hash. + type: string + required: + - name + type: object type: - description: ConsistentHashType defines the type of input - to hash on. + description: Valid Type values are "SourceIP". enum: - SourceIP + - Header type: string required: - type type: object + x-kubernetes-validations: + - message: If consistent hash type is header, the header field + must be set. + rule: 'self.type == ''Header'' ? has(self.header) : !has(self.header)' slowStart: description: |- SlowStart defines the configuration related to the slow start load balancer policy. @@ -444,7 +458,7 @@ spec: "ConsistentHash", "LeastRequest", "Random", - "RoundRobin", + "RoundRobin". enum: - ConsistentHash - LeastRequest diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index c00e9d8a915..cb74c44f487 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -555,14 +555,14 @@ _Appears in:_ ConsistentHash defines the configuration related to the consistent hash -load balancer policy +load balancer policy. _Appears in:_ - [LoadBalancer](#loadbalancer) | Field | Type | Required | Description | | --- | --- | --- | --- | -| `type` | _[ConsistentHashType](#consistenthashtype)_ | true | | +| `type` | _[ConsistentHashType](#consistenthashtype)_ | true | Valid Type values are "SourceIP". | #### ConsistentHashType @@ -577,6 +577,7 @@ _Appears in:_ | Value | Description | | ----- | ----------- | | `SourceIP` | SourceIPConsistentHashType hashes based on the source IP address.
| +| `Header` | HeaderConsistentHashType hashes based on a request header.
| #### CustomHeaderExtensionSettings @@ -1624,6 +1625,21 @@ _Appears in:_ | `url` | _string_ | true | URL is the URL containing the wasm code. | +#### Header + + + +Header defines the header hashing configuration for consistent hash based +load balancing. + +_Appears in:_ +- [ConsistentHash](#consistenthash) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `name` | _string_ | true | Name of the header to hash. | + + #### HeaderMatchType @@ -2018,7 +2034,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `type` | _[LoadBalancerType](#loadbalancertype)_ | true | Type decides the type of Load Balancer policy.
Valid LoadBalancerType values are
"ConsistentHash",
"LeastRequest",
"Random",
"RoundRobin", | +| `type` | _[LoadBalancerType](#loadbalancertype)_ | true | Type decides the type of Load Balancer policy.
Valid LoadBalancerType values are
"ConsistentHash",
"LeastRequest",
"Random",
"RoundRobin". | | `consistentHash` | _[ConsistentHash](#consistenthash)_ | false | ConsistentHash defines the configuration when the load balancer type is
set to ConsistentHash | | `slowStart` | _[SlowStart](#slowstart)_ | false | SlowStart defines the configuration related to the slow start load balancer policy.
If set, during slow start window, traffic sent to the newly added hosts will gradually increase.
Currently this is only supported for RoundRobin and LeastRequest load balancers | diff --git a/test/cel-validation/backendtrafficpolicy_test.go b/test/cel-validation/backendtrafficpolicy_test.go index a1dd7ac7eb7..187fae39929 100644 --- a/test/cel-validation/backendtrafficpolicy_test.go +++ b/test/cel-validation/backendtrafficpolicy_test.go @@ -194,6 +194,53 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { "spec.loadBalancer: Invalid value: \"object\": If LoadBalancer type is consistentHash, consistentHash field needs to be set", }, }, + { + desc: "consistentHash header field not nil when consistentHashType is header", + mutate: func(btp *egv1a1.BackendTrafficPolicy) { + btp.Spec = egv1a1.BackendTrafficPolicySpec{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ + Group: gwapiv1a2.Group("gateway.networking.k8s.io"), + Kind: gwapiv1a2.Kind("Gateway"), + Name: gwapiv1a2.ObjectName("eg"), + }, + }, + LoadBalancer: &egv1a1.LoadBalancer{ + Type: egv1a1.ConsistentHashLoadBalancerType, + ConsistentHash: &egv1a1.ConsistentHash{ + Type: "Header", + Header: &egv1a1.Header{ + Name: "name", + }, + }, + }, + } + }, + wantErrors: []string{}, + }, + { + desc: "consistentHash header field nil when consistentHashType is header", + mutate: func(btp *egv1a1.BackendTrafficPolicy) { + btp.Spec = egv1a1.BackendTrafficPolicySpec{ + TargetRef: gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ + Group: gwapiv1a2.Group("gateway.networking.k8s.io"), + Kind: gwapiv1a2.Kind("Gateway"), + Name: gwapiv1a2.ObjectName("eg"), + }, + }, + LoadBalancer: &egv1a1.LoadBalancer{ + Type: egv1a1.ConsistentHashLoadBalancerType, + ConsistentHash: &egv1a1.ConsistentHash{ + Type: "Header", + }, + }, + } + }, + wantErrors: []string{ + "spec.loadBalancer.consistentHash: Invalid value: \"object\": If consistent hash type is header, the header field must be set", + }, + }, { desc: "leastRequest with ConsistentHash nil", mutate: func(btp *egv1a1.BackendTrafficPolicy) {