Documentation
¶
Index ¶
- Constants
- type BootstrapConfirmFn
- type BootstrapSummary
- type BootstrapTerraformEntry
- type ComponentFailure
- type DestroyPlanSummary
- type DestroyResult
- type NodeHealthCheckOptions
- type PlanSummary
- type Provisioner
- func (i *Provisioner) Apply(blueprint *blueprintv1alpha1.Blueprint, componentID string) error
- func (i *Provisioner) ApplyKustomize(ctx context.Context, blueprint *blueprintv1alpha1.Blueprint, ...) error
- func (i *Provisioner) ApplyKustomizeAll(ctx context.Context, blueprint *blueprintv1alpha1.Blueprint) error
- func (i *Provisioner) BeginVersionTransition(blueprint *blueprintv1alpha1.Blueprint) error
- func (i *Provisioner) Bootstrap(blueprint *blueprintv1alpha1.Blueprint, ...) (bool, error)
- func (i *Provisioner) CheckComponentDestroyable(blueprint *blueprintv1alpha1.Blueprint, componentID string) error
- func (i *Provisioner) CheckNodeHealth(ctx context.Context, options NodeHealthCheckOptions, outputFunc func(string)) error
- func (i *Provisioner) CheckVersionGate(blueprint *blueprintv1alpha1.Blueprint) (VersionGate, error)
- func (i *Provisioner) Close()
- func (i *Provisioner) Converge(ctx context.Context, blueprint *blueprintv1alpha1.Blueprint, ...) error
- func (i *Provisioner) Destroy(blueprint *blueprintv1alpha1.Blueprint, componentID string) (bool, error)
- func (i *Provisioner) DestroyAll(blueprint *blueprintv1alpha1.Blueprint, continueOnError bool, ...) (DestroyResult, error)
- func (i *Provisioner) DestroyAllTerraform(blueprint *blueprintv1alpha1.Blueprint, continueOnError bool, ...) (DestroyResult, error)
- func (i *Provisioner) DestroyKustomize(blueprint *blueprintv1alpha1.Blueprint, componentID string) error
- func (i *Provisioner) Down(blueprint *blueprintv1alpha1.Blueprint) error
- func (i *Provisioner) GetVersionMarker() (kubernetes.VersionMarker, bool, error)
- func (i *Provisioner) HasLocalStateWithResources(componentID string) (bool, error)
- func (i *Provisioner) HasRemoteState(blueprint *blueprintv1alpha1.Blueprint, componentID string) (bool, error)
- func (i *Provisioner) InitComponent(blueprint *blueprintv1alpha1.Blueprint, componentID string) error
- func (i *Provisioner) Install(ctx context.Context, blueprint *blueprintv1alpha1.Blueprint, prune bool) error
- func (i *Provisioner) ListLocalStateComponentIDs() ([]string, error)
- func (i *Provisioner) MigrateComponentState(blueprint *blueprintv1alpha1.Blueprint, componentID string) error
- func (i *Provisioner) MigrateState(blueprint *blueprintv1alpha1.Blueprint) ([]string, error)
- func (i *Provisioner) Notify(ctx context.Context, blueprint *blueprintv1alpha1.Blueprint) error
- func (i *Provisioner) OnTerraformApply(fn func(id string) (bool, error))
- func (i *Provisioner) OnTerraformPostApply(fn func(id string) error)
- func (i *Provisioner) PivotToLocalIfClusterGone() (bool, error)
- func (i *Provisioner) PlaceSecrets(ctx context.Context, resolved ResolvedSecrets, ...) error
- func (i *Provisioner) Plan(blueprint *blueprintv1alpha1.Blueprint, componentID string) error
- func (i *Provisioner) PlanAll(blueprint *blueprintv1alpha1.Blueprint) (*PlanSummary, error)
- func (i *Provisioner) PlanDestroyAll(blueprint *blueprintv1alpha1.Blueprint) (*DestroyPlanSummary, error)
- func (i *Provisioner) PlanDestroyKustomizeComponentSummary(blueprint *blueprintv1alpha1.Blueprint, name string) (fluxinfra.KustomizePlan, error)
- func (i *Provisioner) PlanDestroyKustomizeSummary(blueprint *blueprintv1alpha1.Blueprint) (*DestroyPlanSummary, error)
- func (i *Provisioner) PlanDestroyTerraformComponentSummary(blueprint *blueprintv1alpha1.Blueprint, componentID string) (terraforminfra.TerraformComponentPlan, error)
- func (i *Provisioner) PlanDestroyTerraformSummary(blueprint *blueprintv1alpha1.Blueprint) (*DestroyPlanSummary, error)
- func (i *Provisioner) PlanKustomization(blueprint *blueprintv1alpha1.Blueprint, componentID string) error
- func (i *Provisioner) PlanKustomizeAll(blueprint *blueprintv1alpha1.Blueprint) error
- func (i *Provisioner) PlanKustomizeAllJSON(blueprint *blueprintv1alpha1.Blueprint) error
- func (i *Provisioner) PlanKustomizeComponentSummary(blueprint *blueprintv1alpha1.Blueprint, name string) (fluxinfra.KustomizePlan, error)
- func (i *Provisioner) PlanKustomizeJSON(blueprint *blueprintv1alpha1.Blueprint, componentID string) error
- func (i *Provisioner) PlanKustomizeSummary(blueprint *blueprintv1alpha1.Blueprint) (*PlanSummary, error)
- func (i *Provisioner) PlanTerraformAll(blueprint *blueprintv1alpha1.Blueprint) error
- func (i *Provisioner) PlanTerraformAllJSON(blueprint *blueprintv1alpha1.Blueprint) error
- func (i *Provisioner) PlanTerraformAllResourceChangesJSON(blueprint *blueprintv1alpha1.Blueprint) error
- func (i *Provisioner) PlanTerraformComponentSummary(blueprint *blueprintv1alpha1.Blueprint, componentID string) (terraforminfra.TerraformComponentPlan, error)
- func (i *Provisioner) PlanTerraformJSON(blueprint *blueprintv1alpha1.Blueprint, componentID string) error
- func (i *Provisioner) PlanTerraformResourceChangesJSON(blueprint *blueprintv1alpha1.Blueprint, componentID string) error
- func (i *Provisioner) PlanTerraformSummary(blueprint *blueprintv1alpha1.Blueprint) (*PlanSummary, error)
- func (i *Provisioner) PrepareLocalTeardown(blueprint *blueprintv1alpha1.Blueprint) (bool, error)
- func (i *Provisioner) PrunableKustomizations(blueprint *blueprintv1alpha1.Blueprint) ([]string, error)
- func (i *Provisioner) Prune(blueprint *blueprintv1alpha1.Blueprint) error
- func (i *Provisioner) RemoveLocalState(componentID string) error
- func (i *Provisioner) ResolveSecrets(blueprint *blueprintv1alpha1.Blueprint) (ResolvedSecrets, error)
- func (i *Provisioner) Teardown(blueprint *blueprintv1alpha1.Blueprint, terraformOnly bool, ...) (DestroyResult, error)
- func (i *Provisioner) TeardownComponent(blueprint *blueprintv1alpha1.Blueprint, componentID string) (bool, error)
- func (i *Provisioner) Uninstall(blueprint *blueprintv1alpha1.Blueprint) error
- func (i *Provisioner) Up(blueprint *blueprintv1alpha1.Blueprint, ...) (bool, error)
- func (i *Provisioner) UpgradeNode(ctx context.Context, node string, image string, offlineTimeout time.Duration, ...) error
- func (i *Provisioner) UpgradeNodes(ctx context.Context, nodes []string, image string, powercycle bool) error
- func (i *Provisioner) ValidateBackendComponents(blueprint *blueprintv1alpha1.Blueprint) error
- func (i *Provisioner) Wait(ctx context.Context, blueprint *blueprintv1alpha1.Blueprint) error
- func (i *Provisioner) WriteVersionMarker(blueprint *blueprintv1alpha1.Blueprint) error
- type ResolvedSecret
- type ResolvedSecrets
- type VersionGate
Constants ¶
const KustomizeFailureID = "kustomize"
KustomizeFailureID is the sentinel ID for a kustomize Uninstall failure under continue-on-error mode. The kustomize layer reports one aggregate failure, not one per Kustomization.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BootstrapConfirmFn ¶ added in v0.9.0
type BootstrapConfirmFn func(*BootstrapSummary) bool
BootstrapConfirmFn receives the bootstrap summary and returns true to proceed.
type BootstrapSummary ¶ added in v0.9.0
type BootstrapSummary struct {
ContextName string
BackendType string
Terraform []BootstrapTerraformEntry
Kustomize []string
}
BootstrapSummary describes the operator-visible intent of a bootstrap call.
func BuildBootstrapSummary ¶ added in v0.9.0
func BuildBootstrapSummary(blueprint *blueprintv1alpha1.Blueprint, contextName, backendType string) *BootstrapSummary
BuildBootstrapSummary constructs the operator-visible intent description for a bootstrap, independent of any Provisioner instance so the project layer can render the plan before committing to privileged work. The CRD layers are materialized via withCrdLayer so the bootstrap plan lists the synthesized "crds"/"crds-<source>" kustomizations the stack installs, matching what `windsor plan` shows rather than hiding them until apply.
type BootstrapTerraformEntry ¶ added in v0.9.0
BootstrapTerraformEntry is a single row in the Terraform section of the bootstrap summary.
type ComponentFailure ¶ added in v0.9.0
type ComponentFailure = terraforminfra.ComponentFailure
ComponentFailure is a per-component error captured during continue-on-error destroy. Aliased from the terraform package so callers can use a single type identity across the layer boundary without duplication.
type DestroyPlanSummary ¶ added in v0.9.0
type DestroyPlanSummary struct {
Terraform []terraforminfra.TerraformComponentPlan
Kustomize []fluxinfra.KustomizePlan
}
DestroyPlanSummary holds aggregated destroy-plan results across all infrastructure layers. The shape mirrors PlanSummary but without the Hints field: destroy is gated on a working cluster (the kustomize layer queries flux's live inventory), so a tooling-missing fallback is not part of the destroy contract — fail fast instead. The TerraformComponentPlan and KustomizePlan entries here come from the destroy-side producers; renderers must use a destroy-aware formatter to translate IsNew correctly (apply-side "(new)" becomes destroy-side "(no state)" / "(not deployed)").
type DestroyResult ¶ added in v0.9.0
type DestroyResult struct {
Destroyed []string
Skipped []string
SkippedClusterGone []string
Failed []ComponentFailure
TerraformDeferred bool
}
DestroyResult is the cmd-facing aggregate of a destroy pass. Destroyed, Skipped, and Failed roll up every component the provisioner attempted, kustomize and terraform. TerraformDeferred marks that the terraform stage was skipped: a kustomize failure occurred, or a non-backend component still needs work. Add fields for other destroy layers, such as Helm, to this type, not to the terraform-package outcome.
SkippedClusterGone is separate from Skipped. It names kustomizations skipped for a missing kubeconfig, not empty terraform state. An empty terraform state may be an orphan hazard. A missing kubeconfig on a destroy re-run just means the cluster is already gone. See reportSkippedDestroyComponents and reportSkippedClusterGoneKustomizations in cmd/destroy.go.
type NodeHealthCheckOptions ¶
type NodeHealthCheckOptions struct {
Nodes []string
Timeout time.Duration
Version string
K8SEndpoint string
K8SEndpointProvided bool
CheckNodeReady bool
SkipServices []string
WaitForReboot bool
OfflineTimeout time.Duration
}
NodeHealthCheckOptions contains options for node health checking.
type PlanSummary ¶ added in v0.9.0
type PlanSummary struct {
Terraform []terraforminfra.TerraformComponentPlan
Kustomize []fluxinfra.KustomizePlan
Hints []string
}
PlanSummary holds aggregated plan results across all infrastructure layers. Terraform contains one entry per enabled component; Kustomize contains one entry per non-destroyOnly kustomization. Either slice may be nil when the corresponding layer is absent from the blueprint or its tooling is unavailable. Hints contains upgrade suggestions collected when required CLI tools are absent.
type Provisioner ¶
type Provisioner struct {
TerraformStack terraforminfra.Stack
FluxStack fluxinfra.Stack
Notifier fluxinfra.Notifier
KubernetesManager kubernetes.KubernetesManager
KubernetesClient k8sclient.KubernetesClient
ClusterClient cluster.ClusterClient
// contains filtered or unexported fields
}
Provisioner manages the lifecycle of all infrastructure components (terraform, kubernetes, clusters). It provides a unified interface for creating, initializing, and managing these infrastructure components with proper dependency injection and error handling.
func NewProvisioner ¶
func NewProvisioner(rt *runtime.Runtime, blueprintHandler blueprint.BlueprintHandler, opts ...*Provisioner) *Provisioner
NewProvisioner creates a new Provisioner instance with the provided runtime and blueprint handler. It sets up kubernetes manager and kubernetes client. Terraform stack and cluster client are initialized lazily when needed by the Up(), Down(), and WaitForHealth() methods. Panics if runtime or blueprintHandler are nil.
func (*Provisioner) Apply ¶ added in v0.9.0
func (i *Provisioner) Apply(blueprint *blueprintv1alpha1.Blueprint, componentID string) error
Apply runs terraform init, plan, and apply for a single component identified by componentID. Returns an error if terraform is disabled, the stack cannot be initialized, the component is not found, or any terraform operation fails.
func (*Provisioner) ApplyKustomize ¶ added in v0.9.0
func (i *Provisioner) ApplyKustomize(ctx context.Context, blueprint *blueprintv1alpha1.Blueprint, componentID string) error
ApplyKustomize applies a single kustomization identified by componentID to the cluster and places its declared secrets. It finds the named kustomization in the blueprint, filters the blueprint to that one kustomization (preserving sources and repository for correct source creation), resolves that kustomization's secrets, applies it via the kubernetes manager, then places the resolved secrets into the namespace it creates — scoped to the one kustomization so placement never blocks on a namespace another kustomization would create. Secret pruning is off, since a single-kustomization apply is additive. Returns an error if the blueprint is nil, the kubernetes manager is not configured, the kustomization is not found, the kustomization is marked destroyOnly, or resolution, apply, or placement fails.
func (*Provisioner) ApplyKustomizeAll ¶ added in v0.9.0
func (i *Provisioner) ApplyKustomizeAll(ctx context.Context, blueprint *blueprintv1alpha1.Blueprint) error
ApplyKustomizeAll applies all non-destroyOnly kustomizations in the blueprint to the cluster and places their declared secrets. Delegates to Install with pruning off, since applying the full set is additive here — kustomization and secret pruning are separate, explicitly-flagged steps. Returns an error if the blueprint is nil, the kubernetes manager is not configured, or the apply or placement fails.
func (*Provisioner) BeginVersionTransition ¶ added in v0.9.0
func (i *Provisioner) BeginVersionTransition(blueprint *blueprintv1alpha1.Blueprint) error
BeginVersionTransition writes the in-flight marker for an upgrade toward blueprint: it preserves the applied source set from the existing marker (empty for a legacy context) and records the blueprint's set as the target under the upgrading phase. apply's version gate refuses while the marker is non-idle; WriteVersionMarker settles it to idle on success.
func (*Provisioner) Bootstrap ¶ added in v0.9.0
func (i *Provisioner) Bootstrap(blueprint *blueprintv1alpha1.Blueprint, onApply ...func(id string) (bool, error)) (bool, error)
Bootstrap brings up a context's infrastructure end-to-end; it is a thin alias for Up — see Up's doc for the backend pivot. Kept as a distinct, self-documenting entry point for `windsor bootstrap`'s explicit-confirmation flow. Returns (halted, err); halted=true means an inner apply call stopped cleanly after a component (e.g. cluster reachability needs operator action), leaving bootstrap partially complete until the operator re-runs it.
func (*Provisioner) CheckComponentDestroyable ¶ added in v0.9.0
func (i *Provisioner) CheckComponentDestroyable(blueprint *blueprintv1alpha1.Blueprint, componentID string) error
CheckComponentDestroyable reports whether a single terraform component may be destroyed in isolation. On a non-local backend a backend component is refused: its state provides the backend every other component uses, so destroying it directly would orphan their state. Callers run this before generating a destroy plan so the refusal is surfaced up front, rather than as a raw terraform init error when the component tries to reach a kubernetes backend whose cluster may already be gone. A Backend that names no real component also refuses outright — see resolveBackendComponents.
func (*Provisioner) CheckNodeHealth ¶
func (i *Provisioner) CheckNodeHealth(ctx context.Context, options NodeHealthCheckOptions, outputFunc func(string)) error
CheckNodeHealth performs health checks for cluster nodes and Kubernetes endpoints. It supports checking node health via cluster client (for Talos/Omni clusters) and/or Kubernetes API health checks. The method handles timeout configuration, version checking, and node readiness verification. Returns an error if any health check fails.
func (*Provisioner) CheckVersionGate ¶ added in v0.9.0
func (i *Provisioner) CheckVersionGate(blueprint *blueprintv1alpha1.Blueprint) (VersionGate, error)
CheckVersionGate reads the version marker and reports how the given blueprint relates to it, without deciding policy. A missing marker (pre-bootstrap, no cluster, or legacy) yields MarkerFound=false so callers treat it as "nothing applied yet — proceed". When a marker exists, InFlight reflects a non-idle phase and VersionMatch compares the blueprint's resolved source-ref set against the applied set. Returns an error only on a real read/decode failure or when the blueprint's sources cannot be reduced to an unambiguous set; callers may treat a read failure as best-effort (cluster unreachable) rather than a hard stop.
func (*Provisioner) Close ¶
func (i *Provisioner) Close()
Close releases resources held by provisioner components. It closes cluster client connections if present. This method should be called when the provisioner instance is no longer needed to clean up resources.
func (*Provisioner) Converge ¶ added in v0.9.0
func (i *Provisioner) Converge(ctx context.Context, blueprint *blueprintv1alpha1.Blueprint, timeout time.Duration) error
Converge drives the blueprint's kustomizations toward Ready within timeout, best-effort. Each round it reads readiness, then reconciles and force-nudges any stalled HelmRelease for every kustomization not yet Ready, so a stalled chain recovers in seconds instead of waiting for the next Flux interval. It returns once everything is Ready or the timeout elapses; a still-unready cluster is not an error here (use Wait for that). A nil blueprint or missing kubernetes manager is a no-op.
func (*Provisioner) Destroy ¶ added in v0.9.0
func (i *Provisioner) Destroy(blueprint *blueprintv1alpha1.Blueprint, componentID string) (bool, error)
Destroy runs terraform init and destroy for a single component identified by componentID. Returns (skipped, nil) when the component's state is empty (nothing to destroy), (false, nil) when destroy ran successfully, or (false, err) on any failure. Returns an error if the blueprint is nil, terraform is disabled, the stack cannot be initialized, the component is not found, or any terraform operation fails. TerraformStack bounds refresh and destroy with a timeout, so an unreachable provider fails within that time instead of hanging.
func (*Provisioner) DestroyAll ¶ added in v0.9.0
func (i *Provisioner) DestroyAll(blueprint *blueprintv1alpha1.Blueprint, continueOnError bool, excludeIDs ...string) (DestroyResult, error)
DestroyAll destroys every infrastructure component: kustomizations first, then terraform. Uninstall is a no-op when no local kubeconfig exists. See kubeconfigPresent. DestroyAll then counts eligible kustomizations as SkippedClusterGone, not Destroyed. This keeps `windsor destroy` idempotent after a prior run already tore the cluster down.
Under continueOnError, any kustomize failure defers terraform. See blocksNextStage. Windsor cannot tell whether a live controller is still mid-delete of a resource terraform never tracked, so it never guesses.
excludeIDs skips components in the terraform pass. Callers use this to destroy the backend component last.
func (*Provisioner) DestroyAllTerraform ¶ added in v0.9.0
func (i *Provisioner) DestroyAllTerraform(blueprint *blueprintv1alpha1.Blueprint, continueOnError bool, excludeIDs ...string) (DestroyResult, error)
DestroyAllTerraform destroys all terraform components in reverse dependency order. Components with Destroy set to false, or listed in excludeIDs, are skipped. The cmd-layer symmetric-destroy flow excludes the backend component here, to migrate and destroy it last. Returns the IDs of components skipped for empty state, alongside any error, so callers see partial progress even when a later component fails.
func (*Provisioner) DestroyKustomize ¶ added in v0.9.0
func (i *Provisioner) DestroyKustomize(blueprint *blueprintv1alpha1.Blueprint, componentID string) error
DestroyKustomize deletes a single kustomization by name from the cluster. It is a no-op when no local kubeconfig exists (see kubeconfigPresent): the cluster is already gone, so the kustomization is already gone with it. Returns an error if the blueprint is nil, the kubernetes manager is not configured, the kustomization is not found in the blueprint, or the delete operation fails.
func (*Provisioner) Down ¶
func (i *Provisioner) Down(blueprint *blueprintv1alpha1.Blueprint) error
Down destroys the "workstation" terraform component if it is present in the blueprint, then returns. All other terraform components are left untouched; use Destroy / DestroyAll for those. If terraform is disabled or the blueprint has no "workstation" component, Down is a no-op. Returns an error if the blueprint is nil or the destroy operation fails.
func (*Provisioner) GetVersionMarker ¶ added in v0.9.0
func (i *Provisioner) GetVersionMarker() (kubernetes.VersionMarker, bool, error)
GetVersionMarker reads the applied-version marker for this context's gitops namespace, reporting false when no marker exists (a pre-bootstrap, no-cluster, or legacy context). apply and plan read the marker to gate on the blueprint version; only bootstrap and upgrade write it. Returns false without consulting the cluster when no context-scoped kubeconfig is present — there is no cluster, so nothing is applied and there is no version to read.
func (*Provisioner) HasLocalStateWithResources ¶ added in v0.9.0
func (i *Provisioner) HasLocalStateWithResources(componentID string) (bool, error)
HasLocalStateWithResources reports whether the component's local state file exists and contains at least one resource entry.
func (*Provisioner) HasRemoteState ¶ added in v0.9.0
func (i *Provisioner) HasRemoteState(blueprint *blueprintv1alpha1.Blueprint, componentID string) (bool, error)
HasRemoteState reports whether the component has non-empty state in the currently-configured backend. Call before any backend override so the probe targets the configured remote.
func (*Provisioner) InitComponent ¶ added in v0.9.0
func (i *Provisioner) InitComponent(blueprint *blueprintv1alpha1.Blueprint, componentID string) error
InitComponent runs `terraform init` for one component using the currently- configured backend; no -migrate-state, no plan, no apply.
func (*Provisioner) Install ¶
func (i *Provisioner) Install(ctx context.Context, blueprint *blueprintv1alpha1.Blueprint, prune bool) error
Install applies the blueprint's kustomization layer and places its declared secrets as one unit, so every command that installs kustomizations also materializes their secrets rather than re-wiring that sequence itself. It first resolves the blueprint's declared Secrets to plaintext, failing before any cluster mutation on a misconfigured secret; then applies all blueprint resources in order — namespace, source repositories, and each kustomization — firing a best-effort flux webhook notification inside the same progress scope so flux reconciles immediately instead of at the next interval (notification failures never abort the install); then places the resolved secrets into the namespaces their owning kustomizations create, gating each on namespace creation rather than kustomization readiness so a consumer whose readiness depends on its secret cannot deadlock placement. prune reclaims CLI-placed secrets this context no longer declares, mirroring kustomization prune (on for upgrade and apply --prune, off otherwise). ctx is threaded into Notify and placement so a cancelled parent context (e.g. Ctrl+C) tears down promptly. The blueprint must be provided. Returns an error if resolution, apply, or placement fails.
func (*Provisioner) ListLocalStateComponentIDs ¶ added in v0.9.1
func (i *Provisioner) ListLocalStateComponentIDs() ([]string, error)
ListLocalStateComponentIDs returns every componentID with local Terraform state on disk, whether or not it is still declared in the active blueprint.
func (*Provisioner) MigrateComponentState ¶ added in v0.9.0
func (i *Provisioner) MigrateComponentState(blueprint *blueprintv1alpha1.Blueprint, componentID string) error
MigrateComponentState reinitializes a single Terraform component's backend against the currently configured backend, migrating state as needed. Used by `windsor bootstrap` to move only the backend component's state to remote (e.g. S3) immediately after the backend infrastructure is applied with a local backend; subsequent components then init directly against the configured remote backend on the next Up. Returns an error if the blueprint is nil, the component is not found, terraform is disabled, or any terraform operation fails.
func (*Provisioner) MigrateState ¶ added in v0.9.0
func (i *Provisioner) MigrateState(blueprint *blueprintv1alpha1.Blueprint) ([]string, error)
MigrateState reinitializes every Terraform component's backend against the currently configured backend, migrating state as needed. Used by `windsor bootstrap` after its local-first apply pass to move state to the configured remote backend once that backend's underlying infrastructure (e.g. the kubernetes cluster hosting the k8s backend) has been provisioned. Safe to invoke directly for users who change backend config and want existing state migrated in place. The blueprint parameter is required. Returns the IDs of components whose directories were missing and therefore skipped; callers decide whether that is an error condition — bootstrap treats any skip as anomalous (Up should have materialized every dir); pre-destroy migration discards the list because un-applied components are a normal condition there.
The skipped slice is returned alongside any error (not only on success), mirroring the Stack.MigrateState contract. Dropping it on the error path would strand bootstrap without the context it needs to emit "A was skipped, then B failed" in a single diagnostic — the exact signal the operator needs to investigate what removed A's directory between Up and MigrateState.
func (*Provisioner) Notify ¶ added in v0.9.0
func (i *Provisioner) Notify(ctx context.Context, blueprint *blueprintv1alpha1.Blueprint) error
Notify forwards to the flux webhook Notifier and is intended as the final step of bootstrap/up/apply so flux reconciles the blueprint's sources immediately instead of waiting for its next scheduled interval. The call is best-effort: every failure path inside the Notifier is converted to nil with a warning, so callers can invoke Notify unconditionally without risking command failure on clusters that have no webhook configured.
func (*Provisioner) OnTerraformApply ¶ added in v0.9.0
func (i *Provisioner) OnTerraformApply(fn func(id string) (bool, error))
OnTerraformApply registers a hook to run after each Terraform component apply, inside the progress spinner. The hook returns (haltAfter, err); haltAfter=true signals the component apply succeeded but subsequent components must not be applied (e.g. cluster reachability needs host configuration the operator hasn't done yet). Errors are real failures.
func (*Provisioner) OnTerraformPostApply ¶ added in v0.9.0
func (i *Provisioner) OnTerraformPostApply(fn func(id string) error)
OnTerraformPostApply registers a hook to run after each Terraform component's Done line is printed. Use this for operations that must not run inside the progress spinner (e.g. interactive sudo prompts).
func (*Provisioner) PivotToLocalIfClusterGone ¶ added in v0.9.0
func (i *Provisioner) PivotToLocalIfClusterGone() (bool, error)
PivotToLocalIfClusterGone pivots terraform.backend.type to local, without migrating, when the kubernetes backend's cluster is gone or unreachable — the targeted-destroy counterpart to PrepareLocalTeardown, reading state a prior full teardown already migrated to local. No-op otherwise.
func (*Provisioner) PlaceSecrets ¶ added in v0.9.0
func (i *Provisioner) PlaceSecrets(ctx context.Context, resolved ResolvedSecrets, blueprint *blueprintv1alpha1.Blueprint, prune bool) error
PlaceSecrets materializes secrets that ResolveSecrets produced into their target namespace(s), and — when prune is set — reconciles by deleting the CLI-placed secrets this context no longer wants. It runs after Install. Placement is not serialized: on each round it places every secret whose target namespace already exists and defers the rest, then polls, so a secret whose namespace is ready is never blocked behind one whose namespace is not. This matters because kustomizations commonly depend on a secret the CLI places (e.g. a cloud-controller-manager needs its token before nodes initialize and downstream namespaces appear); placing the ready ones first breaks that cycle rather than deadlocking on a namespace that only appears once an earlier secret is placed. For each secret it resolves the target namespace(s) — the ones the entry named (gated on those existing in the cluster) or, when it named none, the namespace its owning kustomization creates or deploys into (failing closed on more than one so a secret is never placed by guessing) — applies an Opaque Secret into each, and rolls the workloads there that consume it, keyed by a content digest, so a changed value reaches running pods rather than sitting stale. It surfaces a single progress line naming what it is placing or waiting on, and times out naming the secrets whose namespaces never appeared. As it places a secret it requests an immediate flux reconcile of the owning kustomization (the secret is what that kustomization was waiting on), and while waiting it nudges the dependency closure of the still-pending owners on a throttle, so a chain unblocked by a placement advances in seconds rather than one flux interval per hop. When prune is set it records every (namespace, secret) it placed and hands that desired set to PruneSecrets, which reclaims any CLI-placed secret not in it. Pruning is gated so secret reclaim mirrors Kustomization prune: on under apply's --prune and upgrade, off for the place-only flows. When no kubernetes manager is configured it is a no-op only if there is also nothing to place.
func (*Provisioner) Plan ¶ added in v0.9.0
func (i *Provisioner) Plan(blueprint *blueprintv1alpha1.Blueprint, componentID string) error
Plan runs terraform init and plan for a single component identified by componentID. It does not apply any changes. Returns an error if the terraform stack cannot be initialized, the component is not found, or any terraform operation fails.
func (*Provisioner) PlanAll ¶ added in v0.9.0
func (i *Provisioner) PlanAll(blueprint *blueprintv1alpha1.Blueprint) (*PlanSummary, error)
PlanAll runs a best-effort summary plan across every Terraform component and Flux kustomization in the blueprint. It initialises both stacks as needed and collects per-component results without aborting on individual failures, so callers always receive as complete a picture as possible. Returns an error only when blueprint is nil or stack initialisation itself fails.
func (*Provisioner) PlanDestroyAll ¶ added in v0.9.0
func (i *Provisioner) PlanDestroyAll(blueprint *blueprintv1alpha1.Blueprint) (*DestroyPlanSummary, error)
PlanDestroyAll previews the destroy plan across both Terraform and Flux layers, aggregating both into one DestroyPlanSummary. See PlanDestroyKustomizeSummary for the flux-side unreachable-cluster classification.
func (*Provisioner) PlanDestroyKustomizeComponentSummary ¶ added in v0.9.0
func (i *Provisioner) PlanDestroyKustomizeComponentSummary(blueprint *blueprintv1alpha1.Blueprint, name string) (fluxinfra.KustomizePlan, error)
PlanDestroyKustomizeComponentSummary previews the destroy plan for a single Flux kustomization by querying its live inventory. Returns an error if blueprint is nil, stack init fails, or the kustomization is destroyOnly / pinned destroy=false (which DeleteBlueprint would skip).
func (*Provisioner) PlanDestroyKustomizeSummary ¶ added in v0.9.0
func (i *Provisioner) PlanDestroyKustomizeSummary(blueprint *blueprintv1alpha1.Blueprint) (*DestroyPlanSummary, error)
PlanDestroyKustomizeSummary previews the destroy plan for every eligible Flux kustomization from live cluster inventory. A stale kubeconfig reports every kustomization as not-deployed; see FluxStack.PlanDestroySummary. DestroyOnly hooks and destroy=false pinned kustomizations are filtered to match DeleteBlueprint. withCrdLayer flattens FluxSystem tiers and CRD layers first, so the plan matches Uninstall's teardown set.
func (*Provisioner) PlanDestroyTerraformComponentSummary ¶ added in v0.9.0
func (i *Provisioner) PlanDestroyTerraformComponentSummary(blueprint *blueprintv1alpha1.Blueprint, componentID string) (terraforminfra.TerraformComponentPlan, error)
PlanDestroyTerraformComponentSummary previews the destroy plan for a single Terraform component. Returns an error if blueprint is nil, stack init fails, or the component is pinned destroy=false (which Teardown would skip).
func (*Provisioner) PlanDestroyTerraformSummary ¶ added in v0.9.0
func (i *Provisioner) PlanDestroyTerraformSummary(blueprint *blueprintv1alpha1.Blueprint) (*DestroyPlanSummary, error)
PlanDestroyTerraformSummary previews the destroy plan for every Terraform component the blueprint would actually tear down (filtering destroy=false pins). Mirrors PlanTerraformSummary but uses `terraform plan -destroy -json` per component. Returns an error only when blueprint is nil or stack init fails.
func (*Provisioner) PlanKustomization ¶ added in v0.9.0
func (i *Provisioner) PlanKustomization(blueprint *blueprintv1alpha1.Blueprint, componentID string) error
PlanKustomization runs flux diff for a single kustomization identified by componentID. Returns an error if the flux CLI is not found, the component is not in the blueprint, or the diff fails.
func (*Provisioner) PlanKustomizeAll ¶ added in v0.9.0
func (i *Provisioner) PlanKustomizeAll(blueprint *blueprintv1alpha1.Blueprint) error
PlanKustomizeAll runs flux diff for every non-destroyOnly kustomization in the blueprint. Returns an error if the flux CLI is not found or any diff fails.
func (*Provisioner) PlanKustomizeAllJSON ¶ added in v0.9.0
func (i *Provisioner) PlanKustomizeAllJSON(blueprint *blueprintv1alpha1.Blueprint) error
PlanKustomizeAllJSON runs kustomize build for every non-destroyOnly kustomization and writes JSON to stdout. Returns an error if the kustomize CLI is not found or any build fails.
func (*Provisioner) PlanKustomizeComponentSummary ¶ added in v0.9.0
func (i *Provisioner) PlanKustomizeComponentSummary(blueprint *blueprintv1alpha1.Blueprint, name string) (fluxinfra.KustomizePlan, error)
PlanKustomizeComponentSummary plans a single Flux kustomization and returns its structured result. Returns an error only when blueprint is nil or stack initialisation fails.
func (*Provisioner) PlanKustomizeJSON ¶ added in v0.9.0
func (i *Provisioner) PlanKustomizeJSON(blueprint *blueprintv1alpha1.Blueprint, componentID string) error
PlanKustomizeJSON runs kustomize build for the named kustomization (or all when componentID is "all") and writes the rendered manifests as JSON to stdout. Returns an error if blueprint is nil, the stack cannot be initialised, or the build fails.
func (*Provisioner) PlanKustomizeSummary ¶ added in v0.9.0
func (i *Provisioner) PlanKustomizeSummary(blueprint *blueprintv1alpha1.Blueprint) (*PlanSummary, error)
PlanKustomizeSummary runs a best-effort summary plan across every Flux kustomization in the blueprint without touching the Terraform layer. Returns an error only when blueprint is nil or stack initialisation fails.
func (*Provisioner) PlanTerraformAll ¶ added in v0.9.0
func (i *Provisioner) PlanTerraformAll(blueprint *blueprintv1alpha1.Blueprint) error
PlanTerraformAll runs terraform init and plan for every enabled component, streaming output directly. Returns an error if blueprint is nil, the stack cannot be initialised, or any component's plan fails.
func (*Provisioner) PlanTerraformAllJSON ¶ added in v0.9.0
func (i *Provisioner) PlanTerraformAllJSON(blueprint *blueprintv1alpha1.Blueprint) error
PlanTerraformAllJSON runs terraform plan -json for every enabled component, streaming machine-readable JSON lines output directly to stdout. Returns an error if blueprint is nil, the stack cannot be initialised, or any component's plan fails.
func (*Provisioner) PlanTerraformAllResourceChangesJSON ¶ added in v0.9.1
func (i *Provisioner) PlanTerraformAllResourceChangesJSON(blueprint *blueprintv1alpha1.Blueprint) error
PlanTerraformAllResourceChangesJSON runs terraform plan and show -json for every enabled component, printing each component's plan document directly to stdout. Returns an error if blueprint is nil, the stack cannot be initialised, or any component's plan fails.
func (*Provisioner) PlanTerraformComponentSummary ¶ added in v0.9.0
func (i *Provisioner) PlanTerraformComponentSummary(blueprint *blueprintv1alpha1.Blueprint, componentID string) (terraforminfra.TerraformComponentPlan, error)
PlanTerraformComponentSummary plans a single Terraform component and returns its structured result. Returns an error only when blueprint is nil or stack initialisation fails.
func (*Provisioner) PlanTerraformJSON ¶ added in v0.9.0
func (i *Provisioner) PlanTerraformJSON(blueprint *blueprintv1alpha1.Blueprint, componentID string) error
PlanTerraformJSON runs terraform plan -json for a single component, streaming machine-readable JSON lines output directly to stdout. Returns an error if blueprint is nil, the stack cannot be initialised, or the plan fails.
func (*Provisioner) PlanTerraformResourceChangesJSON ¶ added in v0.9.1
func (i *Provisioner) PlanTerraformResourceChangesJSON(blueprint *blueprintv1alpha1.Blueprint, componentID string) error
PlanTerraformResourceChangesJSON runs terraform plan and show -json for a single component, printing the resulting plan document directly to stdout. Returns an error if blueprint is nil, the stack cannot be initialised, or the plan fails.
func (*Provisioner) PlanTerraformSummary ¶ added in v0.9.0
func (i *Provisioner) PlanTerraformSummary(blueprint *blueprintv1alpha1.Blueprint) (*PlanSummary, error)
PlanTerraformSummary runs a best-effort summary plan across every Terraform component in the blueprint without touching the Flux/Kustomize layer. Returns an error only when blueprint is nil or stack initialisation fails.
func (*Provisioner) PrepareLocalTeardown ¶ added in v0.9.0
func (i *Provisioner) PrepareLocalTeardown(blueprint *blueprintv1alpha1.Blueprint) (bool, error)
PrepareLocalTeardown migrates every component's state to local and pivots terraform.backend.type to local, so a kubernetes-backend teardown never dials the cluster it's about to destroy. A migration failure aborts only while the cluster is still reachable; once it's gone, state was already migrated on an earlier pass. No-op for a non-kubernetes backend.
func (*Provisioner) PrunableKustomizations ¶ added in v0.9.0
func (i *Provisioner) PrunableKustomizations(blueprint *blueprintv1alpha1.Blueprint) ([]string, error)
PrunableKustomizations returns the names of this context's Kustomizations that the blueprint no longer declares — exactly what Prune would delete. It is the read-only input to plan's prune preview and upgrade's confirmation gate; it deletes nothing. It prepares the blueprint with the synthesized CRD layers so the desired set matches what Prune deletes against.
func (*Provisioner) Prune ¶ added in v0.9.0
func (i *Provisioner) Prune(blueprint *blueprintv1alpha1.Blueprint) error
Prune removes Kustomizations belonging to this context that are no longer present in the blueprint, leaving every still-declared kustomization (platform and user) and any other context's kustomizations untouched. It prepares the blueprint with the synthesized CRD layers — matching what Install applied — so those layers are recognized as desired and not pruned.
func (*Provisioner) RemoveLocalState ¶ added in v0.9.0
func (i *Provisioner) RemoveLocalState(componentID string) error
RemoveLocalState removes the per-component local terraform state file. Missing files are tolerated.
func (*Provisioner) ResolveSecrets ¶ added in v0.9.0
func (i *Provisioner) ResolveSecrets(blueprint *blueprintv1alpha1.Blueprint) (ResolvedSecrets, error)
ResolveSecrets resolves every flux system's declared Secrets to plaintext ahead of Install, so a misconfigured secret fails the command before anything is applied to the cluster. For each compiled kustomization carrying Secrets it evaluates each data reference (the evaluator registers resolved values with the shell scrubber). A reference that resolves to nothing — nil (absent from configuration or a secret() lookup that failed to resolve) or an empty string — fails closed unless it carries a "??" default, since a required key that resolves away is misconfiguration and silently dropping it strands a downstream consumer with a missing key. Adding a ?? default marks the key optional and omits it. A secret whose keys all resolve away is not created at all, so an optional secret leaves no empty Secret behind. The result is keyed by owning kustomization for PlaceSecrets to materialize post-Install; it is empty when no kustomization declares Secrets.
func (*Provisioner) Teardown ¶ added in v0.9.0
func (i *Provisioner) Teardown(blueprint *blueprintv1alpha1.Blueprint, terraformOnly bool, continueOnError bool) (DestroyResult, error)
Teardown reverses Bootstrap.
Without a declared backend, Teardown forwards to DestroyAll (or DestroyAllTerraform when terraformOnly is true).
With a backend declared via Blueprint.Backend, Teardown destroys in stages:
- Destroy every non-backend component.
- Destroy the backend's other components, if Stage 1 had no failures.
- Destroy the backend component itself, if Stage 2 had no failures.
This order keeps the state store alive until its dependents are gone. See blocksNextStage for the failure check between stages. TerraformDeferred marks a skipped stage.
A Backend that names no real component is refused; see resolveBackendComponents.
func (*Provisioner) TeardownComponent ¶ added in v0.9.0
func (i *Provisioner) TeardownComponent(blueprint *blueprintv1alpha1.Blueprint, componentID string) (bool, error)
TeardownComponent destroys a single terraform component. Targeting any backend component on a non-local backend is refused: its state provides the backend that other components rely on, so destroying it in isolation would orphan their state. Use `windsor destroy` (no arguments) for the full-cycle teardown.
func (*Provisioner) Uninstall ¶
func (i *Provisioner) Uninstall(blueprint *blueprintv1alpha1.Blueprint) error
Uninstall orchestrates the high-level kustomization teardown process from the blueprint. It initializes the kubernetes manager and deletes all blueprint kustomizations, including the synthesized CRD layer (withCrdLayer) so its Flux Kustomization objects are removed symmetrically with apply; the layer keeps Prune disabled, so the vendored CRDs themselves are retained. DeleteBlueprint emits its own per-Kustomization progress (Start/Done/Fail spinners), so this method does not wrap the call in WithProgress — doing so would suppress the inner per-Kustomization output and produce a single opaque "Removing blueprint resources" line that hides the long per-Kustomization waits inherent to WaitForTermination-driven teardown.
Uninstall is a no-op when no local kubeconfig exists. See kubeconfigPresent for the reasoning: a missing kubeconfig means the cluster is already gone, so there is nothing to suspend or delete, and building a client would only fail with a stat error.
func (*Provisioner) Up ¶
func (i *Provisioner) Up(blueprint *blueprintv1alpha1.Blueprint, onApply ...func(id string) (bool, error)) (bool, error)
Up orchestrates the high-level infrastructure deployment process. When the blueprint declares a backend it pivots through local state first, then the configured backend (applyWithBackendPivot) — unconfirmed, same as any other apply through this method, including from cmd/apply.go and cmd/up.go; confirmation is a cmd/bootstrap.go concern, not this method's. Without a declared backend it applies directly. A kubernetes backend with no declared backend and no kubeconfig yet is refused with an actionable error instead of a raw terraform connection failure. On a remote backend, a declared Backend that names no real component is refused rather than silently treated as unset — see resolveBackendComponents. Returns (halted, err); halted=true means a hook stopped after a component.
func (*Provisioner) UpgradeNode ¶ added in v0.9.0
func (i *Provisioner) UpgradeNode(ctx context.Context, node string, image string, offlineTimeout time.Duration, powercycle bool, outputFunc func(string)) error
UpgradeNode performs a complete per-node upgrade: captures the node's current boot ID, sends the upgrade gRPC request (wait=false), waits for the node to reboot (confirmed by its boot ID changing, offlineTimeout caps this phase), waits for the node to come back healthy, then performs a final service health check. powercycle requests a full ACPI reboot instead of the default kexec, needed on platforms (e.g. nested virtualization) where kexec doesn't reliably register as an offline transition. outputFunc receives status messages during the wait phases. Returns an error if any step fails or times out.
func (*Provisioner) UpgradeNodes ¶ added in v0.9.0
func (i *Provisioner) UpgradeNodes(ctx context.Context, nodes []string, image string, powercycle bool) error
UpgradeNodes sends an upgrade request to specified cluster nodes. powercycle requests a full ACPI reboot instead of the default kexec. It initializes the cluster client based on config, then calls UpgradeNodes on it. The caller is responsible for subsequently monitoring reboot status. Returns an error if the cluster client cannot be initialized or if any node upgrade request fails.
func (*Provisioner) ValidateBackendComponents ¶ added in v0.9.1
func (i *Provisioner) ValidateBackendComponents(blueprint *blueprintv1alpha1.Blueprint) error
ValidateBackendComponents refuses a Blueprint.Backend that names no real component, before a destroy plan is generated.
func (*Provisioner) Wait ¶
func (i *Provisioner) Wait(ctx context.Context, blueprint *blueprintv1alpha1.Blueprint) error
Wait waits for kustomizations from the blueprint to be ready. It initializes the kubernetes manager if needed and polls the status of all kustomizations until they are ready or a timeout occurs. The timeout is calculated from the longest dependency chain in the blueprint. The wait honors ctx, so a cancelled context (caller SIGTERM/Ctrl+C or command deadline) ends it promptly. Returns an error if the kubernetes manager is not configured, initialization fails, or waiting times out.
func (*Provisioner) WriteVersionMarker ¶ added in v0.9.0
func (i *Provisioner) WriteVersionMarker(blueprint *blueprintv1alpha1.Blueprint) error
WriteVersionMarker records the blueprint version applied to this context as a marker ConfigMap in the gitops namespace, capturing the resolved reference of each applied source. Only bootstrap and upgrade write the marker; apply and plan only read it, so the marker stays an authoritative record of what was deliberately rolled out rather than drifting with every reconcile.
type ResolvedSecret ¶ added in v0.9.0
ResolvedSecret is one Secret ready to place: its resolved plaintext data and the namespaces it targets. Namespaces is empty when the authored entry named none, in which case placement auto-resolves the single namespace the owning kustomization creates.
type ResolvedSecrets ¶ added in v0.9.0
type ResolvedSecrets map[string]map[string]ResolvedSecret
ResolvedSecrets maps an owning kustomization name to the Secrets ready to place in the namespace(s) it creates: Secret name -> ResolvedSecret (target namespaces plus resolved plaintext data). It holds resolved secret material in memory only (never serialized), produced by ResolveSecrets before Install and consumed by PlaceSecrets after.
type VersionGate ¶ added in v0.9.0
type VersionGate struct {
MarkerFound bool // a marker exists for this context (false = pre-bootstrap, no cluster, or legacy)
InFlight bool // the marker phase is not idle (an upgrade is in flight)
VersionMatch bool // the blueprint's resolved source-ref set equals the applied set
}
VersionGate describes how the blueprint a command is about to apply relates to the version marker recorded in the cluster. It is the input to apply's version-equality seam: apply may reconcile in place only when a settled marker matches the blueprint it would apply. Any other state — a version mismatch or an in-flight transition — belongs to upgrade. The caller decides policy (proceed, refuse, or honor --force); this struct only reports the relation.