diff options
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/helper/schema/backend.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/helper/schema/backend.go | 138 |
1 files changed, 122 insertions, 16 deletions
diff --git a/vendor/github.com/hashicorp/terraform/helper/schema/backend.go b/vendor/github.com/hashicorp/terraform/helper/schema/backend.go index 57fbba7..c8d8ae2 100644 --- a/vendor/github.com/hashicorp/terraform/helper/schema/backend.go +++ b/vendor/github.com/hashicorp/terraform/helper/schema/backend.go | |||
@@ -2,8 +2,15 @@ package schema | |||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "context" | 4 | "context" |
5 | "fmt" | ||
5 | 6 | ||
7 | "github.com/hashicorp/terraform/tfdiags" | ||
8 | "github.com/zclconf/go-cty/cty" | ||
9 | |||
10 | "github.com/hashicorp/terraform/config/hcl2shim" | ||
11 | "github.com/hashicorp/terraform/configs/configschema" | ||
6 | "github.com/hashicorp/terraform/terraform" | 12 | "github.com/hashicorp/terraform/terraform" |
13 | ctyconvert "github.com/zclconf/go-cty/cty/convert" | ||
7 | ) | 14 | ) |
8 | 15 | ||
9 | // Backend represents a partial backend.Backend implementation and simplifies | 16 | // Backend represents a partial backend.Backend implementation and simplifies |
@@ -38,41 +45,123 @@ func FromContextBackendConfig(ctx context.Context) *ResourceData { | |||
38 | return ctx.Value(backendConfigKey).(*ResourceData) | 45 | return ctx.Value(backendConfigKey).(*ResourceData) |
39 | } | 46 | } |
40 | 47 | ||
41 | func (b *Backend) Input( | 48 | func (b *Backend) ConfigSchema() *configschema.Block { |
42 | input terraform.UIInput, | 49 | // This is an alias of CoreConfigSchema just to implement the |
43 | c *terraform.ResourceConfig) (*terraform.ResourceConfig, error) { | 50 | // backend.Backend interface. |
51 | return b.CoreConfigSchema() | ||
52 | } | ||
53 | |||
54 | func (b *Backend) PrepareConfig(configVal cty.Value) (cty.Value, tfdiags.Diagnostics) { | ||
44 | if b == nil { | 55 | if b == nil { |
45 | return c, nil | 56 | return configVal, nil |
46 | } | 57 | } |
58 | var diags tfdiags.Diagnostics | ||
59 | var err error | ||
47 | 60 | ||
48 | return schemaMap(b.Schema).Input(input, c) | 61 | // In order to use Transform below, this needs to be filled out completely |
49 | } | 62 | // according the schema. |
63 | configVal, err = b.CoreConfigSchema().CoerceValue(configVal) | ||
64 | if err != nil { | ||
65 | return configVal, diags.Append(err) | ||
66 | } | ||
50 | 67 | ||
51 | func (b *Backend) Validate(c *terraform.ResourceConfig) ([]string, []error) { | 68 | // lookup any required, top-level attributes that are Null, and see if we |
52 | if b == nil { | 69 | // have a Default value available. |
53 | return nil, nil | 70 | configVal, err = cty.Transform(configVal, func(path cty.Path, val cty.Value) (cty.Value, error) { |
71 | // we're only looking for top-level attributes | ||
72 | if len(path) != 1 { | ||
73 | return val, nil | ||
74 | } | ||
75 | |||
76 | // nothing to do if we already have a value | ||
77 | if !val.IsNull() { | ||
78 | return val, nil | ||
79 | } | ||
80 | |||
81 | // get the Schema definition for this attribute | ||
82 | getAttr, ok := path[0].(cty.GetAttrStep) | ||
83 | // these should all exist, but just ignore anything strange | ||
84 | if !ok { | ||
85 | return val, nil | ||
86 | } | ||
87 | |||
88 | attrSchema := b.Schema[getAttr.Name] | ||
89 | // continue to ignore anything that doesn't match | ||
90 | if attrSchema == nil { | ||
91 | return val, nil | ||
92 | } | ||
93 | |||
94 | // this is deprecated, so don't set it | ||
95 | if attrSchema.Deprecated != "" || attrSchema.Removed != "" { | ||
96 | return val, nil | ||
97 | } | ||
98 | |||
99 | // find a default value if it exists | ||
100 | def, err := attrSchema.DefaultValue() | ||
101 | if err != nil { | ||
102 | diags = diags.Append(fmt.Errorf("error getting default for %q: %s", getAttr.Name, err)) | ||
103 | return val, err | ||
104 | } | ||
105 | |||
106 | // no default | ||
107 | if def == nil { | ||
108 | return val, nil | ||
109 | } | ||
110 | |||
111 | // create a cty.Value and make sure it's the correct type | ||
112 | tmpVal := hcl2shim.HCL2ValueFromConfigValue(def) | ||
113 | |||
114 | // helper/schema used to allow setting "" to a bool | ||
115 | if val.Type() == cty.Bool && tmpVal.RawEquals(cty.StringVal("")) { | ||
116 | // return a warning about the conversion | ||
117 | diags = diags.Append("provider set empty string as default value for bool " + getAttr.Name) | ||
118 | tmpVal = cty.False | ||
119 | } | ||
120 | |||
121 | val, err = ctyconvert.Convert(tmpVal, val.Type()) | ||
122 | if err != nil { | ||
123 | diags = diags.Append(fmt.Errorf("error setting default for %q: %s", getAttr.Name, err)) | ||
124 | } | ||
125 | |||
126 | return val, err | ||
127 | }) | ||
128 | if err != nil { | ||
129 | // any error here was already added to the diagnostics | ||
130 | return configVal, diags | ||
54 | } | 131 | } |
55 | 132 | ||
56 | return schemaMap(b.Schema).Validate(c) | 133 | shimRC := b.shimConfig(configVal) |
134 | warns, errs := schemaMap(b.Schema).Validate(shimRC) | ||
135 | for _, warn := range warns { | ||
136 | diags = diags.Append(tfdiags.SimpleWarning(warn)) | ||
137 | } | ||
138 | for _, err := range errs { | ||
139 | diags = diags.Append(err) | ||
140 | } | ||
141 | return configVal, diags | ||
57 | } | 142 | } |
58 | 143 | ||
59 | func (b *Backend) Configure(c *terraform.ResourceConfig) error { | 144 | func (b *Backend) Configure(obj cty.Value) tfdiags.Diagnostics { |
60 | if b == nil { | 145 | if b == nil { |
61 | return nil | 146 | return nil |
62 | } | 147 | } |
63 | 148 | ||
149 | var diags tfdiags.Diagnostics | ||
64 | sm := schemaMap(b.Schema) | 150 | sm := schemaMap(b.Schema) |
151 | shimRC := b.shimConfig(obj) | ||
65 | 152 | ||
66 | // Get a ResourceData for this configuration. To do this, we actually | 153 | // Get a ResourceData for this configuration. To do this, we actually |
67 | // generate an intermediary "diff" although that is never exposed. | 154 | // generate an intermediary "diff" although that is never exposed. |
68 | diff, err := sm.Diff(nil, c, nil, nil) | 155 | diff, err := sm.Diff(nil, shimRC, nil, nil, true) |
69 | if err != nil { | 156 | if err != nil { |
70 | return err | 157 | diags = diags.Append(err) |
158 | return diags | ||
71 | } | 159 | } |
72 | 160 | ||
73 | data, err := sm.Data(nil, diff) | 161 | data, err := sm.Data(nil, diff) |
74 | if err != nil { | 162 | if err != nil { |
75 | return err | 163 | diags = diags.Append(err) |
164 | return diags | ||
76 | } | 165 | } |
77 | b.config = data | 166 | b.config = data |
78 | 167 | ||
@@ -80,11 +169,28 @@ func (b *Backend) Configure(c *terraform.ResourceConfig) error { | |||
80 | err = b.ConfigureFunc(context.WithValue( | 169 | err = b.ConfigureFunc(context.WithValue( |
81 | context.Background(), backendConfigKey, data)) | 170 | context.Background(), backendConfigKey, data)) |
82 | if err != nil { | 171 | if err != nil { |
83 | return err | 172 | diags = diags.Append(err) |
173 | return diags | ||
84 | } | 174 | } |
85 | } | 175 | } |
86 | 176 | ||
87 | return nil | 177 | return diags |
178 | } | ||
179 | |||
180 | // shimConfig turns a new-style cty.Value configuration (which must be of | ||
181 | // an object type) into a minimal old-style *terraform.ResourceConfig object | ||
182 | // that should be populated enough to appease the not-yet-updated functionality | ||
183 | // in this package. This should be removed once everything is updated. | ||
184 | func (b *Backend) shimConfig(obj cty.Value) *terraform.ResourceConfig { | ||
185 | shimMap, ok := hcl2shim.ConfigValueFromHCL2(obj).(map[string]interface{}) | ||
186 | if !ok { | ||
187 | // If the configVal was nil, we still want a non-nil map here. | ||
188 | shimMap = map[string]interface{}{} | ||
189 | } | ||
190 | return &terraform.ResourceConfig{ | ||
191 | Config: shimMap, | ||
192 | Raw: shimMap, | ||
193 | } | ||
88 | } | 194 | } |
89 | 195 | ||
90 | // Config returns the configuration. This is available after Configure is | 196 | // Config returns the configuration. This is available after Configure is |