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) 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) PlanTerraformComponentSummary(blueprint *blueprintv1alpha1.Blueprint, componentID string) (terraforminfra.TerraformComponentPlan, error)
- func (i *Provisioner) PlanTerraformJSON(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) 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 used when the kustomize Uninstall step fails under continue-on-error mode. The kustomize layer surfaces a single aggregate failure rather than per-Kustomization entries, so the tier-gate logic in Teardown can distinguish kustomize failures (which do not block the terraform backend tier) from terraform-component failures (which do).
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
Failed []ComponentFailure
TierDeferred bool
}
DestroyResult is the cmd-facing aggregate of a destroy pass. Destroyed, Skipped, and Failed roll up every component the provisioner attempted — kustomize plus terraform — and TierDeferred records the provisioner-layer decision to leave the backend tier alone when a non-tier component still needs work. Fields for additional destroy layers (e.g. Helm) belong on this type, not on the terraform-package outcome.
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. For local or external backends it forwards to Up. For an in-blueprint backend tier (Blueprint.Backend set) it always pivots the tier: Stage 1 pins local, pulls any existing tier state from the configured backend to local, applies the tier against local; Stage 2 pushes tier state to the configured backend; Stage 3 applies non-tier components. The algorithm is idempotent — every bootstrap runs the same flow regardless of whether the backend already exists.
Returns (halted, err). halted=true means one of the inner Up calls signaled a clean halt-after-component (e.g. cluster reachability needs operator action). On halt the caller surfaces the deferred-work summary; bootstrap is partially complete and the operator re-runs after addressing it. Operator confirmation is the project layer's responsibility — callers gate Bootstrap on the operator's decision so declining the plan never reaches privileged work (workstation startup, DNS, etc.).
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-tier member 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.
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 actively drives the blueprint's kustomizations toward Ready within timeout, best-effort. Each round it reads readiness (without failing on a failed kustomization) and, for every kustomization not yet Ready, requests an immediate reconcile and forces any stalled HelmRelease it owns — so a chain that stalled after apply (a dependent waiting on a now-ready dependency, or a HelmRelease that failed and exhausted its remediation) recovers in seconds rather than at the next flux interval. Nudges are throttled to keep reconcile traffic modest. It returns as soon as every kustomization is Ready, or when timeout elapses; it is a driver, not a gate, so a still-unready cluster is not an error here — callers that must fail on un-readiness use Wait afterward. 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. Runs checkKubernetesReachableForDestroy once terraform is confirmed enabled.
func (*Provisioner) DestroyAll ¶ added in v0.9.0
func (i *Provisioner) DestroyAll(blueprint *blueprintv1alpha1.Blueprint, continueOnError bool, excludeIDs ...string) (DestroyResult, error)
DestroyAll destroys all infrastructure components: first uninstalls all kustomizations, then destroys all terraform components. The kustomization uninstall step is skipped when no kubeconfig exists at the context-scoped path — the cluster is gone (or was never bootstrapped past terraform), so trying to talk to its API would fail with a stat error and abort the whole destroy. Skipping idempotently lets `windsor destroy` run cleanly after the cluster's already been torn down by a prior partial destroy or out-of-band action. excludeIDs are forwarded to the terraform destroy pass so cmd-layer callers can peel off the backend component for the symmetric-destroy flow (destroy non-backend against live remote state, then migrate-and-destroy backend last). Returns the IDs of terraform components that were skipped because their state was empty (never applied, already torn down) alongside any error from either step — paired with the error so callers see what was no-op'd even when a later step fails. Returns an error if either step fails. checkKubernetesReachableForDestroy runs after the kustomize step (so it never fires if kustomize already hard-failed) and before terraform.
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 the stack in reverse dependency order. Components with Destroy set to false are skipped. excludeIDs are skipped entirely (used by the cmd-layer symmetric-destroy flow to peel the backend component off the bulk pass and migrate it before destroying it last). If terraform is disabled, returns an error. Returns the IDs of components that were skipped because their state was empty alongside any error, mirroring the MigrateState contract — the slice is paired with the error so callers see partial progress even when a later component fails. Skipped components had nothing in state to destroy (never applied, fully torn down already, or upstream destroy collapsed their cloud objects out from under them); cmd-layer callers surface them in the user-facing summary so an operator can see "these were no-ops" alongside "these were destroyed". Runs checkKubernetesReachableForDestroy once terraform is confirmed enabled.
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. 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) 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 for the rest of the process when the kubernetes backend's cluster is gone (no kubeconfig) or unreachable. Unlike PrepareLocalTeardown it does not migrate — the state is already the local copy a prior full teardown pulled off the cluster before destroying it — it only redirects reads to that copy. This is the targeted-destroy counterpart: a single component destroy cannot migrate everything to local without stranding the cluster-up case (one component destroyed locally while the rest still read kubernetes would drift), so it operates on kubernetes while the cluster is up and on the already-migrated local state once the cluster is gone. A reachable cluster or non-kubernetes backend is a no-op. Returns whether it pivoted.
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. Initialises each stack as needed and aggregates the results into a single DestroyPlanSummary for rendering. A cluster failure on the flux side aborts the whole plan — destroy needs the cluster, so a partial plan would be misleading.
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 by querying live cluster inventory. Returns an error if the cluster is unreachable — destroy itself cannot proceed without it, so a blueprint-derived fallback would mislead. DestroyOnly hooks and destroy= false pinned kustomizations are filtered to match DeleteBlueprint. The blueprint is passed through withCrdLayer so FluxSystem tiers and synthesized CRD layers are flattened into Kustomizations — matching Uninstall's teardown set exactly, so the plan lists the same kustomizations the destroy removes.
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) 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) 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 makes a kubernetes-backend teardown operate entirely against local state. Because the kubernetes backend stores state on the cluster the teardown is about to destroy, this pulls every component's state to local up front — while the cluster still hosts the backend — and pivots terraform.backend.type to local for the rest of the process. From that point the destroy plan and every component destroy read local state, never dialing a backend that is going away, so "the cluster is gone" can no longer strand the teardown. The pivot is unconditional for a kubernetes backend; reachability is consulted only to classify a migration failure: while the cluster is still reachable a failure is real — destroying now would run against empty local state and orphan resources, so it aborts — but once the cluster is gone (a resumed teardown) the state was already migrated on the earlier pass and is the local copy, so it proceeds against it. Returns whether it pivoted; a non-kubernetes backend is a no-op.
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. With no backend tier it forwards to DestroyAll (or DestroyAllTerraform when terraformOnly). With a tier declared via Blueprint.Backend, Stage 1 destroys non-tier components against the configured backend, then Stage 2 pins local, pulls every tier member's state to local, and destroys the tier in reverse declaration order. When continueOnError is true, per-component destroy errors in Stage 1 are collected rather than aborting the loop; the backend tier is only attempted when Stage 1 produced zero failures, to avoid destroying the state store while other components still depend on it. The tier-deferred flag on the result signals when Stage 2 was skipped for this reason. Stage 2's tier destroy skips the Kubernetes-reachability preflight: Stage 1 has, by design, already destroyed the cluster (it is never a tier member), so an unreachable API at this point is the expected state, not a broken-auth signal, and the backend tier never has a kubernetes/helm provider dependency for the check to protect.
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-tier member 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.
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. It runs Terraform apply when terraform.enabled and the stack exists, invoking the given onApply hooks after each component apply (after any hooks registered via OnTerraformApply). The blueprint parameter is required.
Returns (halted bool, err error). halted=true means a hook signaled a clean stop after a component apply — the apply succeeded, but subsequent components were intentionally skipped. err remains the path for real failures.
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: sends the upgrade gRPC request (wait=false), waits for the node to go offline via version polling (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) 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.