-
Notifications
You must be signed in to change notification settings - Fork 845
refactor: conditionally create controller dependencies based on operations #4239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
- Add HasMutationOperations, HasStatusOperation, HasGenerateOperation helpers - Refactor setupControllers to conditionally create OPA client, mutation system, expansion system, provider cache based on operations - Update controller.AddToManager to handle nil dependencies - Add comprehensive tests for operation helper functions Co-authored-by: JaydipGabani <[email protected]>
- Move cert watcher creation to a single location when external data is enabled - Share cert watcher between OPA client and mutation system - Clean up duplicate comments Co-authored-by: JaydipGabani <[email protected]>
|
@copilot 1. changes in operations.go are not need, use IsAssigned whenever you want to check for presence of an operations. Re-analyze and think hard about whole operation and controller dependencies integration, double check you changes so far and the future changes as well to make sure all the dependencies are properly initiated for only required operaitons. Focus on code readbility, clean and optimized code. Do not add unnecessary comments. Remove not needed tests. |
- Remove helper functions from operations.go, use IsAssigned directly - Replace all usages in main.go with direct IsAssigned calls - Add nil checks in audit.AddToManager and webhook.AddToManager - Remove unnecessary comments per feedback Co-authored-by: JaydipGabani <[email protected]>
Done in commit c9ef9e9:
All dependencies are now properly initialized only for required operations. |
|
@copilot main.go:385 does operation status require opaclient? |
Status controllers only aggregate status CRDs and don't use OPA client or cache manager Co-authored-by: JaydipGabani <[email protected]>
No, status operation does not require OPA client. Fixed in commit 1a6834b. Status controllers (constraintstatus, configstatus, mutatorstatus, etc.) only aggregate status CRDs - they don't interact with the OPA constraint framework. The CFClient field in some Adder structs is injected but never used in reconciliation logic. Removed status from both OPA client and cache manager dependencies. |
JaydipGabani
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot please address these changes.
| setupLog.Info("setting up controllers") | ||
|
|
||
| // Events ch will be used to receive events from dynamic watches registered | ||
| // via the registrar below. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
preserve the original comments as much as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Restored original comments in commit 094d605. All removed comments have been preserved including:
- "Block until the setup (certificate generation) finishes."
- "certWatcher is used to watch for changes to Gatekeeper's certificate and key files."
- "register the client cert watcher to the driver"
- "register the client cert watcher to the mutation system"
- "processExcluder is used for namespace exclusion for specified processes in config"
- "Setup all Controllers"
- "Events ch will be used to receive events from dynamic watches registered via the registrar below."
Preserved original comments as requested to maintain code documentation Co-authored-by: JaydipGabani <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR refactors controller dependency initialization in main.go to conditionally create dependencies based on assigned operations. This addresses issues where pods running with limited operation sets would fail to initialize unnecessary dependencies (e.g., mutation-only pods failing to initialize OPA client).
Key changes:
- Conditional creation of OPA client, mutation system, expansion system, provider cache, cache manager, and webhook config cache based on operation assignments
- Nil-check guards added in controller injection, webhook setup, and audit manager initialization
- Maintains backward compatibility with default behavior (all operations enabled)
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| main.go | Conditionally creates controller dependencies based on operations using operations.IsAssigned() checks |
| pkg/controller/controller.go | Adds nil checks before dependency injection to handle optional dependencies |
| pkg/webhook/webhook.go | Adds nil check to skip webhook setup when neither OPA client nor mutation system are available |
| pkg/audit/controller.go | Adds nil check to skip audit manager initialization when OPA client is unavailable |
| if needsExpansionSystem { | ||
| expansionSystem = expansion.NewSystem(mutationSystem) | ||
| } |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The conditional creation of expansionSystem introduces a potential nil pointer dereference bug. When *expansion.ExpansionEnabled is false, expansionSystem will be nil, but it's still passed to webhook and audit handlers which call .Expand() on it without nil checks (see pkg/webhook/policy.go:621 and pkg/audit/manager.go:719).
Solution: Always create the expansionSystem (even when expansion is disabled), similar to how it was done before this refactoring:
// Always create expansion system, even if expansion is disabled
// The system handles nil mutationSystem gracefully
if needsMutationSystem {
expansionSystem = expansion.NewSystem(mutationSystem)
} else {
expansionSystem = expansion.NewSystem(nil)
}Or more concisely, remove the conditional and always create it:
expansionSystem = expansion.NewSystem(mutationSystem)The expansion.System is designed to work even when no expansion templates are defined - it will simply return empty results.
| if needsExpansionSystem { | |
| expansionSystem = expansion.NewSystem(mutationSystem) | |
| } | |
| expansionSystem = expansion.NewSystem(mutationSystem) |
What this PR does / why we need it:
Controllers were initializing all dependencies regardless of assigned operations, causing failures when pods ran with limited operation sets (e.g., mutation-only pods failing to initialize OPA client).
Changes:
operations.IsAssigned()directly:Example:
Which issue(s) this PR fixes:
Fixes #4051
Fixes #3964
Special notes for your reviewer:
operations.IsAssigned()directly for cleaner, more readable codeOriginal prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.