Design (not implemented): a Cluster API infrastructure provider
Status: scoped, not built. This documents what a real Kairon Cluster
API (CAPI) provider -- "Kubernetes clusters made of Kairon Machines,"
managed the standard clusterctl/CAPI way -- would take, and why it's
being named rather than attempted as a quick addition. Read this before
assuming it's close to existing, or trivial to bolt on.
Why this is a separate project, not a feature
Every other item in Kairon's own feature roadmap has been an incremental
addition within the existing kairon-controller/kairon-node
architecture: a new CRD, a new reconcile step, a new field. A real CAPI
infrastructure provider is different in kind, not just size:
- It needs its own CRDs matching CAPI's exact contract --
KaironCluster/KaironMachine/KaironMachineTemplateimplementing theInfrastructureCluster/InfrastructureMachine/InfrastructureMachineTemplateinterfaces CAPI's own corecluster-controller/machine-controllerreconcile against (spec.providerID,status.ready,status.addresses, astatus.failureReason/failureMessagepair, and more) -- a fixed, versioned contract Kairon doesn't get to simplify. - It fundamentally requires
ownerReferences. CAPI's whole object graph (ClusterownsMachineownsKaironMachine, garbage collection cascades through it) is built on Kubernetes'metadata.ownerReferences-- confirmed absent everywhere in this codebase (grep -rn "ownerReferences\|OwnerReference" internal/returns nothing, andmodel.ObjectMeta(internal/model/types.go) has no such field at all). Every other parent-child relationship in Kairon today is a plain name/label reference the reconcile loop resolves itself (MachineMigrationSpec .MachineName,MachineSet's ownkairon.zyvor.dev/machinesetlabel -- seeinternal/controller/machineset.go), a deliberate choice consistent with this project's no-client-go, hand-rolled-API posture. Supporting real ownerReference-based garbage collection means either adopting it project-wide (a cross-cutting model change well beyond this one feature) or building a second, CAPI-only convention that behaves differently from every other CRD kind Kairon already has -- neither is a small addition. - It's a second, separate controller-manager binary and release
artifact, not a new file in
internal/controller-- CAPI providers are conventionally their own repository/binary/Helm chart, registered withclusterctlvia a provider manifest (clusterctl generate provider), versioned and released independently of Kairon's ownkairon-controller. - It needs CAPI's own conformance test suite (
cluster-api/test/e2e) to be a credible, trustworthy provider at all -- not something a unit test in this repo's owninternal/controllerpackage can stand in for.
What genuinely does fit well, if this is built later
Not everything is friction -- two real architectural fits are worth naming so a future design pass doesn't have to rediscover them:
- Bootstrap data bridges cleanly onto
spec.cloudInit. CAPI's bootstrap providers (kubeadm, etc.) hand an infrastructure provider a ready-made cloud-init/ignition blob via a Secret (spec.bootstrap.dataSecretNameon the coreMachine) -- and Kairon'sMachine.spec.cloudInitalready forwards operator-supplied customization verbatim into FluxVM's own cloud-init NoCloud seed image (internal/model.CloudInitSpec, seemachine-network.md). AKaironMachinecontroller could plausibly just read that Secret's contents and pass it straight through asspec.cloudInit's raw payload -- little new plumbing needed on the FluxVM/cloud-init side specifically. MachineSet's replica-reconciliation shape is close to what CAPI's ownMachineDeployment/MachineSetalready expect from an infra template --internal/controller/machineset.go's "create/delete to match a template, track a template-hash label" pattern is conceptually the same shape CAPI itself uses at its own layer, so the reconciliation logic wouldn't be unfamiliar to design, even though the object graph (CRDs, ownerReferences) would be new.
Recommended path if this becomes a priority
Not a Kairon feature PR -- a separate project (its own repository,
following cluster-api-provider-<name> convention), starting from
CAPI's own provider scaffolding (clusterctl init --infrastructure
against a bootstrapped skeleton), that calls into Kairon's existing
internal/kube-style client (or, more likely, just talks to the same
Kubernetes API server the Machine CRD already lives on) to translate
CAPI's KaironMachine objects into ordinary Kairon Machine objects --
treating Kairon's own API exactly the way a cloud infrastructure provider
treats a cloud API, not reaching into Kairon's internals directly.