don't panic of the users aborts backend input

When the user aborts input, it may end up as an unknown value, which
needs to be converted to null for PrepareConfig.

Allow PrepareConfig to accept null config values in order to fill in
missing defaults.
This commit is contained in:
James Bardin 2019-03-01 18:45:06 -05:00
parent a0f3a2daa0
commit 2adf5801d9
3 changed files with 32 additions and 2 deletions

View File

@ -1038,6 +1038,13 @@ func (m *Meta) backendInitFromConfig(c *configs.Backend) (backend.Backend, cty.V
if err != nil {
diags = diags.Append(fmt.Errorf("Error asking for input to configure backend %q: %s", c.Type, err))
}
// We get an unknown here if the if the user aborted input, but we can't
// turn that into a config value, so set it to null and let the provider
// handle it in PrepareConfig.
if !configVal.IsKnown() {
configVal = cty.NullVal(configVal.Type())
}
}
newVal, validateDiags := b.PrepareConfig(configVal)

View File

@ -182,7 +182,11 @@ func (b *Backend) Configure(obj cty.Value) tfdiags.Diagnostics {
// that should be populated enough to appease the not-yet-updated functionality
// in this package. This should be removed once everything is updated.
func (b *Backend) shimConfig(obj cty.Value) *terraform.ResourceConfig {
shimMap := hcl2shim.ConfigValueFromHCL2(obj).(map[string]interface{})
shimMap, ok := hcl2shim.ConfigValueFromHCL2(obj).(map[string]interface{})
if !ok {
// If the configVal was nil, we still want a non-nil map here.
shimMap = map[string]interface{}{}
}
return &terraform.ResourceConfig{
Config: shimMap,
Raw: shimMap,

View File

@ -31,6 +31,21 @@ func TestBackendPrepare(t *testing.T) {
true,
},
{
"Null config",
&Backend{
Schema: map[string]*Schema{
"foo": &Schema{
Required: true,
Type: TypeString,
},
},
},
nil,
map[string]cty.Value{},
true,
},
{
"Basic required field set",
&Backend{
@ -111,7 +126,11 @@ func TestBackendPrepare(t *testing.T) {
for i, tc := range cases {
t.Run(fmt.Sprintf("%d-%s", i, tc.Name), func(t *testing.T) {
configVal, diags := tc.B.PrepareConfig(cty.ObjectVal(tc.Config))
cfgVal := cty.NullVal(cty.Object(map[string]cty.Type{}))
if tc.Config != nil {
cfgVal = cty.ObjectVal(tc.Config)
}
configVal, diags := tc.B.PrepareConfig(cfgVal)
if diags.HasErrors() != tc.Err {
for _, d := range diags {
t.Error(d.Description())