decode legacy timeouts

The new decoder is more precise, and unpacks the timeout block into a
single map, which ResourceTimeout.ConfigDecode was updated to handle.
We however still need to work with legacy versions of terraform, with
the old decoder.
This commit is contained in:
James Bardin 2019-01-30 16:10:17 -05:00
parent 8a3bf9a592
commit 9cf8f48239
3 changed files with 103 additions and 10 deletions

View File

@ -278,7 +278,7 @@ func TestProviderValidate(t *testing.T) {
} }
} }
func TestProviderDiff_timeoutInvalidType(t *testing.T) { func TestProviderDiff_legacyTimeoutType(t *testing.T) {
p := &Provider{ p := &Provider{
ResourcesMap: map[string]*Resource{ ResourcesMap: map[string]*Resource{
"blah": &Resource{ "blah": &Resource{
@ -308,6 +308,48 @@ func TestProviderDiff_timeoutInvalidType(t *testing.T) {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }
_, err = p.Diff(
&terraform.InstanceInfo{
Type: "blah",
},
nil,
terraform.NewResourceConfig(ic),
)
if err != nil {
t.Fatal(err)
}
}
func TestProviderDiff_invalidTimeoutType(t *testing.T) {
p := &Provider{
ResourcesMap: map[string]*Resource{
"blah": &Resource{
Schema: map[string]*Schema{
"foo": {
Type: TypeInt,
Optional: true,
},
},
Timeouts: &ResourceTimeout{
Create: DefaultTimeout(10 * time.Minute),
},
},
},
}
invalidCfg := map[string]interface{}{
"foo": 42,
"timeouts": []interface{}{
map[string]interface{}{
"create": "40m",
},
},
}
ic, err := config.NewRawConfig(invalidCfg)
if err != nil {
t.Fatalf("err: %s", err)
}
_, err = p.Diff( _, err = p.Diff(
&terraform.InstanceInfo{ &terraform.InstanceInfo{
Type: "blah", Type: "blah",

View File

@ -63,7 +63,27 @@ func (t *ResourceTimeout) ConfigDecode(s *Resource, c *terraform.ResourceConfig)
} }
if raw, ok := c.Config[TimeoutsConfigKey]; ok { if raw, ok := c.Config[TimeoutsConfigKey]; ok {
if timeoutValues, ok := raw.(map[string]interface{}); ok { var rawTimeouts []map[string]interface{}
switch raw := raw.(type) {
case map[string]interface{}:
rawTimeouts = append(rawTimeouts, raw)
case []map[string]interface{}:
rawTimeouts = raw
case string:
if raw == config.UnknownVariableValue {
// Timeout is not defined in the config
// Defaults will be used instead
return nil
} else {
log.Printf("[ERROR] Invalid timeout value: %q", raw)
return fmt.Errorf("Invalid Timeout value found")
}
default:
log.Printf("[ERROR] Invalid timeout structure: %#v", raw)
return fmt.Errorf("Invalid Timeout structure found")
}
for _, timeoutValues := range rawTimeouts {
for timeKey, timeValue := range timeoutValues { for timeKey, timeValue := range timeoutValues {
// validate that we're dealing with the normal CRUD actions // validate that we're dealing with the normal CRUD actions
var found bool var found bool
@ -108,14 +128,6 @@ func (t *ResourceTimeout) ConfigDecode(s *Resource, c *terraform.ResourceConfig)
} }
return nil return nil
} }
if v, ok := raw.(string); ok && v == config.UnknownVariableValue {
// Timeout is not defined in the config
// Defaults will be used instead
return nil
}
log.Printf("[ERROR] Invalid timeout structure: %T", raw)
return fmt.Errorf("Invalid Timeout structure found")
} }
return nil return nil

View File

@ -129,6 +129,45 @@ func TestResourceTimeout_ConfigDecode(t *testing.T) {
} }
} }
func TestResourceTimeout_legacyConfigDecode(t *testing.T) {
r := &Resource{
Timeouts: &ResourceTimeout{
Create: DefaultTimeout(10 * time.Minute),
Update: DefaultTimeout(5 * time.Minute),
},
}
raw, err := config.NewRawConfig(
map[string]interface{}{
"foo": "bar",
TimeoutsConfigKey: []map[string]interface{}{
{
"create": "2m",
"update": "1m",
},
},
})
if err != nil {
t.Fatalf("err: %s", err)
}
c := terraform.NewResourceConfig(raw)
timeout := &ResourceTimeout{}
err = timeout.ConfigDecode(r, c)
if err != nil {
t.Fatalf("Expected good timeout returned:, %s", err)
}
expected := &ResourceTimeout{
Create: DefaultTimeout(2 * time.Minute),
Update: DefaultTimeout(1 * time.Minute),
}
if !reflect.DeepEqual(timeout, expected) {
t.Fatalf("bad timeout decode.\nExpected:\n%#v\nGot:\n%#v\n", expected, timeout)
}
}
func TestResourceTimeout_DiffEncode_basic(t *testing.T) { func TestResourceTimeout_DiffEncode_basic(t *testing.T) {
cases := []struct { cases := []struct {
Timeout *ResourceTimeout Timeout *ResourceTimeout