blob: 757a3d0f29f28d94371eb412c0943f5d24830567 [file] [log] [blame]
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package terraform
import (
"fmt"
"github.com/mitchellh/copystructure"
)
// upgradeStateV1ToV2 is used to upgrade a V1 state representation
// into a V2 state representation
func upgradeStateV1ToV2(old *stateV1) (*State, error) {
if old == nil {
return nil, nil
}
remote, err := old.Remote.upgradeToV2()
if err != nil {
return nil, fmt.Errorf("Error upgrading State V1: %v", err)
}
modules := make([]*ModuleState, len(old.Modules))
for i, module := range old.Modules {
upgraded, err := module.upgradeToV2()
if err != nil {
return nil, fmt.Errorf("Error upgrading State V1: %v", err)
}
modules[i] = upgraded
}
if len(modules) == 0 {
modules = nil
}
newState := &State{
Version: 2,
Serial: old.Serial,
Remote: remote,
Modules: modules,
}
newState.sort()
newState.init()
return newState, nil
}
func (old *remoteStateV1) upgradeToV2() (*RemoteState, error) {
if old == nil {
return nil, nil
}
config, err := copystructure.Copy(old.Config)
if err != nil {
return nil, fmt.Errorf("Error upgrading RemoteState V1: %v", err)
}
return &RemoteState{
Type: old.Type,
Config: config.(map[string]string),
}, nil
}
func (old *moduleStateV1) upgradeToV2() (*ModuleState, error) {
if old == nil {
return nil, nil
}
pathRaw, err := copystructure.Copy(old.Path)
if err != nil {
return nil, fmt.Errorf("Error upgrading ModuleState V1: %v", err)
}
path, ok := pathRaw.([]string)
if !ok {
return nil, fmt.Errorf("Error upgrading ModuleState V1: path is not a list of strings")
}
if len(path) == 0 {
// We found some V1 states with a nil path. Assume root and catch
// duplicate path errors later (as part of Validate).
path = rootModulePath
}
// Outputs needs upgrading to use the new structure
outputs := make(map[string]*OutputState)
for key, output := range old.Outputs {
outputs[key] = &OutputState{
Type: "string",
Value: output,
Sensitive: false,
}
}
resources := make(map[string]*ResourceState)
for key, oldResource := range old.Resources {
upgraded, err := oldResource.upgradeToV2()
if err != nil {
return nil, fmt.Errorf("Error upgrading ModuleState V1: %v", err)
}
resources[key] = upgraded
}
dependencies, err := copystructure.Copy(old.Dependencies)
if err != nil {
return nil, fmt.Errorf("Error upgrading ModuleState V1: %v", err)
}
return &ModuleState{
Path: path,
Outputs: outputs,
Resources: resources,
Dependencies: dependencies.([]string),
}, nil
}
func (old *resourceStateV1) upgradeToV2() (*ResourceState, error) {
if old == nil {
return nil, nil
}
dependencies, err := copystructure.Copy(old.Dependencies)
if err != nil {
return nil, fmt.Errorf("Error upgrading ResourceState V1: %v", err)
}
primary, err := old.Primary.upgradeToV2()
if err != nil {
return nil, fmt.Errorf("Error upgrading ResourceState V1: %v", err)
}
deposed := make([]*InstanceState, len(old.Deposed))
for i, v := range old.Deposed {
upgraded, err := v.upgradeToV2()
if err != nil {
return nil, fmt.Errorf("Error upgrading ResourceState V1: %v", err)
}
deposed[i] = upgraded
}
if len(deposed) == 0 {
deposed = nil
}
return &ResourceState{
Type: old.Type,
Dependencies: dependencies.([]string),
Primary: primary,
Deposed: deposed,
Provider: old.Provider,
}, nil
}
func (old *instanceStateV1) upgradeToV2() (*InstanceState, error) {
if old == nil {
return nil, nil
}
attributes, err := copystructure.Copy(old.Attributes)
if err != nil {
return nil, fmt.Errorf("Error upgrading InstanceState V1: %v", err)
}
ephemeral, err := old.Ephemeral.upgradeToV2()
if err != nil {
return nil, fmt.Errorf("Error upgrading InstanceState V1: %v", err)
}
meta, err := copystructure.Copy(old.Meta)
if err != nil {
return nil, fmt.Errorf("Error upgrading InstanceState V1: %v", err)
}
newMeta := make(map[string]interface{})
for k, v := range meta.(map[string]string) {
newMeta[k] = v
}
return &InstanceState{
ID: old.ID,
Attributes: attributes.(map[string]string),
Ephemeral: *ephemeral,
Meta: newMeta,
}, nil
}
func (old *ephemeralStateV1) upgradeToV2() (*EphemeralState, error) {
connInfo, err := copystructure.Copy(old.ConnInfo)
if err != nil {
return nil, fmt.Errorf("Error upgrading EphemeralState V1: %v", err)
}
return &EphemeralState{
ConnInfo: connInfo.(map[string]string),
}, nil
}