Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send the JSON state representation to Cloud backend (when available) #31698

Merged
merged 18 commits into from Aug 30, 2022
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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
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