From f4758803fe572c428796fb9ae9c6fcaf8512ad2b Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Mon, 30 Aug 2021 15:27:58 -0700 Subject: [PATCH] cloud: Backend implements new version of the backend.Local interface This makes the new backend compatible with the new terraform.Context API, which has changed in main. --- internal/cloud/backend.go | 2 ++ internal/cloud/backend_context.go | 32 +++++++++++++++----------- internal/cloud/backend_context_test.go | 2 +- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/internal/cloud/backend.go b/internal/cloud/backend.go index b6ae5e154..2a0549689 100644 --- a/internal/cloud/backend.go +++ b/internal/cloud/backend.go @@ -90,6 +90,8 @@ type Cloud struct { } var _ backend.Backend = (*Cloud)(nil) +var _ backend.Enhanced = (*Cloud)(nil) +var _ backend.Local = (*Cloud)(nil) // New creates a new initialized cloud backend. func New(services *disco.Disco) *Cloud { diff --git a/internal/cloud/backend_context.go b/internal/cloud/backend_context.go index 55f9aba54..a564a6d3a 100644 --- a/internal/cloud/backend_context.go +++ b/internal/cloud/backend_context.go @@ -6,7 +6,6 @@ import ( "log" "strings" - "github.com/hashicorp/errwrap" tfe "github.com/hashicorp/go-tfe" "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/hclsyntax" @@ -18,9 +17,15 @@ import ( "github.com/zclconf/go-cty/cty" ) -// Context implements backend.Enhanced. -func (b *Cloud) Context(op *backend.Operation) (*terraform.Context, statemgr.Full, tfdiags.Diagnostics) { +// LocalRun implements backend.Local +func (b *Cloud) LocalRun(op *backend.Operation) (*backend.LocalRun, statemgr.Full, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics + ret := &backend.LocalRun{ + PlanOpts: &terraform.PlanOpts{ + Mode: op.PlanMode, + Targets: op.Targets, + }, + } op.StateLocker = op.StateLocker.WithContext(context.Background()) @@ -31,7 +36,7 @@ func (b *Cloud) Context(op *backend.Operation) (*terraform.Context, statemgr.Ful log.Printf("[TRACE] cloud: requesting state manager for workspace %q", remoteWorkspaceName) stateMgr, err := b.StateMgr(op.Workspace) if err != nil { - diags = diags.Append(errwrap.Wrapf("Error loading state: {{err}}", err)) + diags = diags.Append(fmt.Errorf("error loading state: %w", err)) return nil, nil, diags } @@ -50,7 +55,7 @@ func (b *Cloud) Context(op *backend.Operation) (*terraform.Context, statemgr.Ful log.Printf("[TRACE] cloud: reading remote state for workspace %q", remoteWorkspaceName) if err := stateMgr.RefreshState(); err != nil { - diags = diags.Append(errwrap.Wrapf("Error loading state: {{err}}", err)) + diags = diags.Append(fmt.Errorf("error loading state: %w", err)) return nil, nil, diags } @@ -61,15 +66,13 @@ func (b *Cloud) Context(op *backend.Operation) (*terraform.Context, statemgr.Ful } // Copy set options from the operation - opts.PlanMode = op.PlanMode - opts.Targets = op.Targets opts.UIInput = op.UIIn // Load the latest state. If we enter contextFromPlanFile below then the // state snapshot in the plan file must match this, or else it'll return // error diagnostics. log.Printf("[TRACE] cloud: retrieving remote state snapshot for workspace %q", remoteWorkspaceName) - opts.State = stateMgr.State() + ret.InputState = stateMgr.State() log.Printf("[TRACE] cloud: loading configuration for the current working directory") config, configDiags := op.ConfigLoader.LoadConfig(op.ConfigDir) @@ -77,21 +80,21 @@ func (b *Cloud) Context(op *backend.Operation) (*terraform.Context, statemgr.Ful if configDiags.HasErrors() { return nil, nil, diags } - opts.Config = config + ret.Config = config // The underlying API expects us to use the opaque workspace id to request // variables, so we'll need to look that up using our organization name // and workspace name. remoteWorkspaceID, err := b.getRemoteWorkspaceID(context.Background(), op.Workspace) if err != nil { - diags = diags.Append(errwrap.Wrapf("Error finding remote workspace: {{err}}", err)) + diags = diags.Append(fmt.Errorf("error finding remote workspace: %w", err)) return nil, nil, diags } log.Printf("[TRACE] cloud: retrieving variables from workspace %s/%s (%s)", remoteWorkspaceName, b.organization, remoteWorkspaceID) tfeVariables, err := b.client.Variables.List(context.Background(), remoteWorkspaceID, tfe.VariableListOptions{}) if err != nil && err != tfe.ErrResourceNotFound { - diags = diags.Append(errwrap.Wrapf("Error loading variables: {{err}}", err)) + diags = diags.Append(fmt.Errorf("error loading variables: %w", err)) return nil, nil, diags } @@ -100,7 +103,7 @@ func (b *Cloud) Context(op *backend.Operation) (*terraform.Context, statemgr.Ful // more lax about them, stubbing out any unset ones as unknown. // This gives us enough information to produce a consistent context, // but not enough information to run a real operation (plan, apply, etc) - opts.Variables = stubAllVariables(op.Variables, config.Module.Variables) + ret.PlanOpts.SetVariables = stubAllVariables(op.Variables, config.Module.Variables) } else { if tfeVariables != nil { if op.Variables == nil { @@ -121,16 +124,17 @@ func (b *Cloud) Context(op *backend.Operation) (*terraform.Context, statemgr.Ful if diags.HasErrors() { return nil, nil, diags } - opts.Variables = variables + ret.PlanOpts.SetVariables = variables } } tfCtx, ctxDiags := terraform.NewContext(&opts) diags = diags.Append(ctxDiags) + ret.Core = tfCtx log.Printf("[TRACE] cloud: finished building terraform.Context") - return tfCtx, stateMgr, diags + return ret, stateMgr, diags } func (b *Cloud) getRemoteWorkspaceName(localWorkspaceName string) string { diff --git a/internal/cloud/backend_context_test.go b/internal/cloud/backend_context_test.go index 264d10a71..683ad98eb 100644 --- a/internal/cloud/backend_context_test.go +++ b/internal/cloud/backend_context_test.go @@ -204,7 +204,7 @@ func TestRemoteContextWithVars(t *testing.T) { } b.client.Variables.Create(context.TODO(), workspaceID, *v) - _, _, diags := b.Context(op) + _, _, diags := b.LocalRun(op) if test.WantError != "" { if !diags.HasErrors() {