github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/states/statefile/version1_upgrade.go (about)

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