-
Notifications
You must be signed in to change notification settings - Fork 9.4k
/
base.go
116 lines (101 loc) · 3.91 KB
/
base.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package backendbase
import (
"fmt"
"github.com/zclconf/go-cty/cty"
"github.com/hashicorp/terraform/internal/configs/configschema"
"github.com/hashicorp/terraform/internal/tfdiags"
)
// Base is a partial implementation of [backend.Backend] that can be embedded
// into another implementer to handle most of the configuration schema
// wrangling.
//
// Specifically it implements the ConfigSchema and PrepareConfig methods.
// Implementers embedding this base type must still implement all of the other
// Backend methods.
type Base struct {
// Schema is the schema for the backend configuration.
//
// This shares the same configuration schema model as used in provider
// schemas for resource types, etc, but only a subset of the model is
// actually meaningful for backends. In particular, it doesn't make sense
// to define "computed" attributes because objects conforming to the
// schema are only use for input based on the configuration, and can't
// export any data for use elsewhere in the configuration.
Schema *configschema.Block
// SDKLikeDefaults is an optional addition for backends that were built
// to rely heavily on the legacy SDK's support for default values, both
// hard-coded and taken from environment variables.
//
// If this is non-empty then any key specified here must match a
// primitive-typed toplevel attribute in Schema, and PrepareConfig will
// arrange for the default values to be inserted before it returns.
//
// As a special case, if the value in the configuration is unset (null),
// none of the environment variables are non-empty, and the fallback
// value is empty, then the attribute value will be left as null in the
// object returned by PrepareConfig. In all other situations an attribute
// specified here is definitely not null.
SDKLikeDefaults SDKLikeDefaults
}
// ConfigSchema returns the configuration schema for the backend.
func (b Base) ConfigSchema() *configschema.Block {
return b.Schema
}
// PrepareConfig coerces the given value to the backend's schema if possible,
// and emits deprecation warnings if any deprecated arguments have values
// assigned to them.
func (b Base) PrepareConfig(configVal cty.Value) (cty.Value, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
schema := b.Schema
v, err := schema.CoerceValue(configVal)
if err != nil {
var path cty.Path
if err, ok := err.(cty.PathError); ok {
path = err.Path
}
diags = diags.Append(tfdiags.AttributeValue(
tfdiags.Error,
"Invalid backend configuration",
fmt.Sprintf("The backend configuration is incorrect: %s.", tfdiags.FormatError(err)),
path,
))
return cty.DynamicVal, diags
}
cty.Walk(v, func(path cty.Path, v cty.Value) (bool, error) {
if v.IsNull() {
// Null values for deprecated arguments do not generate deprecation
// warnings, because that represents the argument not being set.
return false, nil
}
// If this path refers to a schema attribute then it might be
// deprecated, in which case we need to return a warning.
attr := schema.AttributeByPath(path)
if attr == nil {
return true, nil
}
if attr.Deprecated {
// The configschema model only has a boolean flag for whether the
// argument is deprecated or not, so this warning message is
// generic. Backends that want to return a custom message should
// leave this flag unset and instead implement a check inside
// their Configure method that returns a warning diagnostic.
diags = diags.Append(tfdiags.AttributeValue(
tfdiags.Warning,
"Deprecated provider argument",
fmt.Sprintf("The argument %s is deprecated. Refer to the backend documentation for more information.", tfdiags.FormatCtyPath(path)),
path,
))
}
return false, nil
})
if len(b.SDKLikeDefaults) != 0 {
var err error
v, err = b.SDKLikeDefaults.ApplyTo(v)
if err != nil {
diags = diags.Append(err)
}
}
return v, diags
}