mirror of
https://github.com/hashicorp/terraform.git
synced 2026-02-19 02:39:17 -05:00
115 lines
3.5 KiB
Go
115 lines
3.5 KiB
Go
// Copyright IBM Corp. 2014, 2026
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package stackconfig
|
|
|
|
import (
|
|
"github.com/hashicorp/hcl/v2"
|
|
"github.com/hashicorp/hcl/v2/gohcl"
|
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
|
"github.com/hashicorp/terraform/internal/stacks/stackconfig/typeexpr"
|
|
"github.com/hashicorp/terraform/internal/tfdiags"
|
|
"github.com/zclconf/go-cty/cty"
|
|
)
|
|
|
|
// InputVariable is a declaration of an input variable within a stack
|
|
// configuration. Callers must provide the values for these variables.
|
|
type InputVariable struct {
|
|
Name string
|
|
|
|
Type TypeConstraint
|
|
DefaultValue cty.Value
|
|
Description string
|
|
|
|
Sensitive bool
|
|
Ephemeral bool
|
|
|
|
DeclRange tfdiags.SourceRange
|
|
}
|
|
|
|
// TypeConstraint represents all of the type constraint information for either
|
|
// an input variable or an output value.
|
|
//
|
|
// After initial decoding only Expression is populated, and it has not yet been
|
|
// analyzed at all so is not even guaranteed to be a valid type constraint
|
|
// expression.
|
|
//
|
|
// For configurations loaded through the main entry point [LoadConfigDir],
|
|
// Constraint is populated with the result of decoding Expression as a type
|
|
// constraint only if the expression is a valid type constraint expression.
|
|
// When loading through shallower entry points such as [DecodeFileBody],
|
|
// Constraint is not populated.
|
|
//
|
|
// Defaults is populated only if Constraint is, and if not nil represents any
|
|
// default values from the type constraint expression.
|
|
type TypeConstraint struct {
|
|
Expression hcl.Expression
|
|
Constraint cty.Type
|
|
Defaults *typeexpr.Defaults
|
|
}
|
|
|
|
func decodeInputVariableBlock(block *hcl.Block) (*InputVariable, tfdiags.Diagnostics) {
|
|
var diags tfdiags.Diagnostics
|
|
ret := &InputVariable{
|
|
Name: block.Labels[0],
|
|
DeclRange: tfdiags.SourceRangeFromHCL(block.DefRange),
|
|
}
|
|
if !hclsyntax.ValidIdentifier(ret.Name) {
|
|
diags = diags.Append(invalidNameDiagnostic(
|
|
"Invalid name for input variable",
|
|
block.LabelRanges[0],
|
|
))
|
|
return nil, diags
|
|
}
|
|
|
|
content, hclDiags := block.Body.Content(inputVariableBlockSchema)
|
|
diags = diags.Append(hclDiags)
|
|
|
|
if attr, ok := content.Attributes["type"]; ok {
|
|
ret.Type.Expression = attr.Expr
|
|
}
|
|
if attr, ok := content.Attributes["default"]; ok {
|
|
val, hclDiags := attr.Expr.Value(nil)
|
|
diags = diags.Append(hclDiags)
|
|
if val == cty.NilVal {
|
|
val = cty.DynamicVal
|
|
}
|
|
ret.DefaultValue = val
|
|
}
|
|
if attr, ok := content.Attributes["description"]; ok {
|
|
hclDiags := gohcl.DecodeExpression(attr.Expr, nil, &ret.Description)
|
|
diags = diags.Append(hclDiags)
|
|
}
|
|
if attr, ok := content.Attributes["sensitive"]; ok {
|
|
hclDiags := gohcl.DecodeExpression(attr.Expr, nil, &ret.Sensitive)
|
|
diags = diags.Append(hclDiags)
|
|
}
|
|
if attr, ok := content.Attributes["ephemeral"]; ok {
|
|
hclDiags := gohcl.DecodeExpression(attr.Expr, nil, &ret.Ephemeral)
|
|
diags = diags.Append(hclDiags)
|
|
}
|
|
|
|
for _, block := range content.Blocks {
|
|
diags = diags.Append(&hcl.Diagnostic{
|
|
Severity: hcl.DiagError,
|
|
Summary: "Custom variable validation not yet supported",
|
|
Detail: "Input variables for a stack configuration do not yet support custom variable validation.",
|
|
Subject: block.DefRange.Ptr(),
|
|
})
|
|
}
|
|
|
|
return ret, diags
|
|
}
|
|
|
|
var inputVariableBlockSchema = &hcl.BodySchema{
|
|
Attributes: []hcl.AttributeSchema{
|
|
{Name: "type", Required: true},
|
|
{Name: "default", Required: false},
|
|
{Name: "description", Required: false},
|
|
{Name: "sensitive", Required: false},
|
|
{Name: "ephemeral", Required: false},
|
|
},
|
|
Blocks: []hcl.BlockHeaderSchema{
|
|
{Type: "validation"},
|
|
},
|
|
}
|