Skip to content

Commit 4061ecd

Browse files
committed
docs(OSAC-2402): sync AGENTS.md with codebase and condense to size limits
Signed-off-by: Ameya Sathe <asathe@redhat.com> Assisted-by: Claude Code <noreply@anthropic.com> Signed-off-by: Ameya Sathe <asathe@redhat.com> rh-pre-commit.version: 2.4.0 rh-pre-commit.check-secrets: ENABLED
1 parent 5174020 commit 4061ecd

1 file changed

Lines changed: 125 additions & 0 deletions

File tree

AGENTS.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# host-management-openstack
2+
3+
Kubernetes controller that manages bare metal host power state via OpenStack Ironic. Watches HostLease custom resources (defined in bare-metal-fulfillment-operator) and reconciles desired power state (`spec.poweredOn`) through Ironic APIs. Optionally integrates with AAP for provisioning workflows via osac-operator's shared provisioning lifecycle.
4+
5+
## Critical Rules
6+
7+
- **No CRDs in this repo** — HostLease is owned by bare-metal-fulfillment-operator; install it before deploying
8+
- **Always `make manifests`** after modifying RBAC markers in controller code
9+
- **Never edit** `config/rbac/role.yaml` — it is generated by controller-gen
10+
- **Always `go mod tidy`** before committing
11+
- Run `make lint test` before committing
12+
13+
## Dev Environment
14+
15+
**Language**: Go (see `go.mod`) | **Framework**: controller-runtime (Kubebuilder v4) | **Build tool**: Make | **Container tool**: Podman (default) | **Test framework**: Ginkgo v2 + Gomega | **Linter**: golangci-lint (see `Makefile`)
16+
17+
```bash
18+
make build # Build manager binary
19+
make test # Unit tests (uses envtest, excludes e2e)
20+
make test-e2e # E2E tests (auto-creates/tears down Kind cluster host-management-openstack-test-e2e)
21+
make lint # golangci-lint
22+
make lint-fix # golangci-lint run --fix
23+
make fmt && make vet # Format and vet
24+
25+
make manifests # Generate RBAC, CRD, and webhook manifests via controller-gen (only RBAC output today — no local CRDs or webhooks)
26+
make generate # Generate DeepCopy methods via controller-gen
27+
28+
make run # Run controller locally (requires HOSTLEASE_NAMESPACE env var)
29+
make deploy IMG=<registry>/host-management-openstack:tag
30+
make undeploy # Remove operator from cluster
31+
32+
make image-build IMG=<registry>/host-management-openstack:tag # Build with Podman
33+
make image-push IMG=<registry>/host-management-openstack:tag
34+
make docker-buildx PLATFORMS=linux/amd64,linux/arm64 # Multi-arch build
35+
make build-installer IMG=... # Generate dist/install.yaml (consolidated manifest)
36+
37+
pre-commit run --all-files # Run all pre-commit hooks
38+
```
39+
40+
## Repository Structure
41+
42+
```text
43+
host-management-openstack/
44+
├── cmd/
45+
│ ├── main.go # Operator entry point (manager setup, AAP config, namespace filtering)
46+
│ └── main_test.go # Entry point tests
47+
├── internal/
48+
│ ├── controller/ # HostLease reconciliation (power sync, provisioning lifecycle, finalizers)
49+
│ └── management/ # Power management abstraction (pluggable backend interface, OpenStack impl)
50+
├── config/
51+
│ ├── default/ # Kustomize default overlay
52+
│ ├── manager/ # Manager deployment manifest
53+
│ ├── rbac/ # Generated RBAC rules
54+
│ ├── prometheus/ # Prometheus monitoring config (commented out by default)
55+
│ ├── network-policy/ # Network policy definitions (commented out by default)
56+
│ └── samples/ # Example HostLease CR
57+
├── test/
58+
│ ├── e2e/ # End-to-end tests (Kind cluster)
59+
│ └── utils/ # Test utilities
60+
├── Makefile # Build, test, lint, deploy targets
61+
├── go.mod # Go dependencies (see go.mod)
62+
└── .golangci.yml # Linter configuration
63+
```
64+
65+
## Resources Managed
66+
67+
This operator manages no CRDs. It watches **HostLease** CRs (from bare-metal-fulfillment-operator) filtered by `spec.hostClass == "openstack"` and reconciles their power state via Ironic using `spec.externalHostID` as the Ironic node UUID.
68+
69+
## Architecture
70+
71+
```text
72+
HostLease CR (spec.poweredOn, spec.externalHostID)
73+
↓ (reconcile, filtered by hostClass == "openstack")
74+
HostLease Controller (named "openstack-host")
75+
├── (power sync via) Management Client → OpenStack Ironic
76+
└── (optional provisioning via) osac-operator/pkg/provisioning → AAP
77+
```
78+
79+
### Key Subsystems
80+
81+
| Package | Purpose |
82+
|---------|---------|
83+
| `internal/controller/` | HostLease reconciliation: finalizers, power sync (60s recheck), AAP provisioning (30s poll) |
84+
| `internal/management/` | Power management abstraction with pluggable backend; OpenStack impl via gophercloud v2 |
85+
| `cmd/main.go` | Manager setup, AAP client config (`OSAC_AAP_*` env vars), namespace filtering (`HOSTLEASE_NAMESPACE`) |
86+
87+
## CI
88+
89+
GitHub Actions (`.github/workflows/`):
90+
- **build-image.yaml** — runs tests, builds + pushes container image to GHCR
91+
- **pre-commit.yaml** — pre-commit hooks + golangci-lint on PRs
92+
93+
## Code Quality
94+
95+
- **golangci-lint** (see `Makefile`) with dupl, errcheck, ginkgolinter, goconst, gocyclo, govet, ineffassign, lll, misspell, prealloc, revive, staticcheck, unconvert, unused; formatters: gofmt, goimports (see `.golangci.yml`)
96+
- **Pre-commit hooks**: trailing-whitespace, check-merge-conflict, end-of-file-fixer, check-added-large-files, check-case-conflict, check-json, check-symlinks, detect-private-key, yamllint --strict (excludes `config/`), golangci-lint run --fix
97+
- **Tests**: Ginkgo v2 + Gomega with envtest for unit tests; Kind cluster for e2e (`test/e2e/`)
98+
99+
## Container Security
100+
101+
- **Base images**: Go toolset (builder, see `Containerfile`), gcr.io/distroless/static:nonroot (runtime)
102+
- **Multi-stage build**: CGO_ENABLED=0, runs as non-root user 65532
103+
- **Default registry**: ghcr.io/osac-project/host-management-openstack:latest
104+
105+
## Code Generation Flow
106+
107+
1. Modify RBAC markers in controller code (`internal/controller/`)
108+
2. Run `make manifests` → runs controller-gen for RBAC, CRD, and webhook output; only RBAC is produced today (HostLease CRD is external)
109+
3. Run `make generate` → regenerates DeepCopy methods if API types change
110+
111+
## Test Structure
112+
113+
- `internal/controller/hostlease_controller_test.go` — reconciliation scenarios with envtest
114+
- `internal/management/openstack_internal_test.go` — OpenStack client unit tests
115+
- `internal/management/management_test.go` — backend factory tests
116+
- `cmd/main_test.go` — entry point tests
117+
- `test/e2e/` — end-to-end tests with Kind cluster (named `host-management-openstack-test-e2e`)
118+
- `test/utils/` — shared test utilities
119+
- **ENVTEST_K8S_VERSION**: Auto-detected from k8s.io/api version in go.mod
120+
121+
## Cross-Component Integration
122+
123+
- **bare-metal-fulfillment-operator** — owns the HostLease CRD; must be installed first
124+
- **osac-operator** — provides `pkg/provisioning` (lifecycle state machine) and `pkg/aap` (AAP client); update with `go get github.com/osac-project/osac-operator@<sha> && go mod tidy`
125+
- **fulfillment-service** — creates HostLease resources during bare metal provisioning

0 commit comments

Comments
 (0)