diff options
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/helper/resource/testing_import_state.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/helper/resource/testing_import_state.go | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/helper/resource/testing_import_state.go b/vendor/github.com/hashicorp/terraform/helper/resource/testing_import_state.go new file mode 100644 index 0000000..28ad105 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/helper/resource/testing_import_state.go | |||
@@ -0,0 +1,141 @@ | |||
1 | package resource | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "log" | ||
6 | "reflect" | ||
7 | "strings" | ||
8 | |||
9 | "github.com/davecgh/go-spew/spew" | ||
10 | "github.com/hashicorp/terraform/terraform" | ||
11 | ) | ||
12 | |||
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 | ||
20 | if importId == "" { | ||
21 | resource, err := testResource(step, state) | ||
22 | if err != nil { | ||
23 | return state, err | ||
24 | } | ||
25 | |||
26 | importId = resource.Primary.ID | ||
27 | } | ||
28 | importPrefix := step.ImportStateIdPrefix | ||
29 | if importPrefix != "" { | ||
30 | importId = fmt.Sprintf("%s%s", importPrefix, importId) | ||
31 | } | ||
32 | |||
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) | ||
36 | if err != nil { | ||
37 | return state, err | ||
38 | } | ||
39 | |||
40 | opts.Module = mod | ||
41 | opts.State = terraform.NewState() | ||
42 | ctx, err := terraform.NewContext(&opts) | ||
43 | if err != nil { | ||
44 | return state, err | ||
45 | } | ||
46 | |||
47 | // Do the import! | ||
48 | newState, err := ctx.Import(&terraform.ImportOpts{ | ||
49 | // Set the module so that any provider config is loaded | ||
50 | Module: mod, | ||
51 | |||
52 | Targets: []*terraform.ImportTarget{ | ||
53 | &terraform.ImportTarget{ | ||
54 | Addr: step.ResourceName, | ||
55 | ID: importId, | ||
56 | }, | ||
57 | }, | ||
58 | }) | ||
59 | if err != nil { | ||
60 | log.Printf("[ERROR] Test: ImportState failure: %s", err) | ||
61 | return state, err | ||
62 | } | ||
63 | |||
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 { | ||
68 | if r.Primary != nil { | ||
69 | states = append(states, r.Primary) | ||
70 | } | ||
71 | } | ||
72 | if err := step.ImportStateCheck(states); err != nil { | ||
73 | return state, err | ||
74 | } | ||
75 | } | ||
76 | |||
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 { | ||
86 | oldR = r2 | ||
87 | break | ||
88 | } | ||
89 | } | ||
90 | if oldR == nil { | ||
91 | return state, fmt.Errorf( | ||
92 | "Failed state verification, resource with ID %s not found", | ||
93 | r.Primary.ID) | ||
94 | } | ||
95 | |||
96 | // Compare their attributes | ||
97 | actual := make(map[string]string) | ||
98 | for k, v := range r.Primary.Attributes { | ||
99 | actual[k] = v | ||
100 | } | ||
101 | expected := make(map[string]string) | ||
102 | for k, v := range oldR.Primary.Attributes { | ||
103 | expected[k] = v | ||
104 | } | ||
105 | |||
106 | // Remove fields we're ignoring | ||
107 | for _, v := range step.ImportStateVerifyIgnore { | ||
108 | for k, _ := range actual { | ||
109 | if strings.HasPrefix(k, v) { | ||
110 | delete(actual, k) | ||
111 | } | ||
112 | } | ||
113 | for k, _ := range expected { | ||
114 | if strings.HasPrefix(k, v) { | ||
115 | delete(expected, k) | ||
116 | } | ||
117 | } | ||
118 | } | ||
119 | |||
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 { | ||
124 | delete(expected, k) | ||
125 | delete(actual, k) | ||
126 | } | ||
127 | } | ||
128 | |||
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."+ | ||
133 | "\n\n%s\n\n%s", | ||
134 | spewConf.Sdump(actual), spewConf.Sdump(expected)) | ||
135 | } | ||
136 | } | ||
137 | } | ||
138 | |||
139 | // Return the old state (non-imported) so we don't change anything. | ||
140 | return state, nil | ||
141 | } | ||