| 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, |
| }, |
| }, |
| } |