From d72911a640e684e0b595cdd638b2ddf77b1515b0 Mon Sep 17 00:00:00 2001 From: Anna Winkler <3526523+annawinkler@users.noreply.github.com> Date: Mon, 18 Jul 2022 13:15:37 -0600 Subject: [PATCH 1/4] Save detailed type outputs to JSONStateOutputs --- go.mod | 10 +++++----- go.sum | 19 +++++++++++-------- internal/backend/remote/backend_state.go | 23 ++++++++++++++++++----- internal/cloud/backend_state.go | 23 ++++++++++++++++++----- internal/command/jsonstate/state.go | 5 +++-- internal/command/jsonstate/state_test.go | 5 +++-- 6 files changed, 58 insertions(+), 27 deletions(-) diff --git a/go.mod b/go.mod index e603cd907ce4..f6283047a0b5 100644 --- a/go.mod +++ b/go.mod @@ -39,9 +39,9 @@ require ( github.com/hashicorp/go-hclog v0.15.0 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-plugin v1.4.3 - github.com/hashicorp/go-retryablehttp v0.7.0 - github.com/hashicorp/go-tfe v1.0.0 - github.com/hashicorp/go-uuid v1.0.2 + github.com/hashicorp/go-retryablehttp v0.7.1 + github.com/hashicorp/go-tfe v1.5.0 + github.com/hashicorp/go-uuid v1.0.3 github.com/hashicorp/go-version v1.6.0 github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f github.com/hashicorp/hcl/v2 v2.13.0 @@ -144,7 +144,7 @@ require ( github.com/hashicorp/go-msgpack v0.5.4 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect - github.com/hashicorp/go-slug v0.8.0 // indirect + github.com/hashicorp/go-slug v0.9.1 // indirect github.com/hashicorp/golang-lru v0.5.1 // indirect github.com/hashicorp/jsonapi v0.0.0-20210826224640-ee7dae0fb22d // indirect github.com/hashicorp/serf v0.9.5 // indirect @@ -184,7 +184,7 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.66.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.30.0 // indirect k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect diff --git a/go.sum b/go.sum index 15b93d78261e..275b0d2c00b8 100644 --- a/go.sum +++ b/go.sum @@ -363,23 +363,25 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-plugin v1.4.3 h1:DXmvivbWD5qdiBts9TpBC7BYL1Aia5sxbRgQB+v6UZM= github.com/hashicorp/go-plugin v1.4.3/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ38b18Udy6vYQ= -github.com/hashicorp/go-retryablehttp v0.7.0 h1:eu1EI/mbirUgP5C8hVsTNaGZreBDlYiwC1FZWkvQPQ4= github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= +github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1aJLQ4LJJbTQ= +github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= -github.com/hashicorp/go-slug v0.8.0 h1:h7AGtXVAI/cJ/Wwa/JQQaftQnWQmZbAzkzgZeZVVmLw= -github.com/hashicorp/go-slug v0.8.0/go.mod h1:Ib+IWBYfEfJGI1ZyXMGNbu2BU+aa3Dzu41RKLH301v4= +github.com/hashicorp/go-slug v0.9.1 h1:gYNVJ3t0jAWx8AT2eYZci3Xd7NBHyjayW9AR1DU4ki0= +github.com/hashicorp/go-slug v0.9.1/go.mod h1:Ib+IWBYfEfJGI1ZyXMGNbu2BU+aa3Dzu41RKLH301v4= github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-tfe v1.0.0 h1:CmwoHrOs7WJfD/yEmVjJ65+dyKeVRrgvRHBLVSQQ6Ks= -github.com/hashicorp/go-tfe v1.0.0/go.mod h1:tJF/OlAXzVbmjiimAPLplSLgwg6kZDUOy0MzHuMwvF4= +github.com/hashicorp/go-tfe v1.5.0 h1:MtABkqH2s6lRFl8HaGt0qESLGAyrmMAFfecsEm+13K8= +github.com/hashicorp/go-tfe v1.5.0/go.mod h1:E8a90lC4kjU5Lc2c0D+SnWhUuyuoCIVm4Ewzv3jCD3A= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= @@ -596,8 +598,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.194/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.232 h1:kwsWbh4rEw42ZDe9/812ebhbwNZxlQyZ2sTmxBOKhN4= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.232/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= @@ -1060,8 +1062,9 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/internal/backend/remote/backend_state.go b/internal/backend/remote/backend_state.go index 53437d7b60c9..54cdd0aadb84 100644 --- a/internal/backend/remote/backend_state.go +++ b/internal/backend/remote/backend_state.go @@ -5,9 +5,12 @@ import ( "context" "crypto/md5" "encoding/base64" + "encoding/json" "fmt" tfe "github.com/hashicorp/go-tfe" + + "github.com/hashicorp/terraform/internal/command/jsonstate" "github.com/hashicorp/terraform/internal/states/remote" "github.com/hashicorp/terraform/internal/states/statefile" "github.com/hashicorp/terraform/internal/states/statemgr" @@ -65,12 +68,22 @@ func (r *remoteClient) Put(state []byte) error { return fmt.Errorf("Error reading state: %s", err) } + ov, err := jsonstate.MarshalOutputs(stateFile.State.RootModule().OutputValues) + if err != nil { + return fmt.Errorf("Error reading output values: %s", err) + } + o, err := json.Marshal(ov) + if err != nil { + return fmt.Errorf("Error converting output values to json: %s", err) + } + options := tfe.StateVersionCreateOptions{ - Lineage: tfe.String(stateFile.Lineage), - Serial: tfe.Int64(int64(stateFile.Serial)), - MD5: tfe.String(fmt.Sprintf("%x", md5.Sum(state))), - State: tfe.String(base64.StdEncoding.EncodeToString(state)), - Force: tfe.Bool(r.forcePush), + Lineage: tfe.String(stateFile.Lineage), + Serial: tfe.Int64(int64(stateFile.Serial)), + MD5: tfe.String(fmt.Sprintf("%x", md5.Sum(state))), + State: tfe.String(base64.StdEncoding.EncodeToString(state)), + Force: tfe.Bool(r.forcePush), + JSONStateOutputs: tfe.String(base64.StdEncoding.EncodeToString(o)), } // If we have a run ID, make sure to add it to the options diff --git a/internal/cloud/backend_state.go b/internal/cloud/backend_state.go index 57bdf7bdabb3..94a1d7a92583 100644 --- a/internal/cloud/backend_state.go +++ b/internal/cloud/backend_state.go @@ -5,9 +5,12 @@ import ( "context" "crypto/md5" "encoding/base64" + "encoding/json" "fmt" tfe "github.com/hashicorp/go-tfe" + + "github.com/hashicorp/terraform/internal/command/jsonstate" "github.com/hashicorp/terraform/internal/states/remote" "github.com/hashicorp/terraform/internal/states/statefile" "github.com/hashicorp/terraform/internal/states/statemgr" @@ -65,12 +68,22 @@ func (r *remoteClient) Put(state []byte) error { return fmt.Errorf("Error reading state: %s", err) } + ov, err := jsonstate.MarshalOutputs(stateFile.State.RootModule().OutputValues) + if err != nil { + return fmt.Errorf("Error reading output values: %s", err) + } + o, err := json.Marshal(ov) + if err != nil { + return fmt.Errorf("Error converting output values to json: %s", err) + } + options := tfe.StateVersionCreateOptions{ - Lineage: tfe.String(stateFile.Lineage), - Serial: tfe.Int64(int64(stateFile.Serial)), - MD5: tfe.String(fmt.Sprintf("%x", md5.Sum(state))), - State: tfe.String(base64.StdEncoding.EncodeToString(state)), - Force: tfe.Bool(r.forcePush), + Lineage: tfe.String(stateFile.Lineage), + Serial: tfe.Int64(int64(stateFile.Serial)), + MD5: tfe.String(fmt.Sprintf("%x", md5.Sum(state))), + State: tfe.String(base64.StdEncoding.EncodeToString(state)), + Force: tfe.Bool(r.forcePush), + JSONStateOutputs: tfe.String(base64.StdEncoding.EncodeToString(o)), } // If we have a run ID, make sure to add it to the options diff --git a/internal/command/jsonstate/state.go b/internal/command/jsonstate/state.go index 83d5c5c377d4..5b91c9c14895 100644 --- a/internal/command/jsonstate/state.go +++ b/internal/command/jsonstate/state.go @@ -159,7 +159,7 @@ func (jsonstate *state) marshalStateValues(s *states.State, schemas *terraform.S var err error // only marshal the root module outputs - sv.Outputs, err = marshalOutputs(s.RootModule().OutputValues) + sv.Outputs, err = MarshalOutputs(s.RootModule().OutputValues) if err != nil { return err } @@ -174,7 +174,8 @@ func (jsonstate *state) marshalStateValues(s *states.State, schemas *terraform.S return nil } -func marshalOutputs(outputs map[string]*states.OutputValue) (map[string]output, error) { +// MarshalOutputs returns the json representation of the state output values +func MarshalOutputs(outputs map[string]*states.OutputValue) (map[string]output, error) { if outputs == nil { return nil, nil } diff --git a/internal/command/jsonstate/state_test.go b/internal/command/jsonstate/state_test.go index 475b6d5ad678..c0cd2e81c38a 100644 --- a/internal/command/jsonstate/state_test.go +++ b/internal/command/jsonstate/state_test.go @@ -6,12 +6,13 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/zclconf/go-cty/cty" + "github.com/hashicorp/terraform/internal/addrs" "github.com/hashicorp/terraform/internal/configs/configschema" "github.com/hashicorp/terraform/internal/lang/marks" "github.com/hashicorp/terraform/internal/states" "github.com/hashicorp/terraform/internal/terraform" - "github.com/zclconf/go-cty/cty" ) func TestMarshalOutputs(t *testing.T) { @@ -92,7 +93,7 @@ func TestMarshalOutputs(t *testing.T) { } for _, test := range tests { - got, err := marshalOutputs(test.Outputs) + got, err := MarshalOutputs(test.Outputs) if test.Err { if err == nil { t.Fatal("succeeded; want error") From 01d510f3cbb7a2e6736d64de11c54ca52072cf28 Mon Sep 17 00:00:00 2001 From: Brandon Croft Date: Fri, 22 Jul 2022 11:25:22 -0600 Subject: [PATCH 2/4] test(cloud): ensure state version is created when saving state --- internal/cloud/backend_state_test.go | 46 +++++++++++++++++++++++++++- internal/cloud/tfe_client_mock.go | 3 ++ internal/command/jsonstate/state.go | 3 +- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/internal/cloud/backend_state_test.go b/internal/cloud/backend_state_test.go index 63c970438a3c..f62ef2846969 100644 --- a/internal/cloud/backend_state_test.go +++ b/internal/cloud/backend_state_test.go @@ -5,6 +5,7 @@ import ( "os" "testing" + tfe "github.com/hashicorp/go-tfe" "github.com/hashicorp/terraform/internal/states" "github.com/hashicorp/terraform/internal/states/remote" "github.com/hashicorp/terraform/internal/states/statefile" @@ -19,7 +20,50 @@ func TestRemoteClient(t *testing.T) { remote.TestClient(t, client) } -func TestRemoteClient_stateLock(t *testing.T) { +func TestRemoteClient_stateVersionCreated(t *testing.T) { + b, bCleanup := testBackendWithName(t) + defer bCleanup() + + raw, err := b.StateMgr(testBackendSingleWorkspaceName) + if err != nil { + t.Fatalf("error: %v", err) + } + + client := raw.(*remote.State).Client + + err = client.Put(([]byte)(` +{ + "version": 4, + "terraform_version": "1.3.0", + "serial": 1, + "lineage": "backend-change", + "outputs": { + "foo": { + "type": "string", + "value": "bar" + } + } +}`)) + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + + stateVersionsAPI := b.client.StateVersions.(*MockStateVersions) + if got, want := len(stateVersionsAPI.stateVersions), 1; got != want { + t.Fatalf("wrong number of state versions in the mock client %d; want %d", got, want) + } + + var stateVersion *tfe.StateVersion + for _, sv := range stateVersionsAPI.stateVersions { + stateVersion = sv + } + + if stateVersionsAPI.outputStates[stateVersion.ID] == nil || len(stateVersionsAPI.outputStates[stateVersion.ID]) == 0 { + t.Fatal("no state version outputs in the mock client") + } +} + +func TestRemoteClient_TestRemoteLocks(t *testing.T) { b, bCleanup := testBackendWithName(t) defer bCleanup() diff --git a/internal/cloud/tfe_client_mock.go b/internal/cloud/tfe_client_mock.go index 9888599faede..f6f026b62b3a 100644 --- a/internal/cloud/tfe_client_mock.go +++ b/internal/cloud/tfe_client_mock.go @@ -923,6 +923,7 @@ type MockStateVersions struct { states map[string][]byte stateVersions map[string]*tfe.StateVersion workspaces map[string][]string + outputStates map[string][]byte } func newMockStateVersions(client *MockClient) *MockStateVersions { @@ -931,6 +932,7 @@ func newMockStateVersions(client *MockClient) *MockStateVersions { states: make(map[string][]byte), stateVersions: make(map[string]*tfe.StateVersion), workspaces: make(map[string][]string), + outputStates: make(map[string][]byte), } } @@ -972,6 +974,7 @@ func (m *MockStateVersions) Create(ctx context.Context, workspaceID string, opti } m.states[sv.DownloadURL] = state + m.outputStates[sv.ID] = []byte(*options.JSONStateOutputs) m.stateVersions[sv.ID] = sv m.workspaces[workspaceID] = append(m.workspaces[workspaceID], sv.ID) diff --git a/internal/command/jsonstate/state.go b/internal/command/jsonstate/state.go index 5b91c9c14895..20491fdbce89 100644 --- a/internal/command/jsonstate/state.go +++ b/internal/command/jsonstate/state.go @@ -174,7 +174,8 @@ func (jsonstate *state) marshalStateValues(s *states.State, schemas *terraform.S return nil } -// MarshalOutputs returns the json representation of the state output values +// MarshalOutputs translates a map of states.OutputValue to a map of jsonstate.output, +// which are defined for json encoding. func MarshalOutputs(outputs map[string]*states.OutputValue) (map[string]output, error) { if outputs == nil { return nil, nil From 0b9bd2fc36f0183e87fa5c01ce8e64ae2c958649 Mon Sep 17 00:00:00 2001 From: Brandon Croft Date: Fri, 22 Jul 2022 11:31:48 -0600 Subject: [PATCH 3/4] make cloud backend_state error messages more conventional --- internal/cloud/backend_state.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/internal/cloud/backend_state.go b/internal/cloud/backend_state.go index 94a1d7a92583..f8cb9f24551d 100644 --- a/internal/cloud/backend_state.go +++ b/internal/cloud/backend_state.go @@ -6,6 +6,7 @@ import ( "crypto/md5" "encoding/base64" "encoding/json" + "errors" "fmt" tfe "github.com/hashicorp/go-tfe" @@ -36,12 +37,12 @@ func (r *remoteClient) Get() (*remote.Payload, error) { // If no state exists, then return nil. return nil, nil } - return nil, fmt.Errorf("Error retrieving state: %v", err) + return nil, fmt.Errorf("failed to retrieve state: %w", err) } state, err := r.client.StateVersions.Download(ctx, sv.DownloadURL) if err != nil { - return nil, fmt.Errorf("Error downloading state: %v", err) + return nil, fmt.Errorf("failed to download state: %w", err) } // If the state is empty, then return nil. @@ -65,16 +66,16 @@ func (r *remoteClient) Put(state []byte) error { // Read the raw state into a Terraform state. stateFile, err := statefile.Read(bytes.NewReader(state)) if err != nil { - return fmt.Errorf("Error reading state: %s", err) + return fmt.Errorf("failed to read state: %w", err) } ov, err := jsonstate.MarshalOutputs(stateFile.State.RootModule().OutputValues) if err != nil { - return fmt.Errorf("Error reading output values: %s", err) + return fmt.Errorf("failed to translate outputs: %w", err) } o, err := json.Marshal(ov) if err != nil { - return fmt.Errorf("Error converting output values to json: %s", err) + return fmt.Errorf("failed to marshal outputs to json: %w", err) } options := tfe.StateVersionCreateOptions{ @@ -96,7 +97,7 @@ func (r *remoteClient) Put(state []byte) error { _, err = r.client.StateVersions.Create(ctx, r.workspace.ID, options) if err != nil { r.stateUploadErr = true - return fmt.Errorf("Error uploading state: %v", err) + return fmt.Errorf("failed to upload state: %w", err) } return nil @@ -106,7 +107,7 @@ func (r *remoteClient) Put(state []byte) error { func (r *remoteClient) Delete() error { err := r.client.Workspaces.Delete(context.Background(), r.organization, r.workspace.Name) if err != nil && err != tfe.ErrResourceNotFound { - return fmt.Errorf("Error deleting workspace %s: %v", r.workspace.Name, err) + return fmt.Errorf("failed to delete workspace %s: %w", r.workspace.Name, err) } return nil @@ -159,7 +160,7 @@ func (r *remoteClient) Unlock(id string) error { if r.lockInfo != nil { // Verify the expected lock ID. if r.lockInfo.ID != id { - lockErr.Err = fmt.Errorf("lock ID does not match existing lock") + lockErr.Err = errors.New("lock ID does not match existing lock") return lockErr } From 7892cb6b5a88dd6ecbdff9e581611ab60cc6efa9 Mon Sep 17 00:00:00 2001 From: Brandon Croft Date: Fri, 22 Jul 2022 12:03:03 -0600 Subject: [PATCH 4/4] reformat imports using goimports --- internal/cloud/backend_state_test.go | 1 + internal/cloud/tfe_client_mock.go | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/cloud/backend_state_test.go b/internal/cloud/backend_state_test.go index f62ef2846969..d28d4d65b850 100644 --- a/internal/cloud/backend_state_test.go +++ b/internal/cloud/backend_state_test.go @@ -6,6 +6,7 @@ import ( "testing" tfe "github.com/hashicorp/go-tfe" + "github.com/hashicorp/terraform/internal/states" "github.com/hashicorp/terraform/internal/states/remote" "github.com/hashicorp/terraform/internal/states/statefile" diff --git a/internal/cloud/tfe_client_mock.go b/internal/cloud/tfe_client_mock.go index f6f026b62b3a..cd27af8f400f 100644 --- a/internal/cloud/tfe_client_mock.go +++ b/internal/cloud/tfe_client_mock.go @@ -16,8 +16,9 @@ import ( "time" tfe "github.com/hashicorp/go-tfe" - tfversion "github.com/hashicorp/terraform/version" "github.com/mitchellh/copystructure" + + tfversion "github.com/hashicorp/terraform/version" ) type MockClient struct {