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
19 importId := step.ImportStateId
21 resource, err := testResource(step, state)
26 importId = resource.Primary.ID
28 importPrefix := step.ImportStateIdPrefix
29 if importPrefix != "" {
30 importId = fmt.Sprintf("%s%s", importPrefix, importId)
33 // Setup the context. We initialize with an empty state. We use the
34 // full config for provider configurations.
35 mod, err := testModule(opts, step)
41 opts.State = terraform.NewState()
42 ctx, err := terraform.NewContext(&opts)
48 newState, err := ctx.Import(&terraform.ImportOpts{
49 // Set the module so that any provider config is loaded
52 Targets: []*terraform.ImportTarget{
53 &terraform.ImportTarget{
54 Addr: step.ResourceName,
60 log.Printf("[ERROR] Test: ImportState failure: %s", err)
64 // Go through the new state and verify
65 if step.ImportStateCheck != nil {
66 var states []*terraform.InstanceState
67 for _, r := range newState.RootModule().Resources {
69 states = append(states, r.Primary)
72 if err := step.ImportStateCheck(states); err != nil {
77 // Verify that all the states match
78 if step.ImportStateVerify {
79 new := newState.RootModule().Resources
80 old := state.RootModule().Resources
81 for _, r := range new {
82 // Find the existing resource
83 var oldR *terraform.ResourceState
84 for _, r2 := range old {
85 if r2.Primary != nil && r2.Primary.ID == r.Primary.ID && r2.Type == r.Type {
91 return state, fmt.Errorf(
92 "Failed state verification, resource with ID %s not found",
96 // Compare their attributes
97 actual := make(map[string]string)
98 for k, v := range r.Primary.Attributes {
101 expected := make(map[string]string)
102 for k, v := range oldR.Primary.Attributes {
106 // Remove fields we're ignoring
107 for _, v := range step.ImportStateVerifyIgnore {
108 for k, _ := range actual {
109 if strings.HasPrefix(k, v) {
113 for k, _ := range expected {
114 if strings.HasPrefix(k, v) {
120 if !reflect.DeepEqual(actual, expected) {
121 // Determine only the different attributes
122 for k, v := range expected {
123 if av, ok := actual[k]; ok && v == av {
129 spewConf := spew.NewDefaultConfig()
130 spewConf.SortKeys = true
131 return state, fmt.Errorf(
132 "ImportStateVerify attributes not equivalent. Difference is shown below. Top is actual, bottom is expected."+
134 spewConf.Sdump(actual), spewConf.Sdump(expected))
139 // Return the old state (non-imported) so we don't change anything.