Skip to content

Commit ebea924

Browse files
refactor: move merge default to parent policy defaultChildMergeType
Replace the EnvoyProxy policyDefaults API with a defaultChildMergeType field on Gateway-targeting BackendTrafficPolicies, following GEP-713. A child policy without its own mergeType merges into the closest parent policy using its defaultChildMergeType; an explicit mergeType (including Replace, allowed by a separate change) always wins. Signed-off-by: Maksim Kuchkovskiy <K.Maksim.E@yandex.ru>
1 parent 0e3e12d commit ebea924

30 files changed

Lines changed: 293 additions & 1031 deletions

File tree

api/v1alpha1/backendtrafficpolicy_types.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ type BackendTrafficPolicy struct {
4646
// +kubebuilder:validation:XValidation:rule="!has(self.compression) || !has(self.compressor)", message="either compression or compressor can be set, not both"
4747
// +kubebuilder:validation:XValidation:rule="!has(self.requestBuffer) || !has(self.httpUpgrade) || self.httpUpgrade.size() == 0", message="requestBuffer cannot be used together with httpUpgrade"
4848
// +kubebuilder:validation:XValidation:rule="!has(self.admissionControl) || ((!has(self.targetRef) || self.targetRef.kind in ['Gateway', 'HTTPRoute', 'GRPCRoute']) && (!has(self.targetRefs) || self.targetRefs.all(ref, ref.kind in ['Gateway', 'HTTPRoute', 'GRPCRoute'])) && (!has(self.targetSelectors) || self.targetSelectors.all(sel, sel.kind in ['Gateway', 'HTTPRoute', 'GRPCRoute'])))", message="admissionControl can only be used with HTTPRoute, GRPCRoute, or Gateway targets"
49+
// +kubebuilder:validation:XValidation:rule="!has(self.defaultChildMergeType) || ((!has(self.targetRef) || self.targetRef.kind == 'Gateway') && (!has(self.targetRefs) || self.targetRefs.all(ref, ref.kind == 'Gateway')) && (!has(self.targetSelectors) || self.targetSelectors.all(sel, sel.kind == 'Gateway')))", message="defaultChildMergeType can only be used with Gateway targets"
4950
type BackendTrafficPolicySpec struct {
5051
PolicyTargetReferences `json:",inline"`
5152
ClusterSettings `json:",inline"`
@@ -60,6 +61,16 @@ type BackendTrafficPolicySpec struct {
6061
// +optional
6162
MergeType *MergeType `json:"mergeType,omitempty"`
6263

64+
// DefaultChildMergeType is the merge strategy applied to child policies (policies targeting
65+
// an xRoute under this policy's target) that do not set their own mergeType, so a child
66+
// policy merges into this policy instead of replacing it. A child policy can opt out by
67+
// setting mergeType to Replace.
68+
// This field can only be set on policies targeting a parent resource (Gateway).
69+
//
70+
// +kubebuilder:validation:Enum=StrategicMerge;JSONMerge
71+
// +optional
72+
DefaultChildMergeType *MergeType `json:"defaultChildMergeType,omitempty"`
73+
6374
// RateLimit allows the user to limit the number of incoming requests
6475
// to a predefined value based on attributes within the traffic flow.
6576
// +optional

api/v1alpha1/envoyproxy_types.go

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -216,36 +216,6 @@ type EnvoyProxySpec struct {
216216
// +kubebuilder:validation:Enum=Replace;StrategicMerge;JSONMerge
217217
// +optional
218218
MergeType *MergeType `json:"mergeType,omitempty"`
219-
220-
// PolicyDefaults defines defaults applied to Envoy Gateway policies attached to
221-
// Gateways that use this EnvoyProxy.
222-
// +optional
223-
PolicyDefaults *PolicyDefaults `json:"policyDefaults,omitempty"`
224-
}
225-
226-
// PolicyDefaults defines defaults applied to Envoy Gateway policies, keyed by policy kind.
227-
type PolicyDefaults struct {
228-
// BackendTrafficPolicy defines defaults applied to BackendTrafficPolicy resources.
229-
// +optional
230-
BackendTrafficPolicy *BackendTrafficPolicyDefaults `json:"backendTrafficPolicy,omitempty"`
231-
}
232-
233-
// BackendTrafficPolicyDefaults defines defaults applied to BackendTrafficPolicy resources.
234-
type BackendTrafficPolicyDefaults struct {
235-
MergeSettings `json:",inline"`
236-
}
237-
238-
// MergeSettings defines how an Envoy Gateway policy that does not set a mergeType is merged by default.
239-
type MergeSettings struct {
240-
// MergeType is the mergeType applied to a policy that does not set one,
241-
// so a route-level policy merges into its parent instead of replacing it.
242-
// +kubebuilder:validation:Enum=StrategicMerge;JSONMerge
243-
// +optional
244-
MergeType *MergeType `json:"mergeType,omitempty"`
245-
246-
// MergeExcludeLabel, when present on a policy, opts that policy out of the default MergeType.
247-
// +optional
248-
MergeExcludeLabel *string `json:"mergeExcludeLabel,omitempty"`
249219
}
250220

251221
// EnvoyProxyGeoIP defines shared GeoIP provider settings for EnvoyProxy.

api/v1alpha1/validation/envoygateway_validate.go

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -71,30 +71,9 @@ func ValidateEnvoyGateway(eg *egv1a1.EnvoyGateway) error {
7171
return fmt.Errorf("disableLua and enableLua must not have the same value")
7272
}
7373

74-
if err := validateEnvoyGatewayDefaultEnvoyProxy(eg.EnvoyProxy); err != nil {
75-
return err
76-
}
77-
7874
return nil
7975
}
8076

81-
// validateEnvoyGatewayDefaultEnvoyProxy validates fields of the default EnvoyProxySpec that are
82-
// enforced by CRD validation for EnvoyProxy resources but not when the spec is provided inline as
83-
// the EnvoyGateway default, since that path does not go through CRD admission.
84-
func validateEnvoyGatewayDefaultEnvoyProxy(spec *egv1a1.EnvoyProxySpec) error {
85-
if spec == nil || spec.PolicyDefaults == nil || spec.PolicyDefaults.BackendTrafficPolicy == nil ||
86-
spec.PolicyDefaults.BackendTrafficPolicy.MergeType == nil {
87-
return nil
88-
}
89-
switch *spec.PolicyDefaults.BackendTrafficPolicy.MergeType {
90-
case egv1a1.StrategicMerge, egv1a1.JSONMerge:
91-
return nil
92-
default:
93-
return fmt.Errorf("envoyProxy.policyDefaults.backendTrafficPolicy.mergeType must be one of StrategicMerge or JSONMerge, got %q",
94-
*spec.PolicyDefaults.BackendTrafficPolicy.MergeType)
95-
}
96-
}
97-
9877
// WarnEnvoyGateway returns deprecation warnings for the provided EnvoyGateway configuration.
9978
func WarnEnvoyGateway(eg *egv1a1.EnvoyGateway) []string {
10079
if eg == nil || eg.ExtensionAPIs == nil {

api/v1alpha1/validation/envoygateway_validate_test.go

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,40 +1054,6 @@ func TestValidateEnvoyGateway(t *testing.T) {
10541054
},
10551055
expect: true,
10561056
},
1057-
{
1058-
name: "default EnvoyProxy with valid backendTrafficPolicy.mergeType",
1059-
eg: &egv1a1.EnvoyGateway{
1060-
EnvoyGatewaySpec: egv1a1.EnvoyGatewaySpec{
1061-
Gateway: egv1a1.DefaultGateway(),
1062-
Provider: egv1a1.DefaultEnvoyGatewayProvider(),
1063-
EnvoyProxy: &egv1a1.EnvoyProxySpec{
1064-
PolicyDefaults: &egv1a1.PolicyDefaults{
1065-
BackendTrafficPolicy: &egv1a1.BackendTrafficPolicyDefaults{MergeSettings: egv1a1.MergeSettings{
1066-
MergeType: new(egv1a1.StrategicMerge),
1067-
}},
1068-
},
1069-
},
1070-
},
1071-
},
1072-
expect: true,
1073-
},
1074-
{
1075-
name: "default EnvoyProxy with invalid backendTrafficPolicy.mergeType",
1076-
eg: &egv1a1.EnvoyGateway{
1077-
EnvoyGatewaySpec: egv1a1.EnvoyGatewaySpec{
1078-
Gateway: egv1a1.DefaultGateway(),
1079-
Provider: egv1a1.DefaultEnvoyGatewayProvider(),
1080-
EnvoyProxy: &egv1a1.EnvoyProxySpec{
1081-
PolicyDefaults: &egv1a1.PolicyDefaults{
1082-
BackendTrafficPolicy: &egv1a1.BackendTrafficPolicyDefaults{MergeSettings: egv1a1.MergeSettings{
1083-
MergeType: new(egv1a1.Replace),
1084-
}},
1085-
},
1086-
},
1087-
},
1088-
},
1089-
expect: false,
1090-
},
10911057
}
10921058

10931059
for _, tc := range testCases {

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 5 additions & 66 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,17 @@ spec:
513513
Note that when the suffix is not provided, the value is interpreted as bytes.
514514
x-kubernetes-int-or-string: true
515515
type: object
516+
defaultChildMergeType:
517+
description: |-
518+
DefaultChildMergeType is the merge strategy applied to child policies (policies targeting
519+
an xRoute under this policy's target) that do not set their own mergeType, so a child
520+
policy merges into this policy instead of replacing it. A child policy can opt out by
521+
setting mergeType to Replace.
522+
This field can only be set on policies targeting a parent resource (Gateway).
523+
enum:
524+
- StrategicMerge
525+
- JSONMerge
526+
type: string
516527
dns:
517528
description: DNS includes dns resolution settings.
518529
properties:
@@ -3357,6 +3368,11 @@ spec:
33573368
|| self.targetRefs.all(ref, ref.kind in [''Gateway'', ''HTTPRoute'',
33583369
''GRPCRoute''])) && (!has(self.targetSelectors) || self.targetSelectors.all(sel,
33593370
sel.kind in [''Gateway'', ''HTTPRoute'', ''GRPCRoute''])))'
3371+
- message: defaultChildMergeType can only be used with Gateway targets
3372+
rule: '!has(self.defaultChildMergeType) || ((!has(self.targetRef) ||
3373+
self.targetRef.kind == ''Gateway'') && (!has(self.targetRefs) || self.targetRefs.all(ref,
3374+
ref.kind == ''Gateway'')) && (!has(self.targetSelectors) || self.targetSelectors.all(sel,
3375+
sel.kind == ''Gateway'')))'
33603376
- message: predictivePercent in preconnect policy only works with RoundRobin
33613377
or Random load balancers
33623378
rule: '!((has(self.connection) && has(self.connection.preconnect) &&

charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -794,29 +794,6 @@ spec:
794794
- StrategicMerge
795795
- JSONMerge
796796
type: string
797-
policyDefaults:
798-
description: |-
799-
PolicyDefaults defines defaults applied to Envoy Gateway policies attached to
800-
Gateways that use this EnvoyProxy.
801-
properties:
802-
backendTrafficPolicy:
803-
description: BackendTrafficPolicy defines defaults applied to
804-
BackendTrafficPolicy resources.
805-
properties:
806-
mergeExcludeLabel:
807-
description: MergeExcludeLabel, when present on a policy,
808-
opts that policy out of the default MergeType.
809-
type: string
810-
mergeType:
811-
description: |-
812-
MergeType is the mergeType applied to a policy that does not set one,
813-
so a route-level policy merges into its parent instead of replacing it.
814-
enum:
815-
- StrategicMerge
816-
- JSONMerge
817-
type: string
818-
type: object
819-
type: object
820797
preserveRouteOrder:
821798
description: |-
822799
PreserveRouteOrder determines if the order of matching for HTTPRoutes is determined by Gateway-API

charts/gateway-helm/charts/crds/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,17 @@ spec:
512512
Note that when the suffix is not provided, the value is interpreted as bytes.
513513
x-kubernetes-int-or-string: true
514514
type: object
515+
defaultChildMergeType:
516+
description: |-
517+
DefaultChildMergeType is the merge strategy applied to child policies (policies targeting
518+
an xRoute under this policy's target) that do not set their own mergeType, so a child
519+
policy merges into this policy instead of replacing it. A child policy can opt out by
520+
setting mergeType to Replace.
521+
This field can only be set on policies targeting a parent resource (Gateway).
522+
enum:
523+
- StrategicMerge
524+
- JSONMerge
525+
type: string
515526
dns:
516527
description: DNS includes dns resolution settings.
517528
properties:
@@ -3356,6 +3367,11 @@ spec:
33563367
|| self.targetRefs.all(ref, ref.kind in [''Gateway'', ''HTTPRoute'',
33573368
''GRPCRoute''])) && (!has(self.targetSelectors) || self.targetSelectors.all(sel,
33583369
sel.kind in [''Gateway'', ''HTTPRoute'', ''GRPCRoute''])))'
3370+
- message: defaultChildMergeType can only be used with Gateway targets
3371+
rule: '!has(self.defaultChildMergeType) || ((!has(self.targetRef) ||
3372+
self.targetRef.kind == ''Gateway'') && (!has(self.targetRefs) || self.targetRefs.all(ref,
3373+
ref.kind == ''Gateway'')) && (!has(self.targetSelectors) || self.targetSelectors.all(sel,
3374+
sel.kind == ''Gateway'')))'
33593375
- message: predictivePercent in preconnect policy only works with RoundRobin
33603376
or Random load balancers
33613377
rule: '!((has(self.connection) && has(self.connection.preconnect) &&

charts/gateway-helm/charts/crds/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -793,29 +793,6 @@ spec:
793793
- StrategicMerge
794794
- JSONMerge
795795
type: string
796-
policyDefaults:
797-
description: |-
798-
PolicyDefaults defines defaults applied to Envoy Gateway policies attached to
799-
Gateways that use this EnvoyProxy.
800-
properties:
801-
backendTrafficPolicy:
802-
description: BackendTrafficPolicy defines defaults applied to
803-
BackendTrafficPolicy resources.
804-
properties:
805-
mergeExcludeLabel:
806-
description: MergeExcludeLabel, when present on a policy,
807-
opts that policy out of the default MergeType.
808-
type: string
809-
mergeType:
810-
description: |-
811-
MergeType is the mergeType applied to a policy that does not set one,
812-
so a route-level policy merges into its parent instead of replacing it.
813-
enum:
814-
- StrategicMerge
815-
- JSONMerge
816-
type: string
817-
type: object
818-
type: object
819796
preserveRouteOrder:
820797
description: |-
821798
PreserveRouteOrder determines if the order of matching for HTTPRoutes is determined by Gateway-API

0 commit comments

Comments
 (0)