github.com/replicatedhq/ship@v0.55.0/pkg/lifecycle/terraform/state.go (about) 1 package terraform 2 3 import ( 4 "bytes" 5 "path" 6 7 "github.com/go-kit/kit/log" 8 "github.com/hashicorp/terraform/terraform" 9 "github.com/pkg/errors" 10 "github.com/replicatedhq/ship/pkg/state" 11 "github.com/spf13/afero" 12 ) 13 14 type stateSaver func(debug log.Logger, fs afero.Afero, statemanager state.Manager, dir string) error 15 type stateRestorer func(debug log.Logger, fs afero.Afero, statemanager state.Manager, dir string) error 16 17 // this is not on a struct because its used by two and de-duping those the *right* way is 18 // going to be a big-ish undertaking 19 func persistState(debug log.Logger, fs afero.Afero, statemanager state.Manager, dir string) error { 20 // write terraform state to state.json 21 statePath := path.Join(dir, "terraform.tfstate") 22 debug.Log("event", "tfstate.readfile", "path", statePath) 23 tfstate, err := fs.ReadFile(statePath) 24 if err != nil { 25 return errors.Wrapf(err, "load state from %s", statePath) 26 } 27 28 debug.Log("event", "tfstate.unmarshal", "path", statePath) 29 tfstatev3, err := terraform.ReadState(bytes.NewReader(tfstate)) 30 if err != nil { 31 return errors.Wrapf(err, "unmarshal tf state") 32 } 33 34 debug.Log("event", "state.load", "path", statePath) 35 shipstate, err := statemanager.CachedState() 36 if err != nil { 37 return errors.Wrapf(err, "load ship state") 38 } 39 versioned := shipstate.Versioned() 40 if versioned.V1.Terraform == nil { 41 versioned.V1.Terraform = &state.Terraform{} 42 } 43 versioned.V1.Terraform.RawState = string(tfstate) 44 versioned.V1.Terraform.State = tfstatev3 45 debug.Log("event", "state.save", "path", statePath) 46 err = statemanager.Save(versioned) 47 if err != nil { 48 return errors.Wrapf(err, "save ship state") 49 } 50 51 return nil 52 } 53 54 func restoreState(debug log.Logger, fs afero.Afero, statemanager state.Manager, dir string) error { 55 56 debug.Log("event", "state.load") 57 shipstate, err := statemanager.CachedState() 58 if err != nil { 59 return errors.Wrapf(err, "load ship state") 60 } 61 62 versioned := shipstate.Versioned() 63 if versioned.V1.Terraform == nil || versioned.V1.Terraform.RawState == "" { 64 debug.Log("event", "tfstate.noPreviousState") 65 return nil 66 } 67 68 statePath := path.Join(dir, "terraform.tfstate") 69 debug.Log("event", "tfstate.writeFile", "path", statePath) 70 71 err = fs.WriteFile(statePath, []byte(versioned.V1.Terraform.RawState), 0644) 72 if err != nil { 73 return errors.Wrapf(err, "write state file") 74 } 75 debug.Log("event", "tfstate.saved", "path", statePath) 76 return nil 77 }