github.com/leg100/ots@v0.0.7-0.20210919080622-034055ced4bd/state_version.go (about) 1 package ots 2 3 import ( 4 "encoding/base64" 5 "errors" 6 "fmt" 7 8 "github.com/leg100/go-tfe" 9 "gorm.io/gorm" 10 ) 11 12 var ( 13 ErrInvalidStateVersionGetOptions = errors.New("invalid state version get options") 14 ) 15 16 // StateVersion represents a Terraform Enterprise state version. 17 type StateVersion struct { 18 ID string 19 20 gorm.Model 21 22 Serial int64 23 VCSCommitSHA string 24 VCSCommitURL string 25 26 // BlobID is ID of the binary object containing the state 27 BlobID string 28 29 // State version belongs to a workspace 30 Workspace *Workspace 31 32 // Run that created this state version. Optional. 33 // Run *Run 34 35 Outputs []*StateVersionOutput 36 37 // State version has many outputs 38 StateVersionOutputs []StateVersionOutput 39 } 40 41 // StateVersionList represents a list of state versions. 42 type StateVersionList struct { 43 *tfe.Pagination 44 Items []*StateVersion 45 } 46 47 type StateVersionService interface { 48 Create(workspaceID string, opts tfe.StateVersionCreateOptions) (*StateVersion, error) 49 Current(workspaceID string) (*StateVersion, error) 50 Get(id string) (*StateVersion, error) 51 Download(id string) ([]byte, error) 52 List(opts tfe.StateVersionListOptions) (*StateVersionList, error) 53 } 54 55 type StateVersionStore interface { 56 Create(sv *StateVersion) (*StateVersion, error) 57 Get(opts StateVersionGetOptions) (*StateVersion, error) 58 List(opts tfe.StateVersionListOptions) (*StateVersionList, error) 59 } 60 61 // StateVersionGetOptions are options for retrieving a single StateVersion. 62 // Either ID *or* WorkspaceID must be specfiied. 63 type StateVersionGetOptions struct { 64 // ID of state version to retrieve 65 ID *string 66 67 // Get current state version belonging to workspace with this ID 68 WorkspaceID *string 69 } 70 71 type StateVersionFactory struct { 72 WorkspaceService WorkspaceService 73 BlobStore BlobStore 74 } 75 76 func (f *StateVersionFactory) NewStateVersion(workspaceID string, opts tfe.StateVersionCreateOptions) (*StateVersion, error) { 77 sv := StateVersion{ 78 Serial: *opts.Serial, 79 ID: GenerateID("sv"), 80 } 81 82 ws, err := f.WorkspaceService.Get(WorkspaceSpecifier{ID: &workspaceID}) 83 if err != nil { 84 return nil, err 85 } 86 sv.Workspace = ws 87 88 decoded, err := base64.StdEncoding.DecodeString(*opts.State) 89 if err != nil { 90 return nil, err 91 } 92 93 sv.BlobID = NewBlobID() 94 if err := f.BlobStore.Put(sv.BlobID, decoded); err != nil { 95 return nil, err 96 } 97 98 state, err := Parse(decoded) 99 if err != nil { 100 return nil, err 101 } 102 103 for k, v := range state.Outputs { 104 sv.Outputs = append(sv.Outputs, &StateVersionOutput{ 105 ID: GenerateID("wsout"), 106 Name: k, 107 Type: v.Type, 108 Value: v.Value, 109 }) 110 } 111 112 return &sv, nil 113 } 114 115 func (r *StateVersion) DownloadURL() string { 116 return fmt.Sprintf("/state-versions/%s/download", r.ID) 117 }