mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-24 08:00:17 -06:00
0d1e6cd5f0
Signed-off-by: Christian Mesh <christianmesh1@gmail.com>
110 lines
3.6 KiB
Go
110 lines
3.6 KiB
Go
// Copyright (c) The OpenTofu Authors
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
// Copyright (c) 2023 HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package configs
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/hashicorp/hcl/v2"
|
|
"github.com/hashicorp/hcl/v2/hcldec"
|
|
"github.com/opentofu/opentofu/internal/addrs"
|
|
"github.com/opentofu/opentofu/internal/configs/configschema"
|
|
"github.com/opentofu/opentofu/internal/lang"
|
|
"github.com/opentofu/opentofu/internal/lang/marks"
|
|
"github.com/zclconf/go-cty/cty"
|
|
)
|
|
|
|
// Backend represents a "backend" block inside a "terraform" block in a module
|
|
// or file.
|
|
type Backend struct {
|
|
Type string
|
|
Config hcl.Body
|
|
Eval *StaticEvaluator
|
|
|
|
TypeRange hcl.Range
|
|
DeclRange hcl.Range
|
|
}
|
|
|
|
func decodeBackendBlock(block *hcl.Block) (*Backend, hcl.Diagnostics) {
|
|
return &Backend{
|
|
Type: block.Labels[0],
|
|
TypeRange: block.LabelRanges[0],
|
|
Config: block.Body,
|
|
DeclRange: block.DefRange,
|
|
}, nil
|
|
}
|
|
|
|
// Hash produces a hash value for the receiver that covers the type and the
|
|
// portions of the config that conform to the given schema.
|
|
//
|
|
// If the config does not conform to the schema then the result is not
|
|
// meaningful for comparison since it will be based on an incomplete result.
|
|
//
|
|
// As an exception, required attributes in the schema are treated as optional
|
|
// for the purpose of hashing, so that an incomplete configuration can still
|
|
// be hashed. Other errors, such as extraneous attributes, have no such special
|
|
// case.
|
|
func (b *Backend) Hash(schema *configschema.Block) (int, hcl.Diagnostics) {
|
|
// Don't fail if required attributes are not set. Instead, we'll just
|
|
// hash them as nulls.
|
|
schema = schema.NoneRequired()
|
|
|
|
// This is a bit of an odd workaround, but the decode below intentionally ignores
|
|
// errors. I don't want to try to change that at this point, but it may be worth doing
|
|
// at some point. For now, I'm just looking to see if there are any references that are
|
|
// not valid that the user should look at, instead of just producing an invalid backend object.
|
|
diags := b.referenceDiagnostics(schema)
|
|
|
|
val, _ := b.Decode(schema)
|
|
if val == cty.NilVal {
|
|
val = cty.UnknownVal(schema.ImpliedType())
|
|
}
|
|
|
|
if marks.Contains(val, marks.Sensitive) {
|
|
return -1, diags.Append(&hcl.Diagnostic{
|
|
Severity: hcl.DiagError,
|
|
Summary: "Backend config contains sensitive values",
|
|
Detail: "The backend configuration is stored in .terraform/terraform.tfstate as well as plan files. It is recommended to instead supply sensitive credentials via backend specific environment variables",
|
|
Subject: b.DeclRange.Ptr(),
|
|
})
|
|
}
|
|
|
|
toHash := cty.TupleVal([]cty.Value{
|
|
cty.StringVal(b.Type),
|
|
val,
|
|
})
|
|
|
|
return toHash.Hash(), diags
|
|
}
|
|
|
|
func (b *Backend) Decode(schema *configschema.Block) (cty.Value, hcl.Diagnostics) {
|
|
return b.Eval.DecodeBlock(b.Config, schema.DecoderSpec(), StaticIdentifier{
|
|
Module: addrs.RootModule,
|
|
Subject: fmt.Sprintf("backend.%s", b.Type),
|
|
DeclRange: b.DeclRange,
|
|
})
|
|
}
|
|
|
|
// This is a hack that may not be needed, but preserves the idea that invalid backends will show a cryptic error about running init during plan/apply startup.
|
|
func (b *Backend) referenceDiagnostics(schema *configschema.Block) hcl.Diagnostics {
|
|
var diags hcl.Diagnostics
|
|
|
|
refs, refsDiags := lang.References(addrs.ParseRef, hcldec.Variables(b.Config, schema.DecoderSpec()))
|
|
diags = append(diags, refsDiags.ToHCL()...)
|
|
if diags.HasErrors() {
|
|
return diags
|
|
}
|
|
|
|
_, ctxDiags := b.Eval.scope(StaticIdentifier{
|
|
Module: addrs.RootModule,
|
|
Subject: fmt.Sprintf("backend.%s", b.Type),
|
|
DeclRange: b.DeclRange,
|
|
}).EvalContext(refs)
|
|
diags = append(diags, ctxDiags.ToHCL()...)
|
|
|
|
return diags
|
|
}
|