feat: support default mergeType for BackendTrafficPolicy via EnvoyProxy#9374
feat: support default mergeType for BackendTrafficPolicy via EnvoyProxy#9374H34rtUnd3rB14d3 wants to merge 3 commits into
Conversation
A route-level BackendTrafficPolicy that leaves mergeType unset currently replaces its parent policy rather than merging into it. That means anyone who wants merging has to remember to set mergeType on every policy. This adds a backendTrafficPolicy section to the EnvoyProxy API with a defaultMergeType field. When a route-level policy doesn't set its own mergeType, it picks up this default and merges into the parent instead of replacing it. An explicit mergeType still wins, an optional excludeLabel lets a policy opt out, and policies in the control-plane namespace are left untouched. defaultMergeType only accepts StrategicMerge or JSONMerge. Fixes envoyproxy#9334 Signed-off-by: Maksim Kuchkovskiy <K.Maksim.E@yandex.ru>
✅ Deploy Preview for cerulean-figolla-1f9435 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e22e13f6f6
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| } | ||
|
|
||
| if policy.Spec.MergeType == nil { | ||
| if policy.Spec.MergeType == nil && !t.anyGatewayMergeDefault(policy, parentRefCtxs) { |
There was a problem hiding this comment.
Keep defaulted merges scoped to the Gateway
When defaultMergeType sends an otherwise-unset policy into the per-listener merge path, MergeGateways mode makes t.IRKey(gwNN) the same for every Gateway and the later route application filters only by listener sectionName. For a route attached to two Gateways that both have a listener named http but different parent BackendTrafficPolicies, the first merged parent policy is applied to both listeners and the second is skipped because the route traffic is already set. Include the Gateway identity when applying defaulted merged route policies in merged-Gateway IR.
Useful? React with 👍 / 👎.
| // +kubebuilder:validation:Enum=StrategicMerge;JSONMerge | ||
| // +optional | ||
| DefaultMergeType *MergeType `json:"defaultMergeType,omitempty"` |
There was a problem hiding this comment.
Validate defaultMergeType outside the CRD path
The enum marker protects EnvoyProxy CRs, but this same EnvoyProxySpec is also used as the EnvoyGateway default spec, which is loaded through ValidateEnvoyGateway rather than CRD validation. A config such as envoyProxy.backendTrafficPolicy.defaultMergeType: Replace is therefore accepted and effectiveMergeType will use Replace, causing the child policy to replace the parent while statuses record it as merged. Add runtime validation for the EnvoyGateway/default-spec path as well.
Useful? React with 👍 / 👎.
| // BackendTrafficPolicy defines defaults applied to BackendTrafficPolicy resources | ||
| // attached to Gateways that use this EnvoyProxy. | ||
| // +optional | ||
| BackendTrafficPolicy *BackendTrafficPolicyDefaults `json:"backendTrafficPolicy,omitempty"` |
There was a problem hiding this comment.
we may need this for other policy, so this might became a common settings for all the xPolicies(at least for EnvoyExtensionPolicy).
cc @envoyproxy/gateway-maintainers
There was a problem hiding this comment.
fixed, pls check that I understood you correctly
Rename the EnvoyProxy policy-defaults type from BackendTrafficPolicyDefaults to a reusable PolicyDefaults, so other xPolicies can adopt the same shape. The backendTrafficPolicy field is unchanged; only the type name changes. Also fixes two review findings: - Validate defaultMergeType on the EnvoyGateway default EnvoyProxySpec. That spec is loaded via config (ValidateEnvoyGateway), not CRD admission, so the enum does not apply and a value like Replace could slip through. effectiveMergeType also defensively ignores a non-merge value, so a stray default can never report a "merged" status while actually replacing. - Scope a defaulted merged route policy to its own Gateway's listeners. In MergeGateways mode all Gateways share one IR keyed by section name, so a route attached to two Gateways with different parent policies received the first Gateway's merge on both. applyTrafficFeatureToRoute now filters listeners by the target Gateway. Adds a merged-gateways golden fixture. Signed-off-by: Maksim Kuchkovskiy <K.Maksim.E@yandex.ru>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #9374 +/- ##
==========================================
- Coverage 75.20% 75.20% -0.01%
==========================================
Files 252 252
Lines 41049 41095 +46
==========================================
+ Hits 30871 30905 +34
- Misses 8084 8090 +6
- Partials 2094 2100 +6 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Add a unit test for applyTrafficFeatureToRoute exercising the TCP and UDP listener skip branches when a route policy targets a different Gateway under the shared MergeGateways IR. The HTTP path is already covered by the merged-gateways golden fixture; this brings the new scoping code to full patch coverage. Signed-off-by: Maksim Kuchkovskiy <K.Maksim.E@yandex.ru>
| // BackendTrafficPolicy defines defaults applied to BackendTrafficPolicy resources | ||
| // attached to Gateways that use this EnvoyProxy. | ||
| // +optional | ||
| BackendTrafficPolicy *PolicyDefaults `json:"backendTrafficPolicy,omitempty"` |
There was a problem hiding this comment.
should we add some things like following for better extension?
policyMergeType:
backendTrafficPolicy:
securitryPolicy: #we could implament this in the future.cc @envoyproxy/gateway-maintainers WDYT?
There was a problem hiding this comment.
IMHO, if we decide to do that, I'd name the parent policyDefaults rather than policyMergeType, since each entry also carries excludeLabel and may grow beyond merge settings later.
What this PR does / why we need it:
Right now, if a route-level
BackendTrafficPolicydoesn't setmergeType, it replaces thegateway- or listener-level policy instead of merging into it. So if you keep a baseline policy on
the Gateway and add route-level policies on top, you have to remember to put
mergeTypeon everysingle one of them, or the baseline silently gets dropped for that route.
This PR lets you set that default once on the
EnvoyProxyinstead:With that in place, a route-level policy that doesn't set its own
mergeTypepicks up the defaultand merges into its parent. A few rules that keep it predictable:
mergeTypeon the policy always wins.excludeLabelkey opts out and replaces its parent as before.defaultMergeTypeonly acceptsStrategicMergeorJSONMerge- the field's enum rejectsReplace, since defaulting to a replace wouldn't do anything.The default rides the existing EnvoyProxy precedence (GatewayClass-level, per-Gateway, and the
EnvoyGateway default spec), so you can set it broadly and override it on a specific Gateway. When no
default is configured, behavior is exactly the same as today, so this is fully backward compatible.
On the approach: an earlier draft did this with a mutating webhook, but the maintainers preferred
putting it on
EnvoyProxysince there's already a default EnvoyProxy concept in EnvoyGateway. ThisPR follows that. Everything is resolved at translation time (
effectiveMergeType/anyGatewayMergeDefaultininternal/gatewayapi/backendtrafficpolicy.go); no new webhook or CRD.Tests: unit tests for the two new helpers, golden translator fixtures covering the merge,
exclude-label, control-plane-namespace, and multi-parent cases, and CEL validation for the new
fields. Docs are updated in the BackendTrafficPolicy concept page and the generated API reference.
Which issue(s) this PR fixes:
Fixes #9334
PR Checklist
git commit -s). See DCO: Sign your work./api), the API was discussed and agreed before the implementation. The API change can be in a separate PR, or in the same PR, but the API must be agreed before implementation. N/A if this PR does not contain API changes.make generate gen-check,make lint, and the unit-test/coverage build pass. (Flaky e2e failures are not considered breakages, butgen-check,lint, and coverage MUST pass.)release-notes/current/<section>/<pr-number>-<slug>.md(seerelease-notes/current/README.mdfor sections and naming). N/A if this PR does not contain non-trivial changes.make gen-checkand committed the result if API/helm charts/modules changed.release-notes/current/breaking_changes/.