Skip to content

Commit

Permalink
Merge pull request #31698 from hashicorp/megan_tf563
Browse files Browse the repository at this point in the history
Send the JSON state representation to Cloud backend (when available)
  • Loading branch information
megan07 committed Aug 30, 2022
2 parents 477f7fe + 37b7e6e commit cb34020
Show file tree
Hide file tree
Showing 52 changed files with 795 additions and 473 deletions.
4 changes: 2 additions & 2 deletions go.mod
Expand Up @@ -40,7 +40,7 @@ require (
github.com/hashicorp/go-multierror v1.1.1
github.com/hashicorp/go-plugin v1.4.3
github.com/hashicorp/go-retryablehttp v0.7.1
github.com/hashicorp/go-tfe v1.7.0
github.com/hashicorp/go-tfe v1.9.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
Expand Down Expand Up @@ -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.9.1 // indirect
github.com/hashicorp/go-slug v0.10.0 // 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
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Expand Up @@ -370,13 +370,13 @@ github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5O
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.9.1 h1:gYNVJ3t0jAWx8AT2eYZci3Xd7NBHyjayW9AR1DU4ki0=
github.com/hashicorp/go-slug v0.9.1/go.mod h1:Ib+IWBYfEfJGI1ZyXMGNbu2BU+aa3Dzu41RKLH301v4=
github.com/hashicorp/go-slug v0.10.0 h1:mh4DDkBJTh9BuEjY/cv8PTo7k9OjT4PcW8PgZnJ4jTY=
github.com/hashicorp/go-slug v0.10.0/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.7.0 h1:GELRhS5dizF6giwjZBqUC/xPaSuNYB+hWRtUnf6i8K8=
github.com/hashicorp/go-tfe v1.7.0/go.mod h1:E8a90lC4kjU5Lc2c0D+SnWhUuyuoCIVm4Ewzv3jCD3A=
github.com/hashicorp/go-tfe v1.9.0 h1:jkmyo7WKNA7gZDegG5imndoC4sojWXhqMufO+KcHqrU=
github.com/hashicorp/go-tfe v1.9.0/go.mod h1:uSWi2sPw7tLrqNIiASid9j3SprbbkPSJ/2s3X0mMemg=
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/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
Expand Down
2 changes: 1 addition & 1 deletion internal/backend/local/backend.go
Expand Up @@ -344,7 +344,7 @@ func (b *Local) opWait(

// try to force a PersistState just in case the process is terminated
// before we can complete.
if err := opStateMgr.PersistState(); err != nil {
if err := opStateMgr.PersistState(nil); err != nil {
// We can't error out from here, but warn the user if there was an error.
// If this isn't transient, we will catch it again below, and
// attempt to save the state another way.
Expand Down
18 changes: 9 additions & 9 deletions internal/backend/local/backend_apply.go
Expand Up @@ -53,7 +53,7 @@ func (b *Local) opApply(
op.ReportResult(runningOp, diags)
return
}
// the state was locked during succesfull context creation; unlock the state
// the state was locked during successful context creation; unlock the state
// when the operation completes
defer func() {
diags := op.StateLocker.Unlock()
Expand All @@ -68,6 +68,13 @@ func (b *Local) opApply(
// operation.
runningOp.State = lr.InputState

schemas, moreDiags := lr.Core.Schemas(lr.Config, lr.InputState)
diags = diags.Append(moreDiags)
if moreDiags.HasErrors() {
op.ReportResult(runningOp, diags)
return
}

var plan *plans.Plan
// If we weren't given a plan, then we refresh/plan
if op.PlanFile == nil {
Expand All @@ -80,13 +87,6 @@ func (b *Local) opApply(
return
}

schemas, moreDiags := lr.Core.Schemas(lr.Config, lr.InputState)
diags = diags.Append(moreDiags)
if moreDiags.HasErrors() {
op.ReportResult(runningOp, diags)
return
}

trivialPlan := !plan.CanApply()
hasUI := op.UIOut != nil && op.UIIn != nil
mustConfirm := hasUI && !op.AutoApprove && !trivialPlan
Expand Down Expand Up @@ -198,7 +198,7 @@ func (b *Local) opApply(

// Store the final state
runningOp.State = applyState
err := statemgr.WriteAndPersist(opState, applyState)
err := statemgr.WriteAndPersist(opState, applyState, schemas)
if err != nil {
// Export the state file from the state manager and assign the new
// state. This is needed to preserve the existing serial and lineage.
Expand Down
3 changes: 2 additions & 1 deletion internal/backend/local/backend_local_test.go
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/hashicorp/terraform/internal/states/statefile"
"github.com/hashicorp/terraform/internal/states/statemgr"
"github.com/hashicorp/terraform/internal/terminal"
"github.com/hashicorp/terraform/internal/terraform"
"github.com/hashicorp/terraform/internal/tfdiags"
)

Expand Down Expand Up @@ -233,6 +234,6 @@ func (s *stateStorageThatFailsRefresh) RefreshState() error {
return fmt.Errorf("intentionally failing for testing purposes")
}

func (s *stateStorageThatFailsRefresh) PersistState() error {
func (s *stateStorageThatFailsRefresh) PersistState(schemas *terraform.Schemas) error {
return fmt.Errorf("unimplemented")
}
12 changes: 10 additions & 2 deletions internal/backend/local/backend_refresh.go
Expand Up @@ -52,7 +52,7 @@ func (b *Local) opRefresh(
return
}

// the state was locked during succesfull context creation; unlock the state
// the state was locked during successful context creation; unlock the state
// when the operation completes
defer func() {
diags := op.StateLocker.Unlock()
Expand All @@ -73,6 +73,14 @@ func (b *Local) opRefresh(
))
}

// get schemas before writing state
schemas, moreDiags := lr.Core.Schemas(lr.Config, lr.InputState)
diags = diags.Append(moreDiags)
if moreDiags.HasErrors() {
op.ReportResult(runningOp, diags)
return
}

// Perform the refresh in a goroutine so we can be interrupted
var newState *states.State
var refreshDiags tfdiags.Diagnostics
Expand All @@ -96,7 +104,7 @@ func (b *Local) opRefresh(
return
}

err := statemgr.WriteAndPersist(opState, newState)
err := statemgr.WriteAndPersist(opState, newState, schemas)
if err != nil {
diags = diags.Append(fmt.Errorf("failed to write state: %w", err))
op.ReportResult(runningOp, diags)
Expand Down
2 changes: 1 addition & 1 deletion internal/backend/remote-state/azure/backend_state.go
Expand Up @@ -131,7 +131,7 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
err = lockUnlock(err)
return nil, err
}
if err := stateMgr.PersistState(); err != nil {
if err := stateMgr.PersistState(nil); err != nil {
err = lockUnlock(err)
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/backend/remote-state/consul/backend_state.go
Expand Up @@ -120,7 +120,7 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
err = lockUnlock(err)
return nil, err
}
if err := stateMgr.PersistState(); err != nil {
if err := stateMgr.PersistState(nil); err != nil {
err = lockUnlock(err)
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/backend/remote-state/cos/backend_state.go
Expand Up @@ -126,7 +126,7 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
err = lockUnlock(err)
return nil, err
}
if err := stateMgr.PersistState(); err != nil {
if err := stateMgr.PersistState(nil); err != nil {
err = lockUnlock(err)
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/backend/remote-state/gcs/backend_state.go
Expand Up @@ -131,7 +131,7 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
if err := st.WriteState(states.NewState()); err != nil {
return nil, unlock(err)
}
if err := st.PersistState(); err != nil {
if err := st.PersistState(nil); err != nil {
return nil, unlock(err)
}

Expand Down
2 changes: 1 addition & 1 deletion internal/backend/remote-state/inmem/backend.go
Expand Up @@ -141,7 +141,7 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
if err := s.WriteState(statespkg.NewState()); err != nil {
return nil, err
}
if err := s.PersistState(); err != nil {
if err := s.PersistState(nil); err != nil {
return nil, err
}
}
Expand Down
2 changes: 1 addition & 1 deletion internal/backend/remote-state/inmem/backend_test.go
Expand Up @@ -82,7 +82,7 @@ func TestRemoteState(t *testing.T) {
t.Fatal(err)
}

if err := s.PersistState(); err != nil {
if err := s.PersistState(nil); err != nil {
t.Fatal(err)
}

Expand Down
2 changes: 1 addition & 1 deletion internal/backend/remote-state/kubernetes/backend_state.go
Expand Up @@ -123,7 +123,7 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
if err := stateMgr.WriteState(states.NewState()); err != nil {
return nil, unlock(err)
}
if err := stateMgr.PersistState(); err != nil {
if err := stateMgr.PersistState(nil); err != nil {
return nil, unlock(err)
}

Expand Down
2 changes: 1 addition & 1 deletion internal/backend/remote-state/manta/backend_state.go
Expand Up @@ -108,7 +108,7 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
err = lockUnlock(err)
return nil, err
}
if err := stateMgr.PersistState(); err != nil {
if err := stateMgr.PersistState(nil); err != nil {
err = lockUnlock(err)
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/backend/remote-state/oss/backend_state.go
Expand Up @@ -160,7 +160,7 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
err = lockUnlock(err)
return nil, err
}
if err := stateMgr.PersistState(); err != nil {
if err := stateMgr.PersistState(nil); err != nil {
err = lockUnlock(err)
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/backend/remote-state/pg/backend_state.go
Expand Up @@ -99,7 +99,7 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
err = lockUnlock(err)
return nil, err
}
if err := stateMgr.PersistState(); err != nil {
if err := stateMgr.PersistState(nil); err != nil {
err = lockUnlock(err)
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions internal/backend/remote-state/pg/backend_test.go
Expand Up @@ -330,7 +330,7 @@ func TestBackendConcurrentLock(t *testing.T) {
t.Fatalf("failed to lock first state: %v", err)
}

if err = s1.PersistState(); err != nil {
if err = s1.PersistState(nil); err != nil {
t.Fatalf("failed to persist state: %v", err)
}

Expand All @@ -343,7 +343,7 @@ func TestBackendConcurrentLock(t *testing.T) {
t.Fatalf("failed to lock second state: %v", err)
}

if err = s2.PersistState(); err != nil {
if err = s2.PersistState(nil); err != nil {
t.Fatalf("failed to persist state: %v", err)
}

Expand Down
2 changes: 1 addition & 1 deletion internal/backend/remote-state/s3/backend_state.go
Expand Up @@ -184,7 +184,7 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
err = lockUnlock(err)
return nil, err
}
if err := stateMgr.PersistState(); err != nil {
if err := stateMgr.PersistState(nil); err != nil {
err = lockUnlock(err)
return nil, err
}
Expand Down
10 changes: 5 additions & 5 deletions internal/backend/remote-state/s3/backend_test.go
Expand Up @@ -478,7 +478,7 @@ func TestBackendExtraPaths(t *testing.T) {
// Write the first state
stateMgr := &remote.State{Client: client}
stateMgr.WriteState(s1)
if err := stateMgr.PersistState(); err != nil {
if err := stateMgr.PersistState(nil); err != nil {
t.Fatal(err)
}

Expand All @@ -488,7 +488,7 @@ func TestBackendExtraPaths(t *testing.T) {
client.path = b.path("s2")
stateMgr2 := &remote.State{Client: client}
stateMgr2.WriteState(s2)
if err := stateMgr2.PersistState(); err != nil {
if err := stateMgr2.PersistState(nil); err != nil {
t.Fatal(err)
}

Expand All @@ -501,7 +501,7 @@ func TestBackendExtraPaths(t *testing.T) {
// put a state in an env directory name
client.path = b.workspaceKeyPrefix + "/error"
stateMgr.WriteState(states.NewState())
if err := stateMgr.PersistState(); err != nil {
if err := stateMgr.PersistState(nil); err != nil {
t.Fatal(err)
}
if err := checkStateList(b, []string{"default", "s1", "s2"}); err != nil {
Expand All @@ -511,7 +511,7 @@ func TestBackendExtraPaths(t *testing.T) {
// add state with the wrong key for an existing env
client.path = b.workspaceKeyPrefix + "/s2/notTestState"
stateMgr.WriteState(states.NewState())
if err := stateMgr.PersistState(); err != nil {
if err := stateMgr.PersistState(nil); err != nil {
t.Fatal(err)
}
if err := checkStateList(b, []string{"default", "s1", "s2"}); err != nil {
Expand Down Expand Up @@ -550,7 +550,7 @@ func TestBackendExtraPaths(t *testing.T) {
// add a state with a key that matches an existing environment dir name
client.path = b.workspaceKeyPrefix + "/s2/"
stateMgr.WriteState(states.NewState())
if err := stateMgr.PersistState(); err != nil {
if err := stateMgr.PersistState(nil); err != nil {
t.Fatal(err)
}

Expand Down
2 changes: 1 addition & 1 deletion internal/backend/remote-state/swift/backend_state.go
Expand Up @@ -172,7 +172,7 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) {
err = lockUnlock(err)
return nil, err
}
if err := stateMgr.PersistState(); err != nil {
if err := stateMgr.PersistState(nil); err != nil {
err = lockUnlock(err)
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions internal/backend/testing.go
Expand Up @@ -132,7 +132,7 @@ func TestBackendStates(t *testing.T, b Backend) {
if err := foo.WriteState(fooState); err != nil {
t.Fatal("error writing foo state:", err)
}
if err := foo.PersistState(); err != nil {
if err := foo.PersistState(nil); err != nil {
t.Fatal("error persisting foo state:", err)
}

Expand Down Expand Up @@ -160,7 +160,7 @@ func TestBackendStates(t *testing.T, b Backend) {
if err := bar.WriteState(barState); err != nil {
t.Fatalf("bad: %s", err)
}
if err := bar.PersistState(); err != nil {
if err := bar.PersistState(nil); err != nil {
t.Fatalf("bad: %s", err)
}

Expand Down
24 changes: 5 additions & 19 deletions internal/cloud/backend.go
Expand Up @@ -526,15 +526,10 @@ func (b *Cloud) DeleteWorkspace(name string) error {
}

// Configure the remote workspace name.
client := &remoteClient{
client: b.client,
organization: b.organization,
workspace: &tfe.Workspace{
Name: name,
},
}

return client.Delete()
State := &State{tfeClient: b.client, organization: b.organization, workspace: &tfe.Workspace{
Name: name,
}}
return State.Delete()
}

// StateMgr implements backend.Enhanced.
Expand Down Expand Up @@ -619,16 +614,7 @@ func (b *Cloud) StateMgr(name string) (statemgr.Full, error) {
}
}

client := &remoteClient{
client: b.client,
organization: b.organization,
workspace: workspace,

// This is optionally set during Terraform Enterprise runs.
runID: os.Getenv("TFE_RUN_ID"),
}

return NewState(client), nil
return &State{tfeClient: b.client, organization: b.organization, workspace: workspace}, nil
}

// Operation implements backend.Enhanced.
Expand Down

0 comments on commit cb34020

Please sign in to comment.