terraform/internal/configs/moved.go

73 lines
1.8 KiB
Go

package configs
import (
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/terraform/internal/addrs"
)
type Moved struct {
From *addrs.MoveEndpoint
To *addrs.MoveEndpoint
DeclRange hcl.Range
}
func decodeMovedBlock(block *hcl.Block) (*Moved, hcl.Diagnostics) {
var diags hcl.Diagnostics
moved := &Moved{
DeclRange: block.DefRange,
}
content, moreDiags := block.Body.Content(movedBlockSchema)
diags = append(diags, moreDiags...)
if attr, exists := content.Attributes["from"]; exists {
from, traversalDiags := hcl.AbsTraversalForExpr(attr.Expr)
diags = append(diags, traversalDiags...)
if !traversalDiags.HasErrors() {
from, fromDiags := addrs.ParseMoveEndpoint(from)
diags = append(diags, fromDiags.ToHCL()...)
moved.From = from
}
}
if attr, exists := content.Attributes["to"]; exists {
to, traversalDiags := hcl.AbsTraversalForExpr(attr.Expr)
diags = append(diags, traversalDiags...)
if !traversalDiags.HasErrors() {
to, toDiags := addrs.ParseMoveEndpoint(to)
diags = append(diags, toDiags.ToHCL()...)
moved.To = to
}
}
// we can only move from a module to a module, resource to resource, etc.
if !diags.HasErrors() {
if !moved.From.MightUnifyWith(moved.To) {
// We can catch some obviously-wrong combinations early here,
// but we still have other dynamic validation to do at runtime.
diags = diags.Append(&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid \"moved\" addresses",
Detail: "The \"from\" and \"to\" addresses must either both refer to resources or both refer to modules.",
Subject: &moved.DeclRange,
})
}
}
return moved, diags
}
var movedBlockSchema = &hcl.BodySchema{
Attributes: []hcl.AttributeSchema{
{
Name: "from",
Required: true,
},
{
Name: "to",
Required: true,
},
},
}