Documentation
¶
Overview ¶
Package statemove validates declared Terraform resource moves against plan data and generates/maintains the native `moved {}` shim files that effect them (SP1: within one stack). It consumes tfplan.json — it does not run terraform.
Index ¶
- func Cleanup(root, key string) (int, error)
- func RenderShim(key string, ops []Op) string
- func RenderXMove(key string, xm XMove) string
- func ShimFileName(key string) string
- func ValidateMove(plan *tfjson.Plan, from, to string) error
- func XMoveFileName(key string) string
- type Action
- type Decision
- type ExecDeps
- type FoundXMove
- type Locker
- type Move
- type Op
- type Runner
- type Shim
- type XMove
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Cleanup ¶
Cleanup removes shim files matching key; an empty key removes ALL shims. Returns the number of files removed.
func RenderShim ¶
RenderShim renders a PR-keyed shim: a machine-readable header (banner, key, one tab-separated op line each) followed by the native Terraform blocks. The header is the source of truth for list/maintenance.
func RenderXMove ¶
RenderXMove renders the HCL manifest (key in a header comment + an xmove block).
func ShimFileName ¶
ShimFileName is the colocated shim filename for a key, e.g. "_tfsp_move.PR-123.tf".
func ValidateMove ¶
ValidateMove fail-closes unless the plan shows a clean relocation from→to: every resource being destroyed under `from` has a created counterpart under `to` at the rewritten address with the same type, and vice versa (no unmatched creates under `to`). Works for a single resource (exact match), a whole module (prefix), and count/for_each (bracketed) forms.
func XMoveFileName ¶
XMoveFileName is the manifest filename for a key.
Types ¶
type Action ¶
Action is what Execute did/would do for one pair.
func Execute ¶
func Execute(ctx context.Context, deps ExecDeps, root, destStack string, xm XMove, dryRun bool) ([]Action, error)
Execute performs one xmove (dest = root/destStack, source = root/xm.SourceStack): pull both states → backup → decide per pair → (unless dryRun) state mv the to-move pairs on local files and push both (never --force). Fail-closed: any error aborts before pushing.
type Decision ¶
type Decision int
Decision is the per-move runtime action derived from the two live states.
type ExecDeps ¶
type ExecDeps struct {
NewTF func(workingDir string) (Runner, error) // builds a Runner rooted at a stack dir
BackupDir string // pre-move state backups (empty disables)
Locker Locker // optional pessimistic lock around the move (nil = none)
}
ExecDeps injects the terraform factory + a backup dir.
type FoundXMove ¶
type FoundXMove struct {
Path string
DestStack string // dir relative to root (slash form)
Key string
XMove XMove
}
FoundXMove is a discovered manifest with its location.
func DiscoverXMoves ¶
func DiscoverXMoves(root string) ([]FoundXMove, error)
DiscoverXMoves walks root for `_tfsp_xmove.*.hcl` manifests.
type Locker ¶
type Locker interface {
Acquire(ctx context.Context, stackDir string) (release func() error, err error)
}
Locker is an optional pessimistic lock acquired before the pull→mv→push window so a concurrent terraform op on the same state fails to lock (rather than the move failing mid-flight). Acquire returns a release func; an error means the state is already locked and the move must NOT proceed.
type Move ¶
Move is one declared relocation, from one address to another (same stack in SP1). Addresses are opaque Terraform addresses (resource, module, or with count/for_each brackets).
func CrossStackPairs ¶
CrossStackPairs validates a cross-stack move and returns the matched from→to address pairs (fail-closed; same rules as ClassifyCrossStack minus the import id). Used by the `state mv` path, which is address-based and needs no id.
type Op ¶
Op is one operation in a shim file. Kind is "moved" (From→To, same state), "import" (To + ID, adopt into this state), or "removed" (From, drop from this state without destroying). Addresses/ids never contain a tab, so the header encodes ops tab-separated.
func ClassifyCrossStack ¶
ClassifyCrossStack validates a cross-stack move from `from` (in src's plan) to `to` (in dst's plan) and returns the ops to write: `removed` ops in the source shim and `import` ops (id from src's before.id) in the destination shim. Fail- closed: every resource destroyed under `from` must be created under `to` at the rewritten address with the same type and a usable import id, and every create under `to` must have a destroyed counterpart.
type Runner ¶
type Runner interface {
StatePull(ctx context.Context, opts ...tfexec.StatePullOption) (string, error)
StatePush(ctx context.Context, path string, opts ...tfexec.StatePushCmdOption) error
ShowStateFile(ctx context.Context, statePath string, opts ...tfexec.ShowOption) (*tfjson.State, error)
StateMv(ctx context.Context, source, destination string, opts ...tfexec.StateMvCmdOption) error
}
Runner is the subset of *tfexec.Terraform the executor needs (so tests can fake it without a binary).
func NewTerraform ¶
NewTerraform builds the real Runner for a stack dir.
type Shim ¶
type Shim struct {
Path string // path to the .tf
Stack string // dir containing it, relative to the discover root (slash form)
Key string
Ops []Op
}
Shim is a discovered shim file.