]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/helper/resource/state_shim.go
update vendor and go.mod
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / helper / resource / state_shim.go
1 package resource
2
3 import (
4 "encoding/json"
5 "fmt"
6
7 "github.com/hashicorp/terraform/addrs"
8 "github.com/zclconf/go-cty/cty"
9
10 "github.com/hashicorp/terraform/config/hcl2shim"
11 "github.com/hashicorp/terraform/helper/schema"
12
13 "github.com/hashicorp/terraform/states"
14 "github.com/hashicorp/terraform/terraform"
15 )
16
17 // shimState takes a new *states.State and reverts it to a legacy state for the provider ACC tests
18 func shimNewState(newState *states.State, providers map[string]terraform.ResourceProvider) (*terraform.State, error) {
19 state := terraform.NewState()
20
21 // in the odd case of a nil state, let the helper packages handle it
22 if newState == nil {
23 return nil, nil
24 }
25
26 for _, newMod := range newState.Modules {
27 mod := state.AddModule(newMod.Addr)
28
29 for name, out := range newMod.OutputValues {
30 outputType := ""
31 val := hcl2shim.ConfigValueFromHCL2(out.Value)
32 ty := out.Value.Type()
33 switch {
34 case ty == cty.String:
35 outputType = "string"
36 case ty.IsTupleType() || ty.IsListType():
37 outputType = "list"
38 case ty.IsMapType():
39 outputType = "map"
40 }
41
42 mod.Outputs[name] = &terraform.OutputState{
43 Type: outputType,
44 Value: val,
45 Sensitive: out.Sensitive,
46 }
47 }
48
49 for _, res := range newMod.Resources {
50 resType := res.Addr.Type
51 providerType := res.ProviderConfig.ProviderConfig.Type
52
53 resource := getResource(providers, providerType, res.Addr)
54
55 for key, i := range res.Instances {
56 resState := &terraform.ResourceState{
57 Type: resType,
58 Provider: res.ProviderConfig.String(),
59 }
60
61 // We should always have a Current instance here, but be safe about checking.
62 if i.Current != nil {
63 flatmap, err := shimmedAttributes(i.Current, resource)
64 if err != nil {
65 return nil, fmt.Errorf("error decoding state for %q: %s", resType, err)
66 }
67
68 var meta map[string]interface{}
69 if i.Current.Private != nil {
70 err := json.Unmarshal(i.Current.Private, &meta)
71 if err != nil {
72 return nil, err
73 }
74 }
75
76 resState.Primary = &terraform.InstanceState{
77 ID: flatmap["id"],
78 Attributes: flatmap,
79 Tainted: i.Current.Status == states.ObjectTainted,
80 Meta: meta,
81 }
82
83 if i.Current.SchemaVersion != 0 {
84 resState.Primary.Meta = map[string]interface{}{
85 "schema_version": i.Current.SchemaVersion,
86 }
87 }
88
89 for _, dep := range i.Current.Dependencies {
90 resState.Dependencies = append(resState.Dependencies, dep.String())
91 }
92
93 // convert the indexes to the old style flapmap indexes
94 idx := ""
95 switch key.(type) {
96 case addrs.IntKey:
97 // don't add numeric index values to resources with a count of 0
98 if len(res.Instances) > 1 {
99 idx = fmt.Sprintf(".%d", key)
100 }
101 case addrs.StringKey:
102 idx = "." + key.String()
103 }
104
105 mod.Resources[res.Addr.String()+idx] = resState
106 }
107
108 // add any deposed instances
109 for _, dep := range i.Deposed {
110 flatmap, err := shimmedAttributes(dep, resource)
111 if err != nil {
112 return nil, fmt.Errorf("error decoding deposed state for %q: %s", resType, err)
113 }
114
115 var meta map[string]interface{}
116 if dep.Private != nil {
117 err := json.Unmarshal(dep.Private, &meta)
118 if err != nil {
119 return nil, err
120 }
121 }
122
123 deposed := &terraform.InstanceState{
124 ID: flatmap["id"],
125 Attributes: flatmap,
126 Tainted: dep.Status == states.ObjectTainted,
127 Meta: meta,
128 }
129 if dep.SchemaVersion != 0 {
130 deposed.Meta = map[string]interface{}{
131 "schema_version": dep.SchemaVersion,
132 }
133 }
134
135 resState.Deposed = append(resState.Deposed, deposed)
136 }
137 }
138 }
139 }
140
141 return state, nil
142 }
143
144 func getResource(providers map[string]terraform.ResourceProvider, providerName string, addr addrs.Resource) *schema.Resource {
145 p := providers[providerName]
146 if p == nil {
147 panic(fmt.Sprintf("provider %q not found in test step", providerName))
148 }
149
150 // this is only for tests, so should only see schema.Providers
151 provider := p.(*schema.Provider)
152
153 switch addr.Mode {
154 case addrs.ManagedResourceMode:
155 resource := provider.ResourcesMap[addr.Type]
156 if resource != nil {
157 return resource
158 }
159 case addrs.DataResourceMode:
160 resource := provider.DataSourcesMap[addr.Type]
161 if resource != nil {
162 return resource
163 }
164 }
165
166 panic(fmt.Sprintf("resource %s not found in test step", addr.Type))
167 }
168
169 func shimmedAttributes(instance *states.ResourceInstanceObjectSrc, res *schema.Resource) (map[string]string, error) {
170 flatmap := instance.AttrsFlat
171 if flatmap != nil {
172 return flatmap, nil
173 }
174
175 // if we have json attrs, they need to be decoded
176 rio, err := instance.Decode(res.CoreConfigSchema().ImpliedType())
177 if err != nil {
178 return nil, err
179 }
180
181 instanceState, err := res.ShimInstanceStateFromValue(rio.Value)
182 if err != nil {
183 return nil, err
184 }
185
186 return instanceState.Attributes, nil
187 }