This document provides context and guidelines for AI coding assistants working with the Cluster API Operator repository.
The Cluster API Operator is a Kubernetes Operator that manages the lifecycle of Cluster API providers within a management cluster using a declarative approach. It extends the capabilities of the clusterctl CLI, enabling GitOps workflows and automation.
- Organization: Kubernetes SIG Cluster Lifecycle
- Module:
sigs.k8s.io/cluster-api-operator - Documentation: https://cluster-api-operator.sigs.k8s.io
- Language: Go
- Framework: controller-runtime
- Kubernetes Libraries: client-go, apimachinery, apiextensions-apiserver
- Cluster API: sigs.k8s.io/cluster-api
- Testing: Ginkgo/Gomega, envtest
- Build: Make, Docker
- Local Development: Tilt
cluster-api-operator/
├── api/v1alpha2/ # CRD type definitions and interfaces
├── cmd/ # Main entry point and CLI plugin
├── config/ # Kustomize manifests (CRDs, RBAC, webhooks)
├── controller/ # Public controller aliases
├── internal/
│ ├── controller/ # Controller implementations
│ ├── envtest/ # Test environment setup
│ ├── patch/ # Patch utilities
│ └── webhook/ # Admission webhook implementations
├── hack/ # Build scripts and tools
├── test/ # E2E tests and test framework
├── util/ # Shared utilities
└── version/ # Version information
The operator manages seven types of Cluster API providers:
| Type | CRD | Description |
|---|---|---|
| Core | CoreProvider |
Core Cluster API components |
| Infrastructure | InfrastructureProvider |
Cloud/infrastructure providers (AWS, Azure, vSphere, etc.) |
| Bootstrap | BootstrapProvider |
Node bootstrap providers (Kubeadm, etc.) |
| ControlPlane | ControlPlaneProvider |
Control plane providers (Kubeadm, etc.) |
| Addon | AddonProvider |
Addon providers (Helm, etc.) |
| IPAM | IPAMProvider |
IP Address Management providers |
| RuntimeExtension | RuntimeExtensionProvider |
Runtime extension providers |
All providers implement the GenericProvider interface (api/v1alpha2/genericprovider_interfaces.go):
type GenericProvider interface {
client.Object
conditions.Setter
GetSpec() ProviderSpec
SetSpec(in ProviderSpec)
GetStatus() ProviderStatus
SetStatus(in ProviderStatus)
GetType() string
ProviderName() string
}This pattern enables a single GenericProviderReconciler to handle all provider types.
Provider reconciliation follows a phased approach (internal/controller/phases.go):
ApplyFromCache- Apply cached configuration if unchangedPreflightChecks- Validate prerequisitesInitializePhaseReconciler- Set up clusterctl configurationDownloadManifests- Fetch provider manifests (OCI/GitHub/ConfigMap)Load- Load provider configurationFetch- Process YAML manifestsStore- Cache processed manifestsUpgrade- Handle version upgradesInstall- Apply provider componentsReportStatus- Update provider statusFinalize- Cleanup
- Follow Kubernetes coding conventions
- Use
klogfor logging via controller-runtime'sctrl.LoggerFrom(ctx) - Handle errors with proper wrapping using
fmt.Errorf("message: %w", err) - Use the
PhaseErrortype for reconciliation errors with conditions
- API Changes: Modify types in
api/v1alpha2/, runmake generate manifests - Controller Changes: Implement in
internal/controller/ - Webhooks: Add to
internal/webhook/ - Tests: Add unit tests alongside code, E2E tests in
test/e2e/
# Run unit tests
make test
# Run linters
make lint
# Run E2E tests
make test-e2e
# Generate mocks and deep copy
make generate- Clone
cluster-apialongside this repository - Configure
tilt-settings.yamlin cluster-api:provider_repos: - "../cluster-api-operator" enable_providers: - capi-operator enable_core_provider: false
- Run
make tilt-upfrom the cluster-api directory
| Target | Description |
|---|---|
make build |
Build the operator binary |
make docker-build |
Build Docker image |
make test |
Run unit tests |
make lint |
Run linters |
make generate |
Generate code (deep copy, manifests) |
make manifests |
Generate CRD manifests |
make help |
Show all available targets |
Use the cluster-api conditions utilities:
import "sigs.k8s.io/cluster-api/util/conditions"
// Set a condition
conditions.Set(provider, metav1.Condition{
Type: operatorv1.ProviderInstalledCondition,
Status: metav1.ConditionTrue,
Reason: "ProviderInstalled",
Message: "Provider installed successfully",
})Always use the patch helper for updates:
patchHelper, err := patch.NewHelper(provider, r.Client)
if err != nil {
return ctrl.Result{}, err
}
defer func() {
if err := patchHelper.Patch(ctx, provider); err != nil {
reterr = kerrors.NewAggregate([]error{reterr, err})
}
}()Providers can fetch manifests from three sources:
- OCI Registry:
spec.fetchConfig.oci - GitHub URL:
spec.fetchConfig.url - ConfigMap:
spec.fetchConfig.selector
Current API version: v1alpha2 (operator.cluster.x-k8s.io/v1alpha2)
- Cluster API - Main Cluster API project
- clusterctl - CLI tool this operator extends
- Slack: #cluster-api-operator on Kubernetes Slack
- Documentation: https://cluster-api-operator.sigs.k8s.io