9 "github.com/davecgh/go-spew/spew"
10 "github.com/hashicorp/terraform/terraform"
13 // testStepImportState runs an imort state test step
14 func testStepImportState(
15 opts terraform.ContextOpts,
16 state *terraform.State,
17 step TestStep) (*terraform.State, error) {
18 // Determine the ID to import
21 case step.ImportStateIdFunc != nil:
23 importId, err = step.ImportStateIdFunc(state)
27 case step.ImportStateId != "":
28 importId = step.ImportStateId
30 resource, err := testResource(step, state)
34 importId = resource.Primary.ID
37 importPrefix := step.ImportStateIdPrefix
38 if importPrefix != "" {
39 importId = fmt.Sprintf("%s%s", importPrefix, importId)
42 // Setup the context. We initialize with an empty state. We use the
43 // full config for provider configurations.
44 mod, err := testModule(opts, step)
50 opts.State = terraform.NewState()
51 ctx, err := terraform.NewContext(&opts)
57 newState, err := ctx.Import(&terraform.ImportOpts{
58 // Set the module so that any provider config is loaded
61 Targets: []*terraform.ImportTarget{
62 &terraform.ImportTarget{
63 Addr: step.ResourceName,
69 log.Printf("[ERROR] Test: ImportState failure: %s", err)
73 // Go through the new state and verify
74 if step.ImportStateCheck != nil {
75 var states []*terraform.InstanceState
76 for _, r := range newState.RootModule().Resources {
78 states = append(states, r.Primary)
81 if err := step.ImportStateCheck(states); err != nil {
86 // Verify that all the states match
87 if step.ImportStateVerify {
88 new := newState.RootModule().Resources
89 old := state.RootModule().Resources
90 for _, r := range new {
91 // Find the existing resource
92 var oldR *terraform.ResourceState
93 for _, r2 := range old {
94 if r2.Primary != nil && r2.Primary.ID == r.Primary.ID && r2.Type == r.Type {
100 return state, fmt.Errorf(
101 "Failed state verification, resource with ID %s not found",
105 // Compare their attributes
106 actual := make(map[string]string)
107 for k, v := range r.Primary.Attributes {
110 expected := make(map[string]string)
111 for k, v := range oldR.Primary.Attributes {
115 // Remove fields we're ignoring
116 for _, v := range step.ImportStateVerifyIgnore {
117 for k, _ := range actual {
118 if strings.HasPrefix(k, v) {
122 for k, _ := range expected {
123 if strings.HasPrefix(k, v) {
129 if !reflect.DeepEqual(actual, expected) {
130 // Determine only the different attributes
131 for k, v := range expected {
132 if av, ok := actual[k]; ok && v == av {
138 spewConf := spew.NewDefaultConfig()
139 spewConf.SortKeys = true
140 return state, fmt.Errorf(
141 "ImportStateVerify attributes not equivalent. Difference is shown below. Top is actual, bottom is expected."+
143 spewConf.Sdump(actual), spewConf.Sdump(expected))
148 // Return the old state (non-imported) so we don't change anything.