Skip to content

Commit 1b40a76

Browse files
dhaiducekopenshift-merge-bot[bot]
authored andcommitted
Add CLAUDE.md
Assisted-by: Claude code Signed-off-by: Dale Haiducek <[email protected]>
1 parent d2c11fc commit 1b40a76

File tree

1 file changed

+232
-0
lines changed

1 file changed

+232
-0
lines changed

CLAUDE.md

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this
4+
repository.
5+
6+
## Overview
7+
8+
The Configuration Policy Controller is a Kubernetes controller that enforces and evaluates
9+
ConfigurationPolicy resources in Open Cluster Management. It monitors objects on managed clusters,
10+
checks compliance against policy templates, and can automatically remediate non-compliant resources
11+
when set to enforce mode.
12+
13+
## Build, Test, and Run Commands
14+
15+
### Building
16+
17+
```bash
18+
# Build the controller binary
19+
make build
20+
21+
# Build the dryrun CLI tool
22+
make build-cmd
23+
24+
# Build container image (configurable with REGISTRY, IMG, TAG env vars)
25+
make build-images
26+
```
27+
28+
### Testing
29+
30+
```bash
31+
# Run unit tests
32+
make test
33+
34+
# Run unit tests with coverage
35+
make test-coverage
36+
37+
# Run E2E tests (requires KinD cluster)
38+
make e2e-test
39+
40+
# Run specific E2E tests
41+
TESTARGS="--focus=<pattern>" make e2e-test
42+
43+
# Setup KinD cluster for development
44+
make kind-bootstrap-cluster-dev
45+
46+
# Deploy controller to KinD and run E2E tests
47+
make kind-tests
48+
```
49+
50+
### Running Locally
51+
52+
```bash
53+
# Run controller locally (must set WATCH_NAMESPACE)
54+
export WATCH_NAMESPACE=<namespace>
55+
make run
56+
57+
# The controller requires a Kubernetes cluster configured via kubectl
58+
```
59+
60+
### Linting and Formatting
61+
62+
```bash
63+
# Format code
64+
make fmt
65+
```
66+
67+
### Generate Manifests
68+
69+
```bash
70+
# Generate CRDs and RBAC manifests
71+
make manifests
72+
73+
# Generate DeepCopy implementations
74+
make generate
75+
```
76+
77+
## Architecture
78+
79+
### Core Components
80+
81+
**ConfigurationPolicyReconciler** (`controllers/configurationpolicy_controller.go`)
82+
83+
- Main reconciler that evaluates ConfigurationPolicy resources
84+
- Handles both `inform` (report-only) and `enforce` (remediate) modes
85+
- Uses dynamic client to work with any Kubernetes resource type
86+
- Supports templating with Go templates and sprig functions
87+
- Implements watch-based evaluation for efficient resource monitoring
88+
89+
**OperatorPolicyReconciler** (`controllers/operatorpolicy_controller.go`)
90+
91+
- Manages OperatorPolicy resources for OLM operator lifecycle management
92+
- Controls operator subscriptions, CSV status, and upgrade behavior
93+
94+
**Evaluation Flow**:
95+
96+
1. Policy is reconciled based on evaluation interval or watch events
97+
2. Templates are resolved (if present) using go-template-utils library
98+
3. Namespace selector determines target namespaces
99+
4. For each object template:
100+
- Determine desired objects (resolving selectors if needed)
101+
- Compare with existing cluster state
102+
- If enforce mode: create, update, or delete objects as needed
103+
- If inform mode: report compliance status only
104+
5. Status is updated with compliance details and related objects
105+
6. Events are emitted to parent Policy resource
106+
107+
### Key Packages
108+
109+
**pkg/common** - Shared utilities:
110+
111+
- `namespace_selection.go`: NamespaceSelector reconciler for efficient namespace filtering
112+
- `common.go`: Helper functions for environment detection
113+
114+
**pkg/dryrun** - CLI tool for testing policies without a cluster:
115+
116+
- Simulates policy evaluation using fake clients
117+
- Supports reading cluster resources or using local YAML files
118+
- Provides diff output and compliance message reporting
119+
120+
**pkg/mappings** - API resource mappings for the dryrun CLI
121+
122+
**pkg/triggeruninstall** - Handles controller uninstallation cleanup
123+
124+
### Template Processing
125+
126+
The controller supports Go templating in object definitions with these special features:
127+
128+
- Hub templates: can reference objects from the hub cluster (when configured)
129+
- Context variables: `.Object`, `.ObjectName`, `.ObjectNamespace` for dynamic templating per
130+
namespace/object
131+
- Template functions: `fromSecret`, `fromConfigMap`, `fromClusterClaim`, `lookup`, plus sprig
132+
functions
133+
- `skipObject` function: allows conditional object creation based on template logic
134+
- Encryption support: templates can include encrypted values using AES encryption
135+
136+
### Compliance Types
137+
138+
- **musthave**: Object must exist and match the specified fields (partial match)
139+
- **mustnothave**: Object must not exist
140+
- **mustonlyhave**: Object must exist and match exactly (no extra fields)
141+
142+
### Watch vs Polling
143+
144+
The controller supports two evaluation modes:
145+
146+
- **Watch mode** (default): Uses Kubernetes watches for efficient real-time evaluation
147+
- **Polling mode**: Periodically evaluates policies based on evaluationInterval
148+
149+
The dynamic watcher (kubernetes-dependency-watches) automatically manages watches on related
150+
objects.
151+
152+
### Hosted Mode
153+
154+
The controller can run in "hosted mode" where:
155+
156+
- Controller runs on hub cluster
157+
- Evaluates/enforces policies on a separate managed cluster
158+
- Configured via `--target-kubeconfig-path` flag
159+
- Uses separate managers for hub and managed cluster clients
160+
161+
## Important Patterns
162+
163+
### Object Comparison
164+
165+
The comparison logic in `handleSingleKey` and `mergeSpecsHelper` is critical:
166+
167+
- Merges template values into existing object to avoid false negatives
168+
- Handles arrays specially (preserves duplicates, matches by "name" field)
169+
- Dry-run updates verify actual API behavior before enforcement
170+
- `zeroValueEqualsNil` parameter controls empty value handling
171+
172+
### Caching and Evaluation Optimization
173+
174+
- `processedPolicyCache`: Tracks evaluated objects by resourceVersion to avoid redundant comparisons
175+
- `lastEvaluatedCache`: Prevents race conditions with controller-runtime cache staleness
176+
- Evaluation backoff (`--evaluation-backoff`): Throttles frequent policy evaluations
177+
178+
### Pruning Behavior
179+
180+
When `pruneObjectBehavior` is set:
181+
182+
- **DeleteIfCreated**: Removes objects created by the policy
183+
- **DeleteAll**: Removes all objects matching the template
184+
- Tracked via finalizers and object UIDs in status.relatedObjects
185+
186+
### Dry Run CLI
187+
188+
The `dryrun` command provides policy testing without cluster modification:
189+
190+
```bash
191+
# Test policy against local resources
192+
build/_output/bin/dryrun -p policy.yaml resource1.yaml resource2.yaml
193+
194+
# Test policy against live cluster (read-only)
195+
build/_output/bin/dryrun -p policy.yaml --from-cluster
196+
197+
# Compare status against expected
198+
build/_output/bin/dryrun -p policy.yaml resources.yaml --desired-status expected-status.yaml
199+
```
200+
201+
## Testing Guidelines
202+
203+
### E2E Test Structure
204+
205+
- Tests are in `test/e2e/` with descriptive case names
206+
- Use Ginkgo/Gomega framework
207+
- Tests can filter by label: `--label-filter='!hosted-mode'`
208+
- Helper functions in `test/utils/utils.go` for common operations
209+
210+
### Writing Tests
211+
212+
- Use `utils.GetWithTimeout` for eventually-consistent checks
213+
- Clean up resources in AfterEach blocks
214+
- Use unique names to avoid test conflicts
215+
- Test both inform and enforce modes where applicable
216+
217+
## Configuration
218+
219+
### Controller Flags
220+
221+
Key flags when running the controller:
222+
223+
- `--evaluation-concurrency`: Max concurrent policy evaluations (default: 2)
224+
- `--evaluation-backoff`: Seconds before re-evaluation in watch mode (default: 10)
225+
- `--enable-operator-policy`: Enable OperatorPolicy support
226+
- `--target-kubeconfig-path`: Path to managed cluster kubeconfig (hosted mode)
227+
- `--standalone-hub-templates-kubeconfig-path`: Hub cluster for template resolution
228+
229+
### Environment Variables
230+
231+
- `WATCH_NAMESPACE`: Namespace to monitor for policies (required when running locally)
232+
- `POD_NAME`: Used to detect controller pod name

0 commit comments

Comments
 (0)