]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/helper/resource/testing_import_state.go
deps: github.com/hashicorp/terraform@sdk-v0.11-with-go-modules
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / helper / resource / testing_import_state.go
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 var importId string
20 switch {
21 case step.ImportStateIdFunc != nil:
22 var err error
23 importId, err = step.ImportStateIdFunc(state)
24 if err != nil {
25 return state, err
26 }
27 case step.ImportStateId != "":
28 importId = step.ImportStateId
29 default:
30 resource, err := testResource(step, state)
31 if err != nil {
32 return state, err
33 }
34 importId = resource.Primary.ID
35 }
36
37 importPrefix := step.ImportStateIdPrefix
38 if importPrefix != "" {
39 importId = fmt.Sprintf("%s%s", importPrefix, importId)
40 }
41
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)
45 if err != nil {
46 return state, err
47 }
48
49 opts.Module = mod
50 opts.State = terraform.NewState()
51 ctx, err := terraform.NewContext(&opts)
52 if err != nil {
53 return state, err
54 }
55
56 // Do the import!
57 newState, err := ctx.Import(&terraform.ImportOpts{
58 // Set the module so that any provider config is loaded
59 Module: mod,
60
61 Targets: []*terraform.ImportTarget{
62 &terraform.ImportTarget{
63 Addr: step.ResourceName,
64 ID: importId,
65 },
66 },
67 })
68 if err != nil {
69 log.Printf("[ERROR] Test: ImportState failure: %s", err)
70 return state, err
71 }
72
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 {
77 if r.Primary != nil {
78 states = append(states, r.Primary)
79 }
80 }
81 if err := step.ImportStateCheck(states); err != nil {
82 return state, err
83 }
84 }
85
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 {
95 oldR = r2
96 break
97 }
98 }
99 if oldR == nil {
100 return state, fmt.Errorf(
101 "Failed state verification, resource with ID %s not found",
102 r.Primary.ID)
103 }
104
105 // Compare their attributes
106 actual := make(map[string]string)
107 for k, v := range r.Primary.Attributes {
108 actual[k] = v
109 }
110 expected := make(map[string]string)
111 for k, v := range oldR.Primary.Attributes {
112 expected[k] = v
113 }
114
115 // Remove fields we're ignoring
116 for _, v := range step.ImportStateVerifyIgnore {
117 for k, _ := range actual {
118 if strings.HasPrefix(k, v) {
119 delete(actual, k)
120 }
121 }
122 for k, _ := range expected {
123 if strings.HasPrefix(k, v) {
124 delete(expected, k)
125 }
126 }
127 }
128
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 {
133 delete(expected, k)
134 delete(actual, k)
135 }
136 }
137
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."+
142 "\n\n%s\n\n%s",
143 spewConf.Sdump(actual), spewConf.Sdump(expected))
144 }
145 }
146 }
147
148 // Return the old state (non-imported) so we don't change anything.
149 return state, nil
150 }