Skip to content

Commit 9212bfb

Browse files
committed
Add CLAUDE.md
Assisted-by: Claude code Signed-off-by: Dale Haiducek <[email protected]>
1 parent d2c11fc commit 9212bfb

File tree

1 file changed

+200
-0
lines changed

1 file changed

+200
-0
lines changed

CLAUDE.md

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

0 commit comments

Comments
 (0)