7 "github.com/hashicorp/terraform/addrs"
8 "github.com/zclconf/go-cty/cty"
10 "github.com/hashicorp/terraform/config/hcl2shim"
11 "github.com/hashicorp/terraform/helper/schema"
13 "github.com/hashicorp/terraform/states"
14 "github.com/hashicorp/terraform/terraform"
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()
21 // in the odd case of a nil state, let the helper packages handle it
26 for _, newMod := range newState.Modules {
27 mod := state.AddModule(newMod.Addr)
29 for name, out := range newMod.OutputValues {
31 val := hcl2shim.ConfigValueFromHCL2(out.Value)
32 ty := out.Value.Type()
34 case ty == cty.String:
36 case ty.IsTupleType() || ty.IsListType():
42 mod.Outputs[name] = &terraform.OutputState{
45 Sensitive: out.Sensitive,
49 for _, res := range newMod.Resources {
50 resType := res.Addr.Type
51 providerType := res.ProviderConfig.ProviderConfig.Type
53 resource := getResource(providers, providerType, res.Addr)
55 for key, i := range res.Instances {
56 resState := &terraform.ResourceState{
58 Provider: res.ProviderConfig.String(),
61 // We should always have a Current instance here, but be safe about checking.
63 flatmap, err := shimmedAttributes(i.Current, resource)
65 return nil, fmt.Errorf("error decoding state for %q: %s", resType, err)
68 var meta map[string]interface{}
69 if i.Current.Private != nil {
70 err := json.Unmarshal(i.Current.Private, &meta)
76 resState.Primary = &terraform.InstanceState{
79 Tainted: i.Current.Status == states.ObjectTainted,
83 if i.Current.SchemaVersion != 0 {
84 resState.Primary.Meta = map[string]interface{}{
85 "schema_version": i.Current.SchemaVersion,
89 for _, dep := range i.Current.Dependencies {
90 resState.Dependencies = append(resState.Dependencies, dep.String())
93 // convert the indexes to the old style flapmap indexes
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)
101 case addrs.StringKey:
102 idx = "." + key.String()
105 mod.Resources[res.Addr.String()+idx] = resState
108 // add any deposed instances
109 for _, dep := range i.Deposed {
110 flatmap, err := shimmedAttributes(dep, resource)
112 return nil, fmt.Errorf("error decoding deposed state for %q: %s", resType, err)
115 var meta map[string]interface{}
116 if dep.Private != nil {
117 err := json.Unmarshal(dep.Private, &meta)
123 deposed := &terraform.InstanceState{
126 Tainted: dep.Status == states.ObjectTainted,
129 if dep.SchemaVersion != 0 {
130 deposed.Meta = map[string]interface{}{
131 "schema_version": dep.SchemaVersion,
135 resState.Deposed = append(resState.Deposed, deposed)
144 func getResource(providers map[string]terraform.ResourceProvider, providerName string, addr addrs.Resource) *schema.Resource {
145 p := providers[providerName]
147 panic(fmt.Sprintf("provider %q not found in test step", providerName))
150 // this is only for tests, so should only see schema.Providers
151 provider := p.(*schema.Provider)
154 case addrs.ManagedResourceMode:
155 resource := provider.ResourcesMap[addr.Type]
159 case addrs.DataResourceMode:
160 resource := provider.DataSourcesMap[addr.Type]
166 panic(fmt.Sprintf("resource %s not found in test step", addr.Type))
169 func shimmedAttributes(instance *states.ResourceInstanceObjectSrc, res *schema.Resource) (map[string]string, error) {
170 flatmap := instance.AttrsFlat
175 // if we have json attrs, they need to be decoded
176 rio, err := instance.Decode(res.CoreConfigSchema().ImpliedType())
181 instanceState, err := res.ShimInstanceStateFromValue(rio.Value)
186 return instanceState.Attributes, nil