Skip to content

fix: scope expansion ingestion controller to audit and webhook operations - #4778

Open
pujitha24 wants to merge 7 commits into
open-policy-agent:masterfrom
pujitha24:auto/issue-4773
Open

fix: scope expansion ingestion controller to audit and webhook operations#4778
pujitha24 wants to merge 7 commits into
open-policy-agent:masterfrom
pujitha24:auto/issue-4773

Conversation

@pujitha24

Copy link
Copy Markdown
Contributor

What this PR does / why we need it:

setupControllers registers the ExpansionTemplate ingestion controller (pkg/controller/expansion.Adder) in every process where --enable-generator-resource-expansion is true, which is the default. That means status-only, generate-only, mutation-status-only, and mutation-webhook-only processes register a controller and watches for a feature they never evaluate: only the audit and validating-webhook paths actually call expansion.System.Expand(...) (pkg/audit/manager.go, pkg/webhook/policy.go). Beyond the wasted registration, a non-consumer pod's readiness tracker was also unconditionally required to observe every ExpansionTemplate in the cluster (pkg/readiness/ready_tracker.go's Satisfied() gates on the raw expansionEnabled bool), even though no reconciler ran on that pod to ever satisfy that expectation — so a status-only/generate-only/mutation-only pod's /readyz could get stuck permanently unsatisfied whenever any ExpansionTemplate objects exist in the cluster.

This PR scopes both to the operations that actually consume expanded resources (audit and webhook):

  • Added operations.HasExpansionConsumerOperations(), mirroring the existing operations.HasValidationOperations() / mutation.Enabled() pattern already used in this codebase to scope controllers by assigned --operation flags.
  • expansion.Adder.Add now also skips registering the ingestion controller when !operations.HasExpansionConsumerOperations(), in addition to the existing enable-flag check.
  • main.go's readiness.SetupTracker call now passes *expansion.ExpansionEnabled && operations.HasExpansionConsumerOperations() instead of the raw flag, so non-consumer pods stop tracking expansion-template expectations entirely, exactly like mutationEnabled/externalDataEnabled are already scoped in that file.

Default (all-operations) behavior is unchanged, since the default operation set includes both audit and webhook. pkg/controller/expansionstatus (status aggregation) already gates on operations.Status independently and is unaffected.

Which issue(s) this PR fixes (optional, using fixes #<issue number>(, fixes #<issue_number>, ...) format, will close the issue(s) when the PR gets merged):
Fixes #

Special notes for your reviewer:

Validation performed:

  • go build ./... and go vet ./...: clean.
  • golangci-lint run . (whole module, locally installed golangci-lint, not the exact Docker-pinned version make lint uses in CI): 0 issues on the full repo, including the changed files.
  • KUBEBUILDER_ASSETS=<abs path to setup-envtest 1.33.0 assets> go test ./pkg/controller/expansion/... ./pkg/operations/... ./pkg/readiness/...: all pass (envtest-backed suites for the two directly-touched packages plus the readiness package, whose Satisfied()/tracking logic this change also affects).
  • Added pkg/operations.Test_HasExpansionConsumerOperations (table-driven, all seven operations plus none-assigned) and pkg/controller/expansion.TestAdd_RequiresExpansionConsumerOperation. I manually confirmed the failing-before/passing-after property required for this class of fix: temporarily reverting only the new gate in expansion_controller.go (keeping the new test) makes TestAdd_RequiresExpansionConsumerOperation panic with a nil-pointer dereference (newReconciler calling mgr.GetClient() on a nil manager, since Add(nil) no longer returns early); restoring the gate makes it pass. That nil-manager panic is a synthetic test scenario to prove the gate is load-bearing, not a real production path — the real binary always passes a live, non-nil manager to Add.
  • I did not run make native-test/make native-race-test across the full repo, nor a live multi-pod e2e deployment reproducing the stuck-/readyz scenario end-to-end. The readiness-tracker interaction is validated by reading ready_tracker.go (every t.expansions access is already guarded by the same expansionEnabled bool that gates its allocation, exactly mirroring the pre-existing mutationEnabled/externalDataEnabled pattern in the same file) plus the existing pkg/readiness test suite passing unchanged with this change in place.
  • Searched open PRs and the issue's timeline for competing/duplicate work: none found for this issue specifically. PR fix: skip mutation system construction when no mutation operation is assigned #4777 (a different, still-open PR for the sibling issue Initialize mutation dependencies only for mutation operations #4772) touches main.go's mutation-system construction and pkg/controller/mutators/instances/mutator_controllers.go — no file overlap with this change.

Report: #4773

Fixes #4773

…ions

Motivation: setupControllers registered the ExpansionTemplate ingestion
controller in every process where --enable-generator-resource-expansion
is true (the default), even in status-only, generate-only,
mutation-status-only, and mutation-webhook-only processes that never
evaluate expanded resources. Only audit and the validating webhook call
expansion.System.Expand. Beyond the wasted controller/watch
registration, a non-consumer pod's readiness tracker was also
unconditionally required to observe every ExpansionTemplate in the
cluster, even though no reconciler ran on that pod to satisfy that
expectation, so its readiness probe could get stuck permanently
unsatisfied whenever any ExpansionTemplate objects exist.

Approach: added operations.HasExpansionConsumerOperations(), mirroring
the existing operations.HasValidationOperations()/mutation.Enabled()
pattern already used to scope controllers by assigned --operation
flags. expansion.Adder.Add now also skips registering the ingestion
controller when this predicate is false, and main.go's
readiness.SetupTracker call scopes its expansion-tracking bool by the
same predicate, matching how mutationEnabled/externalDataEnabled are
already gated in that file. Default (all-operations) behavior is
unchanged since the default set includes both audit and webhook;
pkg/controller/expansionstatus already gates independently on the
status operation and is unaffected.

Validation: go build ./... and go vet ./... are clean. golangci-lint
run . (local install, not the exact Docker-pinned CI version) reports
0 issues. KUBEBUILDER_ASSETS=<abs path> go test
./pkg/controller/expansion/... ./pkg/operations/... ./pkg/readiness/...
all pass. Added Test_HasExpansionConsumerOperations (table-driven, all
operations) and TestAdd_RequiresExpansionConsumerOperation. Manually
verified the failing-before/passing-after property: temporarily
reverting only the new gate in expansion_controller.go makes
TestAdd_RequiresExpansionConsumerOperation panic with a nil-pointer
dereference (newReconciler calling mgr.GetClient() on a nil manager);
restoring the gate makes it pass. That nil-manager panic is a synthetic
test scenario proving the gate is load-bearing, not a real production
path, since the real binary always passes a live manager. Did not run
make native-test/native-race-test across the full repo, nor a live
multi-pod e2e reproduction of the stuck-readiness scenario; the
readiness-tracker interaction is validated by reading ready_tracker.go
(every t.expansions access is already guarded by the same
expansionEnabled bool that gates its allocation, mirroring the
pre-existing mutationEnabled/externalDataEnabled pattern) plus the
existing pkg/readiness suite passing unchanged. Searched open PRs and
the issue's timeline for competing work: none found for this issue;
a different open PR for a sibling issue touches unrelated files.

Report: open-policy-agent#4773
Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com>
Assisted-by: claude-sonnet-5 (via Claude Code)
@pujitha24
pujitha24 requested a review from a team as a code owner August 24, 2026 22:50
Copilot AI balanced review requested due to automatic review settings August 24, 2026 22:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@codecov-commenter

codecov-commenter commented Aug 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 49.25%. Comparing base (3350319) to head (95fb6e1).
⚠️ Report is 871 commits behind head on master.

❗ There is a different number of reports uploaded between BASE (3350319) and HEAD (95fb6e1). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (3350319) HEAD (95fb6e1)
unittests 2 1
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4778      +/-   ##
==========================================
- Coverage   54.49%   49.25%   -5.25%     
==========================================
  Files         134      291     +157     
  Lines       12329    23396   +11067     
==========================================
+ Hits         6719    11524    +4805     
- Misses       5116    10824    +5708     
- Partials      494     1048     +554     
Flag Coverage Δ
unittests 49.25% <100.00%> (-5.25%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI review requested due to automatic review settings August 25, 2026 17:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings August 26, 2026 18:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings August 27, 2026 08:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings August 28, 2026 22:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings August 31, 2026 23:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Scope expansion controllers to operations that evaluate expanded resources

3 participants