// Copyright (c) The OpenTofu Authors // SPDX-License-Identifier: MPL-2.0 // Copyright (c) 2023 HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 package external import ( "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/gohcl" "github.com/hashicorp/hcl/v2/hclsyntax" "github.com/opentofu/opentofu/internal/encryption/keyprovider" "github.com/opentofu/opentofu/internal/encryption/method" ) // New creates a new descriptor for the AES-GCM encryption method, which requires a 32-byte key. func New() method.Descriptor { return &descriptor{} } type descriptor struct { } func (d *descriptor) ID() method.ID { return "external" } func (d *descriptor) DecodeConfig(methodCtx method.EvalContext, body hcl.Body) (method.Config, hcl.Diagnostics) { var diags hcl.Diagnostics methodCfg := &Config{} content, contentDiags := body.Content(&hcl.BodySchema{ Attributes: []hcl.AttributeSchema{ {Name: "keys", Required: false}, {Name: "encrypt_command", Required: true}, {Name: "decrypt_command", Required: true}, }, }) diags = diags.Extend(contentDiags) if diags.HasErrors() { return nil, diags } if keyAttr, ok := content.Attributes["keys"]; ok { keyExpr := keyAttr.Expr // keyExpr can either be raw data/references to raw data or a string reference to a key provider (JSON support) keyVal, keyDiags := methodCtx.ValueForExpression(keyExpr) diags = diags.Extend(keyDiags) if diags.HasErrors() { return nil, diags } keys, decodeDiags := keyprovider.DecodeOutput(keyVal, keyExpr.Range()) diags = diags.Extend(decodeDiags) if diags.HasErrors() { return nil, diags } methodCfg.Keys = &keys } encryptAttr := content.Attributes["encrypt_command"] encryptVal, valueDiags := methodCtx.ValueForExpression(encryptAttr.Expr) diags = diags.Extend(valueDiags) if diags.HasErrors() { return nil, diags } decodeEncryptCmdDiags := gohcl.DecodeExpression(&hclsyntax.LiteralValueExpr{Val: encryptVal, SrcRange: encryptAttr.Expr.Range()}, nil, &methodCfg.EncryptCommand) diags = diags.Extend(decodeEncryptCmdDiags) if diags.HasErrors() { return nil, diags } decryptAttr := content.Attributes["decrypt_command"] decryptVal, valueDiags := methodCtx.ValueForExpression(decryptAttr.Expr) diags = diags.Extend(valueDiags) if diags.HasErrors() { return nil, diags } decodeDecryptCmdDiags := gohcl.DecodeExpression(&hclsyntax.LiteralValueExpr{Val: decryptVal, SrcRange: decryptAttr.Expr.Range()}, nil, &methodCfg.DecryptCommand) diags = diags.Extend(decodeDecryptCmdDiags) return methodCfg, diags }