github.com/hashicorp/terraform-plugin-sdk@v1.17.2/internal/states/statefile/version1_upgrade.go (about)

     1  package statefile
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  
     7  	"github.com/mitchellh/copystructure"
     8  )
     9  
    10  // upgradeStateV1ToV2 is used to upgrade a V1 state representation
    11  // into a V2 state representation
    12  func upgradeStateV1ToV2(old *stateV1) (*stateV2, error) {
    13  	log.Printf("[TRACE] statefile.Read: upgrading format from v1 to v2")
    14  	if old == nil {
    15  		return nil, nil
    16  	}
    17  
    18  	remote, err := old.Remote.upgradeToV2()
    19  	if err != nil {
    20  		return nil, fmt.Errorf("Error upgrading State V1: %v", err)
    21  	}
    22  
    23  	modules := make([]*moduleStateV2, len(old.Modules))
    24  	for i, module := range old.Modules {
    25  		upgraded, err := module.upgradeToV2()
    26  		if err != nil {
    27  			return nil, fmt.Errorf("Error upgrading State V1: %v", err)
    28  		}
    29  		modules[i] = upgraded
    30  	}
    31  	if len(modules) == 0 {
    32  		modules = nil
    33  	}
    34  
    35  	newState := &stateV2{
    36  		Version: 2,
    37  		Serial:  old.Serial,
    38  		Remote:  remote,
    39  		Modules: modules,
    40  	}
    41  
    42  	return newState, nil
    43  }
    44  
    45  func (old *remoteStateV1) upgradeToV2() (*remoteStateV2, error) {
    46  	if old == nil {
    47  		return nil, nil
    48  	}
    49  
    50  	config, err := copystructure.Copy(old.Config)
    51  	if err != nil {
    52  		return nil, fmt.Errorf("Error upgrading RemoteState V1: %v", err)
    53  	}
    54  
    55  	return &remoteStateV2{
    56  		Type:   old.Type,
    57  		Config: config.(map[string]string),
    58  	}, nil
    59  }
    60  
    61  func (old *moduleStateV1) upgradeToV2() (*moduleStateV2, error) {
    62  	if old == nil {
    63  		return nil, nil
    64  	}
    65  
    66  	pathRaw, err := copystructure.Copy(old.Path)
    67  	if err != nil {
    68  		return nil, fmt.Errorf("Error upgrading ModuleState V1: %v", err)
    69  	}
    70  	path, ok := pathRaw.([]string)
    71  	if !ok {
    72  		return nil, fmt.Errorf("Error upgrading ModuleState V1: path is not a list of strings")
    73  	}
    74  	if len(path) == 0 {
    75  		// We found some V1 states with a nil path. Assume root.
    76  		path = []string{"root"}
    77  	}
    78  
    79  	// Outputs needs upgrading to use the new structure
    80  	outputs := make(map[string]*outputStateV2)
    81  	for key, output := range old.Outputs {
    82  		outputs[key] = &outputStateV2{
    83  			Type:      "string",
    84  			Value:     output,
    85  			Sensitive: false,
    86  		}
    87  	}
    88  
    89  	resources := make(map[string]*resourceStateV2)
    90  	for key, oldResource := range old.Resources {
    91  		upgraded, err := oldResource.upgradeToV2()
    92  		if err != nil {
    93  			return nil, fmt.Errorf("Error upgrading ModuleState V1: %v", err)
    94  		}
    95  		resources[key] = upgraded
    96  	}
    97  
    98  	dependencies, err := copystructure.Copy(old.Dependencies)
    99  	if err != nil {
   100  		return nil, fmt.Errorf("Error upgrading ModuleState V1: %v", err)
   101  	}
   102  
   103  	return &moduleStateV2{
   104  		Path:         path,
   105  		Outputs:      outputs,
   106  		Resources:    resources,
   107  		Dependencies: dependencies.([]string),
   108  	}, nil
   109  }
   110  
   111  func (old *resourceStateV1) upgradeToV2() (*resourceStateV2, error) {
   112  	if old == nil {
   113  		return nil, nil
   114  	}
   115  
   116  	dependencies, err := copystructure.Copy(old.Dependencies)
   117  	if err != nil {
   118  		return nil, fmt.Errorf("Error upgrading ResourceState V1: %v", err)
   119  	}
   120  
   121  	primary, err := old.Primary.upgradeToV2()
   122  	if err != nil {
   123  		return nil, fmt.Errorf("Error upgrading ResourceState V1: %v", err)
   124  	}
   125  
   126  	deposed := make([]*instanceStateV2, len(old.Deposed))
   127  	for i, v := range old.Deposed {
   128  		upgraded, err := v.upgradeToV2()
   129  		if err != nil {
   130  			return nil, fmt.Errorf("Error upgrading ResourceState V1: %v", err)
   131  		}
   132  		deposed[i] = upgraded
   133  	}
   134  	if len(deposed) == 0 {
   135  		deposed = nil
   136  	}
   137  
   138  	return &resourceStateV2{
   139  		Type:         old.Type,
   140  		Dependencies: dependencies.([]string),
   141  		Primary:      primary,
   142  		Deposed:      deposed,
   143  		Provider:     old.Provider,
   144  	}, nil
   145  }
   146  
   147  func (old *instanceStateV1) upgradeToV2() (*instanceStateV2, error) {
   148  	if old == nil {
   149  		return nil, nil
   150  	}
   151  
   152  	attributes, err := copystructure.Copy(old.Attributes)
   153  	if err != nil {
   154  		return nil, fmt.Errorf("Error upgrading InstanceState V1: %v", err)
   155  	}
   156  
   157  	meta, err := copystructure.Copy(old.Meta)
   158  	if err != nil {
   159  		return nil, fmt.Errorf("Error upgrading InstanceState V1: %v", err)
   160  	}
   161  
   162  	newMeta := make(map[string]interface{})
   163  	for k, v := range meta.(map[string]string) {
   164  		newMeta[k] = v
   165  	}
   166  
   167  	return &instanceStateV2{
   168  		ID:         old.ID,
   169  		Attributes: attributes.(map[string]string),
   170  		Meta:       newMeta,
   171  	}, nil
   172  }