github.com/opentofu/opentofu@v1.7.1/internal/tofu/eval_import.go (about)

     1  // Copyright (c) The OpenTofu Authors
     2  // SPDX-License-Identifier: MPL-2.0
     3  // Copyright (c) 2023 HashiCorp, Inc.
     4  // SPDX-License-Identifier: MPL-2.0
     5  
     6  package tofu
     7  
     8  import (
     9  	"fmt"
    10  
    11  	"github.com/hashicorp/hcl/v2"
    12  	"github.com/opentofu/opentofu/internal/instances"
    13  	"github.com/opentofu/opentofu/internal/lang/marks"
    14  	"github.com/opentofu/opentofu/internal/tfdiags"
    15  	"github.com/zclconf/go-cty/cty"
    16  	"github.com/zclconf/go-cty/cty/gocty"
    17  )
    18  
    19  func evaluateImportIdExpression(expr hcl.Expression, ctx EvalContext, keyData instances.RepetitionData) (string, tfdiags.Diagnostics) {
    20  	var diags tfdiags.Diagnostics
    21  
    22  	if expr == nil {
    23  		return "", diags.Append(&hcl.Diagnostic{
    24  			Severity: hcl.DiagError,
    25  			Summary:  "Invalid import id argument",
    26  			Detail:   "The import ID cannot be null.",
    27  			Subject:  nil,
    28  		})
    29  	}
    30  
    31  	// evaluate the import ID and take into consideration the for_each key (if exists)
    32  	importIdVal, evalDiags := evaluateExprWithRepetitionData(ctx, expr, cty.String, keyData)
    33  	diags = diags.Append(evalDiags)
    34  
    35  	if importIdVal.IsNull() {
    36  		return "", diags.Append(&hcl.Diagnostic{
    37  			Severity: hcl.DiagError,
    38  			Summary:  "Invalid import id argument",
    39  			Detail:   "The import ID cannot be null.",
    40  			Subject:  expr.Range().Ptr(),
    41  		})
    42  	}
    43  
    44  	if !importIdVal.IsKnown() {
    45  		return "", diags.Append(&hcl.Diagnostic{
    46  			Severity: hcl.DiagError,
    47  			Summary:  "Invalid import id argument",
    48  			Detail:   `The import block "id" argument depends on resource attributes that cannot be determined until apply, so OpenTofu cannot plan to import this resource.`, // FIXME and what should I do about that?
    49  			Subject:  expr.Range().Ptr(),
    50  			//	Expression:
    51  			//	EvalContext:
    52  			Extra: diagnosticCausedByUnknown(true),
    53  		})
    54  	}
    55  
    56  	if importIdVal.HasMark(marks.Sensitive) {
    57  		return "", diags.Append(&hcl.Diagnostic{
    58  			Severity: hcl.DiagError,
    59  			Summary:  "Invalid import id argument",
    60  			Detail:   "The import ID cannot be sensitive.",
    61  			Subject:  expr.Range().Ptr(),
    62  		})
    63  	}
    64  
    65  	var importId string
    66  	err := gocty.FromCtyValue(importIdVal, &importId)
    67  	if err != nil {
    68  		return "", diags.Append(&hcl.Diagnostic{
    69  			Severity: hcl.DiagError,
    70  			Summary:  "Invalid import id argument",
    71  			Detail:   fmt.Sprintf("The import ID value is unsuitable: %s.", err),
    72  			Subject:  expr.Range().Ptr(),
    73  		})
    74  	}
    75  
    76  	return importId, diags
    77  }
    78  
    79  // evaluateExprWithRepetitionData takes the given HCL expression and evaluates
    80  // it to produce a value, while taking into consideration any repetition key
    81  // (a single combination of each.key and each.value of a for_each argument)
    82  // that should be a part of the scope.
    83  func evaluateExprWithRepetitionData(ctx EvalContext, expr hcl.Expression, wantType cty.Type, keyData instances.RepetitionData) (cty.Value, tfdiags.Diagnostics) {
    84  	scope := ctx.EvaluationScope(nil, nil, keyData)
    85  	return scope.EvalExpr(expr, wantType)
    86  }