Conversation
✅ 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: 0dbbf1f38d
ℹ️ 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".
| got, err := buildRateLimitRule(&tc.rule) | ||
| if tc.expectError { | ||
| require.Error(t, err) | ||
| require.Contains(t, err.Error(), tc.errorMsg) | ||
| require.Nil(t, got) |
There was a problem hiding this comment.
Exercise the rejection through the policy translator
This test invokes buildRateLimitRule directly, so it does not verify the user-visible part of the fix: a real BackendTrafficPolicy with duplicate sourceCIDR selectors must report Accepted: False with the translation error rather than retain the previous successful status. Add an internal/gatewayapi/testdata input/output fixture for this configuration so the translator and status propagation are covered; otherwise this test would still pass if a caller later swallowed the error.
Useful? React with 👍 / 👎.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #10046 +/- ##
=======================================
Coverage 81.41% 81.42%
=======================================
Files 266 266
Lines 41300 41304 +4
=======================================
+ Hits 33626 33633 +7
+ Misses 7673 7670 -3
Partials 1 1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
0dbbf1f to
798320f
Compare
…R rejection Covers the full BackendTrafficPolicy translation path (not just buildRateLimitRule directly) so the Accepted:False status is verified end-to-end, per Codex review feedback on envoyproxy#10046. Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com>
|
The unit test only checked |
|
can we also reject this with CEL? |
…R rejection Covers the full BackendTrafficPolicy translation path (not just buildRateLimitRule directly) so the Accepted:False status is verified end-to-end, per Codex review feedback on envoyproxy#10046. Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com>
baef1dd to
8ab3aac
Compare
… selector Motivation: A global or local rate limit rule with more than one clientSelectors entry, where more than one of those entries carries a sourceCIDR, silently applies only the last sourceCIDR: buildRateLimitRule assigns the parsed CIDR to ir.RateLimitRule.CIDRMatch, a single pointer field, so a second sourceCIDR selector in the same rule overwrites the first instead of being ANDed with it. The earlier selector is dropped with no error, and the policy still reports Accepted: True. This is especially dangerous when sourceCIDR plus invert: true is used as an IP-exemption mechanism, since adding a second exempted CIDR silently un-exempts the first one. Approach: Properly combining multiple sourceCIDR selectors would require reworking ir.RateLimitRule.CIDRMatch into a slice, regenerating deepcopy code, and reworking the nested Envoy rate-limit-descriptor chains in internal/xds/translator/ratelimit.go and local_ratelimit.go, which key descriptors with fixed constant strings that would need per-index uniqueness. That is a larger, higher-risk change than fits a surgical fix, so this change does not implement it. Instead, buildRateLimitRule now detects a second sourceCIDR selector within the same rule and returns a translation error, following the same convention this function already uses for other invalid configs. The policy is then reported as not Accepted with a clear reason instead of silently misapplying an IP match. A single sourceCIDR selector per rule continues to work exactly as before. This does not make multiple CIDRs combine as the CRD description suggests; it only prevents the silent-drop failure mode. Validation: - go build ./internal/gatewayapi/... passes. - go test ./internal/gatewayapi/... passes (all subpackages). - Added TestBuildRateLimitRuleSourceCIDR with a single-selector case (still succeeds) and a two-selector case using Distinct+invert matching the report's repro (now errors with "only one sourceCIDR selector is supported per rule"). Confirmed the two-selector case returns err == nil against the pre-fix code, reproducing the reported bug, and errors after the fix. - gofmt -l reports no issues on the changed files. - golangci-lint run ./internal/gatewayapi/... produces the same pre-existing findings with and without this change; no new findings. - Existing golden testdata under internal/gatewayapi/testdata/ using sourceCIDR each have only one sourceCIDR per rule, so none hit the new error path, consistent with the full package test suite passing unchanged. - gh run list shows Build and Test green on the latest push to main; OSV-Scanner is currently failing on main across unrelated recent commits (dependency scan noise), unrelated to this change. Report: envoyproxy#10025 Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com> Assisted-by: claude-sonnet-5 (via Claude Code)
…R rejection Covers the full BackendTrafficPolicy translation path (not just buildRateLimitRule directly) so the Accepted:False status is verified end-to-end, per Codex review feedback on envoyproxy#10046. Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com>
Add a CEL rule on RateLimitRule.clientSelectors so a rule with more than one sourceCIDR selector is rejected at admission, in addition to the existing translator check. Regenerate CRDs and helm goldens and add CEL validation test cases. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com>
8ab3aac to
2ef993d
Compare
What this PR does / why we need it:
When a global or local rate limit rule has more than one
clientSelectorsentry and morethan one of those entries carries a
sourceCIDR, only the lastsourceCIDRtakes effect.buildRateLimitRule(internal/gatewayapi/backendtrafficpolicy.go) loops overrule.ClientSelectorsand, for headers/methods, appends matches from every selector into aslice so they combine (AND semantics, per the CRD doc: "All individual select conditions
must hold True"). But
ir.RateLimitRule.CIDRMatchis a single*CIDRMatchpointer, so eachsourceCIDRselector overwrites the previous one instead of combining with it. The earlierselector is dropped with no error, and the policy still reports
Accepted: True. This isespecially dangerous when
sourceCIDR+invert: trueis used as an IP-exemptionmechanism: adding a second exempted CIDR silently un-exempts the first one.
Properly supporting multiple ANDed
sourceCIDRselectors would require reworkingir.RateLimitRule.CIDRMatchinto a slice, regenerating deepcopy code, and reworking thenested Envoy rate-limit-descriptor chains built in
internal/xds/translator/ratelimit.goand
local_ratelimit.go(which key descriptors with fixed constant strings that would needper-index uniqueness). That's a larger, higher-risk change than fits a surgical PR, so this
PR does not implement it.
Instead, this PR closes the silent-failure/false-
Accepted: Truegap:buildRateLimitRulenow detects a second
sourceCIDRselector within the same rule and returns a translationerror, the same way this function already errors on other invalid configs (e.g. an invalid
regex or a header missing its value). The policy is then reported as not Accepted with a
clear reason instead of silently misapplying (or un-applying) an IP match. A single
sourceCIDRselector per rule continues to work exactly as before.Note this does not make multiple exempted/matched CIDRs combine as the CRD description
suggests — that still isn't supported. It only prevents the dangerous silent-drop behavior
by surfacing a clear error at translation time.
Both
buildGlobalRateLimitandbuildLocalRateLimitcall through this same function, sothe validation applies consistently to both Global and Local rate limiting.
Which issue(s) this PR fixes:
Fixes #
Report: #10025
Validation:
go build ./internal/gatewayapi/...passes.go test ./internal/gatewayapi/...passes (all subpackages).TestBuildRateLimitRuleSourceCIDRininternal/gatewayapi/backendtrafficpolicy_test.go with two cases: a single
sourceCIDRselector (still succeeds), and two
sourceCIDRselectors across twoclientSelectorsentries with
Distinct+invert(now returns an error containing "only one sourceCIDRselector is supported per rule"). Verified this second case returns
err == nil(i.e.silently succeeds, reproducing the reported bug) against the pre-fix code, and correctly
errors after the fix — a failing-then-passing targeted test proving the defect and the fix.
gofmt -lreports no issues on the changed files.golangci-lint run ./internal/gatewayapi/...produces the same pre-existingSA1019/ST1005/errcheck findings with and without this diff — no new lint findings.
internal/gatewayapi/testdata/that usesourceCIDR: each occurrence is either the onlysourceCIDRin its rule, or belongs to aseparate
rules:entry, so none hit the new multi-selector error path — consistent withthe full package test suite passing unchanged.
gh run list --repo envoyproxy/gateway --branch main --event push --limit 10: the latestpush to
mainshowsBuild and Testgreen;OSV-Scanneris currently failing onmainacross multiple unrelated recent commits (dependency vulnerability scan noise), unrelated
to this change.
PR Checklist
git commit -s). See DCO: Sign your work.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/bug_fixes/10025-ratelimit-multiple-sourcecidr.md.sourceCIDRrules; a rule using more than onesourceCIDRselector, which never worked correctly, now fails to translate with a clear error instead of silently misbehaving. This is a narrowing of previously-silent-broken behavior, not a breaking change to any working configuration.Note: CI on this repo may show
OSV-Scannerred — that check is currently failing onmainindependent of this change (see Validation above).
AI assistance: this change was drafted with Claude Code.
Fixes #10025