mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-28 01:41:48 -06:00
0681935df5
We want the forthcoming v0.12.0 release to be the last significant breaking change to our main configuration constructs for a long time, but not everything could be implemented in that release. As a compromise then, we reserve various names we have some intent of using in a future release so that such future uses will not be a further breaking change later. Some of these names are associated with specific short-term plans, while others are reserved conservatively for possible later work and may be "un-reserved" in a later release if we don't end up using them. The ones that we expect to use in the near future were already being handled, so we'll continue to decode them at the config layer but also produce an error so that we don't get weird behavior downstream where the corresponding features don't work yet.
151 lines
3.9 KiB
Go
151 lines
3.9 KiB
Go
package configs
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/hashicorp/hcl2/hcl"
|
|
)
|
|
|
|
// Provisioner represents a "provisioner" block when used within a
|
|
// "resource" block in a module or file.
|
|
type Provisioner struct {
|
|
Type string
|
|
Config hcl.Body
|
|
Connection *Connection
|
|
When ProvisionerWhen
|
|
OnFailure ProvisionerOnFailure
|
|
|
|
DeclRange hcl.Range
|
|
TypeRange hcl.Range
|
|
}
|
|
|
|
func decodeProvisionerBlock(block *hcl.Block) (*Provisioner, hcl.Diagnostics) {
|
|
pv := &Provisioner{
|
|
Type: block.Labels[0],
|
|
TypeRange: block.LabelRanges[0],
|
|
DeclRange: block.DefRange,
|
|
When: ProvisionerWhenCreate,
|
|
OnFailure: ProvisionerOnFailureFail,
|
|
}
|
|
|
|
content, config, diags := block.Body.PartialContent(provisionerBlockSchema)
|
|
pv.Config = config
|
|
|
|
if attr, exists := content.Attributes["when"]; exists {
|
|
expr, shimDiags := shimTraversalInString(attr.Expr, true)
|
|
diags = append(diags, shimDiags...)
|
|
|
|
switch hcl.ExprAsKeyword(expr) {
|
|
case "create":
|
|
pv.When = ProvisionerWhenCreate
|
|
case "destroy":
|
|
pv.When = ProvisionerWhenDestroy
|
|
default:
|
|
diags = append(diags, &hcl.Diagnostic{
|
|
Severity: hcl.DiagError,
|
|
Summary: "Invalid \"when\" keyword",
|
|
Detail: "The \"when\" argument requires one of the following keywords: create or destroy.",
|
|
Subject: expr.Range().Ptr(),
|
|
})
|
|
}
|
|
}
|
|
|
|
if attr, exists := content.Attributes["on_failure"]; exists {
|
|
expr, shimDiags := shimTraversalInString(attr.Expr, true)
|
|
diags = append(diags, shimDiags...)
|
|
|
|
switch hcl.ExprAsKeyword(expr) {
|
|
case "continue":
|
|
pv.OnFailure = ProvisionerOnFailureContinue
|
|
case "fail":
|
|
pv.OnFailure = ProvisionerOnFailureFail
|
|
default:
|
|
diags = append(diags, &hcl.Diagnostic{
|
|
Severity: hcl.DiagError,
|
|
Summary: "Invalid \"on_failure\" keyword",
|
|
Detail: "The \"on_failure\" argument requires one of the following keywords: continue or fail.",
|
|
Subject: attr.Expr.Range().Ptr(),
|
|
})
|
|
}
|
|
}
|
|
|
|
var seenConnection *hcl.Block
|
|
for _, block := range content.Blocks {
|
|
switch block.Type {
|
|
|
|
case "connection":
|
|
if seenConnection != nil {
|
|
diags = append(diags, &hcl.Diagnostic{
|
|
Severity: hcl.DiagError,
|
|
Summary: "Duplicate connection block",
|
|
Detail: fmt.Sprintf("This provisioner already has a connection block at %s.", seenConnection.DefRange),
|
|
Subject: &block.DefRange,
|
|
})
|
|
continue
|
|
}
|
|
seenConnection = block
|
|
|
|
//conn, connDiags := decodeConnectionBlock(block)
|
|
//diags = append(diags, connDiags...)
|
|
pv.Connection = &Connection{
|
|
Config: block.Body,
|
|
DeclRange: block.DefRange,
|
|
}
|
|
|
|
default:
|
|
// Any other block types are ones we've reserved for future use,
|
|
// so they get a generic message.
|
|
diags = append(diags, &hcl.Diagnostic{
|
|
Severity: hcl.DiagError,
|
|
Summary: "Reserved block type name in provisioner block",
|
|
Detail: fmt.Sprintf("The block type name %q is reserved for use by Terraform in a future version.", block.Type),
|
|
Subject: &block.TypeRange,
|
|
})
|
|
}
|
|
}
|
|
|
|
return pv, diags
|
|
}
|
|
|
|
// Connection represents a "connection" block when used within either a
|
|
// "resource" or "provisioner" block in a module or file.
|
|
type Connection struct {
|
|
Config hcl.Body
|
|
|
|
DeclRange hcl.Range
|
|
}
|
|
|
|
// ProvisionerWhen is an enum for valid values for when to run provisioners.
|
|
type ProvisionerWhen int
|
|
|
|
//go:generate stringer -type ProvisionerWhen
|
|
|
|
const (
|
|
ProvisionerWhenInvalid ProvisionerWhen = iota
|
|
ProvisionerWhenCreate
|
|
ProvisionerWhenDestroy
|
|
)
|
|
|
|
// ProvisionerOnFailure is an enum for valid values for on_failure options
|
|
// for provisioners.
|
|
type ProvisionerOnFailure int
|
|
|
|
//go:generate stringer -type ProvisionerOnFailure
|
|
|
|
const (
|
|
ProvisionerOnFailureInvalid ProvisionerOnFailure = iota
|
|
ProvisionerOnFailureContinue
|
|
ProvisionerOnFailureFail
|
|
)
|
|
|
|
var provisionerBlockSchema = &hcl.BodySchema{
|
|
Attributes: []hcl.AttributeSchema{
|
|
{Name: "when"},
|
|
{Name: "on_failure"},
|
|
},
|
|
Blocks: []hcl.BlockHeaderSchema{
|
|
{Type: "connection"},
|
|
{Type: "lifecycle"}, // reserved for future use
|
|
},
|
|
}
|