2018-10-16 03:15:08 +02:00
|
|
|
package resource
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/hashicorp/terraform/addrs"
|
2019-01-10 18:20:03 +01:00
|
|
|
"github.com/hashicorp/terraform/helper/schema"
|
2018-10-16 03:15:08 +02:00
|
|
|
"github.com/hashicorp/terraform/states"
|
|
|
|
"github.com/hashicorp/terraform/terraform"
|
|
|
|
"github.com/zclconf/go-cty/cty"
|
|
|
|
)
|
|
|
|
|
|
|
|
// TestStateShim is meant to be a fairly comprehensive test, checking for dependencies, root outputs,
|
|
|
|
func TestStateShim(t *testing.T) {
|
|
|
|
state := states.NewState()
|
|
|
|
|
|
|
|
rootModule := state.RootModule()
|
|
|
|
if rootModule == nil {
|
|
|
|
t.Errorf("root module is nil; want valid object")
|
|
|
|
}
|
|
|
|
|
|
|
|
rootModule.SetOutputValue("bar", cty.ListVal([]cty.Value{cty.StringVal("bar"), cty.StringVal("value")}), false)
|
|
|
|
rootModule.SetOutputValue("secret", cty.StringVal("secret value"), true)
|
|
|
|
rootModule.SetResourceInstanceCurrent(
|
|
|
|
addrs.Resource{
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
Type: "test_thing",
|
|
|
|
Name: "foo",
|
|
|
|
}.Instance(addrs.NoKey),
|
|
|
|
&states.ResourceInstanceObjectSrc{
|
2019-01-05 04:22:42 +01:00
|
|
|
Status: states.ObjectReady,
|
|
|
|
AttrsFlat: map[string]string{"id": "foo", "bazzle": "dazzle"},
|
|
|
|
SchemaVersion: 7,
|
2019-10-21 20:42:40 +02:00
|
|
|
DependsOn: []addrs.Referenceable{
|
2018-10-16 03:15:08 +02:00
|
|
|
addrs.ResourceInstance{
|
|
|
|
Resource: addrs.Resource{
|
|
|
|
Mode: 'M',
|
|
|
|
Type: "test_thing",
|
|
|
|
Name: "baz",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2020-02-13 21:32:58 +01:00
|
|
|
addrs.AbsProviderConfig{
|
2020-04-03 20:20:24 +02:00
|
|
|
Provider: addrs.NewDefaultProvider("test"),
|
2020-03-11 19:19:52 +01:00
|
|
|
Module: addrs.RootModule,
|
2020-02-13 21:32:58 +01:00
|
|
|
},
|
2018-10-16 03:15:08 +02:00
|
|
|
)
|
|
|
|
rootModule.SetResourceInstanceCurrent(
|
|
|
|
addrs.Resource{
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
Type: "test_thing",
|
|
|
|
Name: "baz",
|
|
|
|
}.Instance(addrs.NoKey),
|
|
|
|
&states.ResourceInstanceObjectSrc{
|
2019-10-21 20:42:40 +02:00
|
|
|
Status: states.ObjectReady,
|
|
|
|
AttrsFlat: map[string]string{"id": "baz", "bazzle": "dazzle"},
|
|
|
|
DependsOn: []addrs.Referenceable{},
|
2018-10-16 03:15:08 +02:00
|
|
|
},
|
2020-02-13 21:32:58 +01:00
|
|
|
addrs.AbsProviderConfig{
|
2020-04-03 20:20:24 +02:00
|
|
|
Provider: addrs.NewDefaultProvider("test"),
|
2020-03-11 19:19:52 +01:00
|
|
|
Module: addrs.RootModule,
|
2020-02-13 21:32:58 +01:00
|
|
|
},
|
2018-10-16 03:15:08 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
childInstance := addrs.RootModuleInstance.Child("child", addrs.NoKey)
|
|
|
|
childModule := state.EnsureModule(childInstance)
|
|
|
|
childModule.SetResourceInstanceCurrent(
|
|
|
|
addrs.Resource{
|
|
|
|
Mode: addrs.DataResourceMode,
|
|
|
|
Type: "test_data_thing",
|
|
|
|
Name: "foo",
|
|
|
|
}.Instance(addrs.NoKey),
|
|
|
|
&states.ResourceInstanceObjectSrc{
|
2019-10-21 20:42:40 +02:00
|
|
|
Status: states.ObjectReady,
|
|
|
|
AttrsJSON: []byte(`{"id": "bar", "fuzzle":"wuzzle"}`),
|
|
|
|
DependsOn: []addrs.Referenceable{},
|
2018-10-16 03:15:08 +02:00
|
|
|
},
|
2020-02-13 21:32:58 +01:00
|
|
|
addrs.AbsProviderConfig{
|
2020-04-03 20:20:24 +02:00
|
|
|
Provider: addrs.NewDefaultProvider("test"),
|
2020-03-11 19:19:52 +01:00
|
|
|
Module: childInstance.Module(),
|
2020-02-13 21:32:58 +01:00
|
|
|
},
|
2018-10-16 03:15:08 +02:00
|
|
|
)
|
|
|
|
childModule.SetResourceInstanceCurrent(
|
|
|
|
addrs.Resource{
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
Type: "test_thing",
|
|
|
|
Name: "baz",
|
|
|
|
}.Instance(addrs.NoKey),
|
|
|
|
&states.ResourceInstanceObjectSrc{
|
2018-12-05 19:41:53 +01:00
|
|
|
Status: states.ObjectReady,
|
2018-10-16 03:15:08 +02:00
|
|
|
AttrsJSON: []byte(`{"id": "bar", "fizzle":"wizzle"}`),
|
2019-10-21 20:42:40 +02:00
|
|
|
DependsOn: []addrs.Referenceable{
|
2018-10-16 03:15:08 +02:00
|
|
|
addrs.ResourceInstance{
|
|
|
|
Resource: addrs.Resource{
|
|
|
|
Mode: 'D',
|
|
|
|
Type: "test_data_thing",
|
|
|
|
Name: "foo",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2020-02-13 21:32:58 +01:00
|
|
|
addrs.AbsProviderConfig{
|
2020-04-03 20:20:24 +02:00
|
|
|
Provider: addrs.NewDefaultProvider("test"),
|
2020-03-11 19:19:52 +01:00
|
|
|
Module: childInstance.Module(),
|
2020-02-13 21:32:58 +01:00
|
|
|
},
|
2018-10-16 03:15:08 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
childModule.SetResourceInstanceDeposed(
|
|
|
|
addrs.Resource{
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
Type: "test_thing",
|
|
|
|
Name: "baz",
|
|
|
|
}.Instance(addrs.NoKey),
|
|
|
|
"00000001",
|
|
|
|
&states.ResourceInstanceObjectSrc{
|
|
|
|
Status: states.ObjectReady,
|
|
|
|
AttrsFlat: map[string]string{"id": "old", "fizzle": "wizzle"},
|
2019-10-21 20:42:40 +02:00
|
|
|
DependsOn: []addrs.Referenceable{
|
2018-10-16 03:15:08 +02:00
|
|
|
addrs.ResourceInstance{
|
|
|
|
Resource: addrs.Resource{
|
|
|
|
Mode: 'D',
|
|
|
|
Type: "test_data_thing",
|
|
|
|
Name: "foo",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2020-02-13 21:32:58 +01:00
|
|
|
addrs.AbsProviderConfig{
|
2020-04-03 20:20:24 +02:00
|
|
|
Provider: addrs.NewDefaultProvider("test"),
|
2020-03-11 19:19:52 +01:00
|
|
|
Module: childInstance.Module(),
|
2020-02-13 21:32:58 +01:00
|
|
|
},
|
2018-10-16 03:15:08 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
childModule.SetResourceInstanceCurrent(
|
|
|
|
addrs.Resource{
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
Type: "test_thing",
|
|
|
|
Name: "lots",
|
|
|
|
}.Instance(addrs.IntKey(0)),
|
|
|
|
&states.ResourceInstanceObjectSrc{
|
2019-10-21 20:42:40 +02:00
|
|
|
Status: states.ObjectReady,
|
|
|
|
AttrsFlat: map[string]string{"id": "0", "bazzle": "dazzle"},
|
|
|
|
DependsOn: []addrs.Referenceable{},
|
2018-10-16 03:15:08 +02:00
|
|
|
},
|
2020-02-13 21:32:58 +01:00
|
|
|
addrs.AbsProviderConfig{
|
2020-04-03 20:20:24 +02:00
|
|
|
Provider: addrs.NewDefaultProvider("test"),
|
2020-03-11 19:19:52 +01:00
|
|
|
Module: childInstance.Module(),
|
2020-02-13 21:32:58 +01:00
|
|
|
},
|
2018-10-16 03:15:08 +02:00
|
|
|
)
|
|
|
|
childModule.SetResourceInstanceCurrent(
|
|
|
|
addrs.Resource{
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
Type: "test_thing",
|
|
|
|
Name: "lots",
|
|
|
|
}.Instance(addrs.IntKey(1)),
|
|
|
|
&states.ResourceInstanceObjectSrc{
|
2019-10-21 20:42:40 +02:00
|
|
|
Status: states.ObjectTainted,
|
|
|
|
AttrsFlat: map[string]string{"id": "1", "bazzle": "dazzle"},
|
|
|
|
DependsOn: []addrs.Referenceable{},
|
2018-12-05 19:41:53 +01:00
|
|
|
},
|
2020-02-13 21:32:58 +01:00
|
|
|
addrs.AbsProviderConfig{
|
2020-04-03 20:20:24 +02:00
|
|
|
Provider: addrs.NewDefaultProvider("test"),
|
2020-03-11 19:19:52 +01:00
|
|
|
Module: childInstance.Module(),
|
2020-02-13 21:32:58 +01:00
|
|
|
},
|
2018-12-05 19:41:53 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
childModule.SetResourceInstanceCurrent(
|
|
|
|
addrs.Resource{
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
Type: "test_thing",
|
|
|
|
Name: "single_count",
|
|
|
|
}.Instance(addrs.IntKey(0)),
|
|
|
|
&states.ResourceInstanceObjectSrc{
|
2019-10-21 20:42:40 +02:00
|
|
|
Status: states.ObjectReady,
|
|
|
|
AttrsJSON: []byte(`{"id": "single", "bazzle":"dazzle"}`),
|
|
|
|
DependsOn: []addrs.Referenceable{},
|
2018-10-16 03:15:08 +02:00
|
|
|
},
|
2020-02-13 21:32:58 +01:00
|
|
|
addrs.AbsProviderConfig{
|
2020-04-03 20:20:24 +02:00
|
|
|
Provider: addrs.NewDefaultProvider("test"),
|
2020-03-11 19:19:52 +01:00
|
|
|
Module: childInstance.Module(),
|
2020-02-13 21:32:58 +01:00
|
|
|
},
|
2018-10-16 03:15:08 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
expected := &terraform.State{
|
|
|
|
Version: 3,
|
|
|
|
Modules: []*terraform.ModuleState{
|
|
|
|
&terraform.ModuleState{
|
|
|
|
Path: []string{"root"},
|
|
|
|
Outputs: map[string]*terraform.OutputState{
|
|
|
|
"bar": {
|
|
|
|
Type: "list",
|
|
|
|
Value: []interface{}{"bar", "value"},
|
|
|
|
},
|
|
|
|
"secret": {
|
|
|
|
Sensitive: true,
|
|
|
|
Type: "string",
|
|
|
|
Value: "secret value",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Resources: map[string]*terraform.ResourceState{
|
|
|
|
"test_thing.baz": &terraform.ResourceState{
|
2019-03-19 22:45:16 +01:00
|
|
|
Type: "test_thing",
|
|
|
|
Provider: "provider.test",
|
2018-10-16 03:15:08 +02:00
|
|
|
Primary: &terraform.InstanceState{
|
|
|
|
ID: "baz",
|
|
|
|
Attributes: map[string]string{
|
|
|
|
"id": "baz",
|
|
|
|
"bazzle": "dazzle",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"test_thing.foo": &terraform.ResourceState{
|
2019-03-19 22:45:16 +01:00
|
|
|
Type: "test_thing",
|
|
|
|
Provider: "provider.test",
|
2018-10-16 03:15:08 +02:00
|
|
|
Primary: &terraform.InstanceState{
|
|
|
|
ID: "foo",
|
|
|
|
Attributes: map[string]string{
|
|
|
|
"id": "foo",
|
|
|
|
"bazzle": "dazzle",
|
|
|
|
},
|
2019-01-05 04:22:42 +01:00
|
|
|
Meta: map[string]interface{}{
|
|
|
|
"schema_version": 7,
|
|
|
|
},
|
2018-10-16 03:15:08 +02:00
|
|
|
},
|
|
|
|
Dependencies: []string{"test_thing.baz"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
&terraform.ModuleState{
|
|
|
|
Path: []string{"root", "child"},
|
|
|
|
Resources: map[string]*terraform.ResourceState{
|
|
|
|
"test_thing.baz": &terraform.ResourceState{
|
2019-03-19 22:45:16 +01:00
|
|
|
Type: "test_thing",
|
|
|
|
Provider: "module.child.provider.test",
|
2018-10-16 03:15:08 +02:00
|
|
|
Primary: &terraform.InstanceState{
|
|
|
|
ID: "bar",
|
|
|
|
Attributes: map[string]string{
|
|
|
|
"id": "bar",
|
|
|
|
"fizzle": "wizzle",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Deposed: []*terraform.InstanceState{
|
|
|
|
{
|
|
|
|
ID: "old",
|
|
|
|
Attributes: map[string]string{
|
|
|
|
"id": "old",
|
|
|
|
"fizzle": "wizzle",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Dependencies: []string{"data.test_data_thing.foo"},
|
|
|
|
},
|
|
|
|
"data.test_data_thing.foo": &terraform.ResourceState{
|
2019-03-19 22:45:16 +01:00
|
|
|
Type: "test_data_thing",
|
|
|
|
Provider: "module.child.provider.test",
|
2018-10-16 03:15:08 +02:00
|
|
|
Primary: &terraform.InstanceState{
|
|
|
|
ID: "bar",
|
|
|
|
Attributes: map[string]string{
|
|
|
|
"id": "bar",
|
|
|
|
"fuzzle": "wuzzle",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"test_thing.lots.0": &terraform.ResourceState{
|
2019-03-19 22:45:16 +01:00
|
|
|
Type: "test_thing",
|
|
|
|
Provider: "module.child.provider.test",
|
2018-10-16 03:15:08 +02:00
|
|
|
Primary: &terraform.InstanceState{
|
|
|
|
ID: "0",
|
|
|
|
Attributes: map[string]string{
|
|
|
|
"id": "0",
|
|
|
|
"bazzle": "dazzle",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"test_thing.lots.1": &terraform.ResourceState{
|
2019-03-19 22:45:16 +01:00
|
|
|
Type: "test_thing",
|
|
|
|
Provider: "module.child.provider.test",
|
2018-10-16 03:15:08 +02:00
|
|
|
Primary: &terraform.InstanceState{
|
|
|
|
ID: "1",
|
|
|
|
Attributes: map[string]string{
|
|
|
|
"id": "1",
|
|
|
|
"bazzle": "dazzle",
|
|
|
|
},
|
|
|
|
Tainted: true,
|
|
|
|
},
|
|
|
|
},
|
2018-12-05 19:41:53 +01:00
|
|
|
"test_thing.single_count": &terraform.ResourceState{
|
2019-03-19 22:45:16 +01:00
|
|
|
Type: "test_thing",
|
|
|
|
Provider: "module.child.provider.test",
|
2018-12-05 19:41:53 +01:00
|
|
|
Primary: &terraform.InstanceState{
|
|
|
|
ID: "single",
|
|
|
|
Attributes: map[string]string{
|
|
|
|
"id": "single",
|
|
|
|
"bazzle": "dazzle",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2018-10-16 03:15:08 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2019-01-10 18:20:03 +01:00
|
|
|
providers := map[string]terraform.ResourceProvider{
|
|
|
|
"test": &schema.Provider{
|
|
|
|
ResourcesMap: map[string]*schema.Resource{
|
|
|
|
"test_thing": &schema.Resource{
|
|
|
|
Schema: map[string]*schema.Schema{
|
|
|
|
"id": {Type: schema.TypeString, Computed: true},
|
|
|
|
"fizzle": {Type: schema.TypeString, Optional: true},
|
|
|
|
"bazzle": {Type: schema.TypeString, Optional: true},
|
2018-10-16 03:15:08 +02:00
|
|
|
},
|
|
|
|
},
|
2019-01-10 18:20:03 +01:00
|
|
|
},
|
|
|
|
DataSourcesMap: map[string]*schema.Resource{
|
|
|
|
"test_data_thing": &schema.Resource{
|
|
|
|
Schema: map[string]*schema.Schema{
|
|
|
|
"id": {Type: schema.TypeString, Computed: true},
|
|
|
|
"fuzzle": {Type: schema.TypeString, Optional: true},
|
2018-10-16 03:15:08 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2019-01-10 18:20:03 +01:00
|
|
|
shimmed, err := shimNewState(state, providers)
|
2018-10-16 03:15:08 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if !expected.Equal(shimmed) {
|
2020-02-13 21:32:58 +01:00
|
|
|
t.Fatalf("wrong result state\ngot:\n%s\n\nwant:\n%s", shimmed, expected)
|
2018-10-16 03:15:08 +02:00
|
|
|
}
|
|
|
|
}
|
2020-04-03 20:20:24 +02:00
|
|
|
|
|
|
|
// TestShimLegacyState only checks the functionality unique to this func: adding
|
|
|
|
// the implied provider FQN
|
|
|
|
func TestShimLegacyState(t *testing.T) {
|
|
|
|
|
|
|
|
input := &terraform.State{
|
|
|
|
Version: 3,
|
|
|
|
Modules: []*terraform.ModuleState{
|
|
|
|
&terraform.ModuleState{
|
|
|
|
Path: []string{"root"},
|
|
|
|
Resources: map[string]*terraform.ResourceState{
|
|
|
|
"test_thing.baz": &terraform.ResourceState{
|
|
|
|
Type: "test_thing",
|
|
|
|
Provider: "provider.test",
|
|
|
|
Primary: &terraform.InstanceState{
|
|
|
|
ID: "baz",
|
|
|
|
Attributes: map[string]string{
|
|
|
|
"id": "baz",
|
|
|
|
"bazzle": "dazzle",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
&terraform.ModuleState{
|
|
|
|
Path: []string{"root", "child"},
|
|
|
|
Resources: map[string]*terraform.ResourceState{
|
|
|
|
"test_thing.bar": &terraform.ResourceState{
|
|
|
|
Type: "test_thing",
|
|
|
|
Provider: "module.child.provider.test",
|
|
|
|
Primary: &terraform.InstanceState{
|
|
|
|
ID: "bar",
|
|
|
|
Attributes: map[string]string{
|
|
|
|
"id": "bar",
|
|
|
|
"fizzle": "wizzle",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
expected := states.NewState()
|
|
|
|
root := expected.EnsureModule(addrs.RootModuleInstance)
|
|
|
|
root.SetResourceInstanceCurrent(
|
|
|
|
addrs.Resource{
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
Type: "test_thing",
|
|
|
|
Name: "baz",
|
|
|
|
}.Instance(addrs.NoKey),
|
|
|
|
&states.ResourceInstanceObjectSrc{
|
|
|
|
Status: states.ObjectReady,
|
|
|
|
AttrsFlat: map[string]string{"id": "baz", "bazzle": "dazzle"},
|
|
|
|
DependsOn: []addrs.Referenceable{},
|
|
|
|
Dependencies: []addrs.ConfigResource{},
|
|
|
|
},
|
|
|
|
addrs.AbsProviderConfig{
|
|
|
|
Provider: addrs.NewDefaultProvider("test"),
|
|
|
|
Module: addrs.RootModule,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
child := expected.EnsureModule(addrs.RootModuleInstance.Child("child", addrs.NoKey))
|
|
|
|
child.SetResourceInstanceCurrent(
|
|
|
|
addrs.Resource{
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
Type: "test_thing",
|
|
|
|
Name: "bar",
|
|
|
|
}.Instance(addrs.NoKey),
|
|
|
|
&states.ResourceInstanceObjectSrc{
|
|
|
|
Status: states.ObjectReady,
|
|
|
|
AttrsFlat: map[string]string{"id": "bar", "fizzle": "wizzle"},
|
|
|
|
DependsOn: []addrs.Referenceable{},
|
|
|
|
Dependencies: []addrs.ConfigResource{},
|
|
|
|
},
|
|
|
|
addrs.AbsProviderConfig{
|
|
|
|
Provider: addrs.NewDefaultProvider("test"),
|
|
|
|
Module: child.Addr.Module(),
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
got, err := shimLegacyState(input)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error: %s", err)
|
|
|
|
}
|
|
|
|
if !got.Equal(expected) {
|
|
|
|
t.Fatal("wrong result")
|
|
|
|
}
|
|
|
|
}
|