prototype: enabled for import

Signed-off-by: Diogenes Fernandes <diofeher@gmail.com>
This commit is contained in:
Diogenes Fernandes
2025-11-27 17:00:29 -03:00
parent a89667e29c
commit 5eb8b6cbac
2 changed files with 101 additions and 0 deletions

View File

@@ -47,6 +47,10 @@ type Import struct {
ForEach hcl.Expression
// Enabled is the expression for the lifecycle.enabled meta-argument.
// If nil, the import is enabled by default.
Enabled hcl.Expression
ProviderConfigRef *ProviderConfigRef
Provider addrs.Provider
@@ -118,6 +122,62 @@ func decodeImportBlock(block *hcl.Block) (*Import, hcl.Diagnostics) {
imp.ForEach = attr.Expr
}
// Handle lifecycle block
var seenLifecycle *hcl.Block
for _, block := range content.Blocks {
if block.Type == "lifecycle" {
if seenLifecycle != nil {
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Duplicate lifecycle block",
Detail: "Only one lifecycle block is allowed per import block.",
Subject: &block.DefRange,
})
continue
}
seenLifecycle = block
lcContent, lcDiags := block.Body.Content(importLifecycleBlockSchema)
diags = append(diags, lcDiags...)
if attr, exists := lcContent.Attributes["enabled"]; exists {
imp.Enabled = attr.Expr
}
// Check for other lifecycle attributes that are not valid for import blocks
for name, attr := range lcContent.Attributes {
if name != "enabled" {
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid import lifecycle argument",
Detail: "The lifecycle argument \"" + name + "\" is not valid for import blocks. Only \"enabled\" is supported.",
Subject: attr.NameRange.Ptr(),
})
}
}
// Import blocks don't support lifecycle preconditions/postconditions
for _, block := range lcContent.Blocks {
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid lifecycle block",
Detail: "Import blocks do not support \"" + block.Type + "\" blocks within lifecycle.",
Subject: block.DefRange.Ptr(),
})
}
}
}
// Validate that enabled and for_each are not both specified
if imp.Enabled != nil && imp.ForEach != nil {
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid combination of lifecycle.enabled and for_each",
Detail: "The lifecycle.enabled and for_each meta-arguments cannot be used together in the same import block. Use lifecycle.enabled for single-instance imports or for_each for multiple instances.",
Subject: &block.DefRange,
})
}
return imp, diags
}
@@ -138,6 +198,19 @@ var importBlockSchema = &hcl.BodySchema{
Name: "for_each",
},
},
Blocks: []hcl.BlockHeaderSchema{
{Type: "lifecycle"},
},
}
var importLifecycleBlockSchema = &hcl.BodySchema{
// We tell HCL that these elements are valid but we'll validate
// after decoding to return more specific error messages.
Attributes: []hcl.AttributeSchema{
{
Name: "enabled",
},
},
}
// absTraversalForImportToExpr returns a static traversal of an import block's "to" field.

View File

@@ -120,6 +120,20 @@ func (ri *ImportResolver) ValidateImportIDs(ctx context.Context, importTarget *I
// relative to the root module
rootCtx := evalCtx.WithPath(addrs.RootModuleInstance)
// Check if the import is enabled via lifecycle.enabled
if importTarget.Config.Enabled != nil {
enabled, enabledDiags := evaluateEnabledExpression(ctx, importTarget.Config.Enabled, rootCtx)
diags = diags.Append(enabledDiags)
if diags.HasErrors() {
return diags
}
// If the import is disabled, skip validation
if !enabled {
return diags
}
}
if importTarget.Config.ForEach != nil {
const unknownsNotAllowed = false
const tupleAllowed = true
@@ -170,6 +184,20 @@ func (ri *ImportResolver) ExpandAndResolveImport(ctx context.Context, importTarg
// relative to the root module
rootCtx := evalCtx.WithPath(addrs.RootModuleInstance)
// Check if the import is enabled via lifecycle.enabled
if importTarget.Config.Enabled != nil {
enabled, enabledDiags := evaluateEnabledExpression(ctx, importTarget.Config.Enabled, rootCtx)
diags = diags.Append(enabledDiags)
if diags.HasErrors() {
return diags
}
// If the import is disabled, skip it entirely
if !enabled {
return diags
}
}
if importTarget.Config.ForEach != nil {
const unknownsNotAllowed = false
const tupleAllowed = true