refactoring

package
v1.6.0-alpha5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 14, 2023 License: MPL-2.0 Imports: 12 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ValidateMoves

func ValidateMoves(stmts []MoveStatement, rootCfg *configs.Config, declaredInsts instances.Set) tfdiags.Diagnostics

ValidateMoves tests whether all of the given move statements comply with both the single-statement validation rules and the "big picture" rules that constrain statements in relation to one another.

The validation rules are primarily in terms of the configuration, but ValidateMoves also takes the expander that resulted from creating a plan so that it can see which instances are defined for each module and resource, to precisely validate move statements involving specific-instance addresses.

Because validation depends on the planning result but move execution must happen _before_ planning, we have the unusual situation where sibling function ApplyMoves must run before ValidateMoves and must therefore tolerate and ignore any invalid statements. The plan walk will then construct in incorrect plan (because it'll be starting from the wrong prior state) but ValidateMoves will block actually showing that invalid plan to the user.

Types

type MoveBlocked

type MoveBlocked struct {
	Wanted addrs.AbsMoveable
	Actual addrs.AbsMoveable
}

type MoveResults

type MoveResults struct {
	// Changes is a map from the unique keys of the final new resource
	// instance addresses to an object describing what changed.
	//
	// This includes one entry for each resource instance address that was
	// the destination of a move statement. It doesn't include resource
	// instances that were not affected by moves at all, but it does include
	// resource instance addresses that were "blocked" (also recorded in
	// BlockedAddrs) if and only if they were able to move at least
	// partially along a chain before being blocked.
	//
	// In the return value from ApplyMoves, all of the keys are guaranteed to
	// be unique keys derived from addrs.AbsResourceInstance values.
	Changes addrs.Map[addrs.AbsResourceInstance, MoveSuccess]

	// Blocked is a map from the unique keys of the final new
	// resource instances addresses to information about where they "wanted"
	// to move, but were blocked by a pre-existing object at the same address.
	//
	// "Blocking" can arise in unusual situations where multiple points along
	// a move chain were already bound to objects, and thus only one of them
	// can actually adopt the final position in the chain. It can also
	// occur in other similar situations, such as if a configuration contains
	// a move of an entire module and a move of an individual resource into
	// that module, such that the individual resource would collide with a
	// resource in the whole module that was moved.
	//
	// In the return value from ApplyMoves, all of the keys are guaranteed to
	// be unique keys derived from values of addrs.AbsMoveable types.
	Blocked addrs.Map[addrs.AbsMoveable, MoveBlocked]
}

MoveResults describes the outcome of an ApplyMoves call.

func ApplyMoves

func ApplyMoves(stmts []MoveStatement, state *states.State) MoveResults

ApplyMoves modifies in-place the given state object so that any existing objects that are matched by a "from" argument of one of the move statements will be moved to instead appear at the "to" argument of that statement.

The result is a map from the unique key of each absolute address that was either the source or destination of a move to a MoveResult describing what happened at that address.

ApplyMoves does not have any error situations itself, and will instead just ignore any unresolvable move statements. Validation of a set of moves is a separate concern applied to the configuration, because validity of moves is always dependent only on the configuration, not on the state.

ApplyMoves expects exclusive access to the given state while it's running. Don't read or write any part of the state structure until ApplyMoves returns.

func (MoveResults) AddrMoved

func (rs MoveResults) AddrMoved(newAddr addrs.AbsResourceInstance) bool

AddrMoved returns true if and only if the given resource instance moved to a new address in the ApplyMoves call that the receiver is describing.

If AddrMoved returns true, you can pass the same address to method OldAddr to find its original address prior to moving.

func (MoveResults) OldAddr

OldAddr returns the old address of the given resource instance address, or just returns back the same address if the given instance wasn't affected by any move statements.

type MoveStatement

type MoveStatement struct {
	From, To  *addrs.MoveEndpointInModule
	DeclRange tfdiags.SourceRange

	// Implied is true for statements produced by ImpliedMoveStatements, and
	// false for statements produced by FindMoveStatements.
	//
	// An "implied" statement is one that has no explicit "moved" block in
	// the configuration and was instead generated automatically based on a
	// comparison between current configuration and previous run state.
	// For implied statements, the DeclRange field contains the source location
	// of something in the source code that implied the statement, in which
	// case it would probably be confusing to show that source range to the
	// user, e.g. in an error message, without clearly mentioning that it's
	// related to an implied move statement.
	Implied bool
}

func FindMoveStatements

func FindMoveStatements(rootCfg *configs.Config) []MoveStatement

FindMoveStatements recurses through the modules of the given configuration and returns a flat set of all "moved" blocks defined within, in a deterministic but undefined order.

func ImpliedMoveStatements

func ImpliedMoveStatements(rootCfg *configs.Config, prevRunState *states.State, explicitStmts []MoveStatement) []MoveStatement

ImpliedMoveStatements compares addresses in the given state with addresses in the given configuration and potentially returns additional MoveStatement objects representing moves we infer automatically, even though they aren't explicitly recorded in the configuration.

We do this primarily for backward compatibility with behaviors of Terraform versions prior to introducing explicit "moved" blocks. Specifically, this function aims to achieve the same result as the "NodeCountBoundary" heuristic from Terraform v1.0 and earlier, where adding or removing the "count" meta-argument from an already-created resource can automatically preserve the zeroth or the NoKey instance, depending on the direction of the change. We do this only for resources that aren't mentioned already in at least one explicit move statement.

As with the previous-version heuristics it replaces, this is a best effort and doesn't handle all situations. An explicit move statement is always preferred, but our goal here is to match exactly the same cases that the old heuristic would've matched, to retain compatibility for existing modules.

We should think very hard before adding any _new_ implication rules for moved statements.

func (*MoveStatement) Name

func (s *MoveStatement) Name() string

Name is used internally for displaying the statement graph

func (*MoveStatement) ObjectKind

func (s *MoveStatement) ObjectKind() addrs.MoveEndpointKind

type MoveSuccess

type MoveSuccess struct {
	From addrs.AbsResourceInstance
	To   addrs.AbsResourceInstance
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL