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

Fix for no json output of state locking actions for --json flag #32451

Merged
merged 11 commits into from
Feb 7, 2023
12 changes: 7 additions & 5 deletions internal/command/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,15 @@ func (c *ApplyCommand) Run(rawArgs []string) int {

// Prepare the backend, passing the plan file if present, and the
// backend-specific arguments
be, beDiags := c.PrepareBackend(planFile, args.State)
be, beDiags := c.PrepareBackend(planFile, args.State, args.ViewType)
diags = diags.Append(beDiags)
if diags.HasErrors() {
view.Diagnostics(diags)
return 1
}

// Build the operation request
opReq, opDiags := c.OperationRequest(be, view, planFile, args.Operation, args.AutoApprove)
opReq, opDiags := c.OperationRequest(be, view, args.ViewType, planFile, args.Operation, args.AutoApprove)
diags = diags.Append(opDiags)

// Collect variable value and add them to the operation request
Expand Down Expand Up @@ -191,7 +191,7 @@ func (c *ApplyCommand) LoadPlanFile(path string) (*planfile.Reader, tfdiags.Diag
return planFile, diags
}

func (c *ApplyCommand) PrepareBackend(planFile *planfile.Reader, args *arguments.State) (backend.Enhanced, tfdiags.Diagnostics) {
func (c *ApplyCommand) PrepareBackend(planFile *planfile.Reader, args *arguments.State, viewType arguments.ViewType) (backend.Enhanced, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics

// FIXME: we need to apply the state arguments to the meta object here
Expand All @@ -211,7 +211,8 @@ func (c *ApplyCommand) PrepareBackend(planFile *planfile.Reader, args *arguments
}

be, beDiags = c.Backend(&BackendOpts{
Config: backendConfig,
Config: backendConfig,
ViewType: viewType,
})
} else {
plan, err := planFile.ReadPlan()
Expand Down Expand Up @@ -245,6 +246,7 @@ func (c *ApplyCommand) PrepareBackend(planFile *planfile.Reader, args *arguments
func (c *ApplyCommand) OperationRequest(
be backend.Enhanced,
view views.Apply,
viewType arguments.ViewType,
planFile *planfile.Reader,
args *arguments.Operation,
autoApprove bool,
Expand All @@ -257,7 +259,7 @@ func (c *ApplyCommand) OperationRequest(
diags = diags.Append(c.providerDevOverrideRuntimeWarnings())

// Build the operation
opReq := c.Operation(be)
opReq := c.Operation(be, viewType)
opReq.AutoApprove = autoApprove
opReq.ConfigDir = "."
opReq.PlanMode = args.PlanMode
Expand Down
3 changes: 2 additions & 1 deletion internal/command/console.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/backend"
"github.com/hashicorp/terraform/internal/command/arguments"
"github.com/hashicorp/terraform/internal/repl"
"github.com/hashicorp/terraform/internal/terraform"
"github.com/hashicorp/terraform/internal/tfdiags"
Expand Down Expand Up @@ -75,7 +76,7 @@ func (c *ConsoleCommand) Run(args []string) int {
c.ignoreRemoteVersionConflict(b)

// Build the operation
opReq := c.Operation(b)
opReq := c.Operation(b, arguments.ViewHuman)
opReq.ConfigDir = configPath
opReq.ConfigLoader, err = c.initConfigLoader()
opReq.AllowUnsetVariables = true // we'll just evaluate them as unknown
Expand Down
3 changes: 2 additions & 1 deletion internal/command/graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"strings"

"github.com/hashicorp/terraform/internal/backend"
"github.com/hashicorp/terraform/internal/command/arguments"
"github.com/hashicorp/terraform/internal/dag"
"github.com/hashicorp/terraform/internal/plans"
"github.com/hashicorp/terraform/internal/plans/planfile"
Expand Down Expand Up @@ -91,7 +92,7 @@ func (c *GraphCommand) Run(args []string) int {
c.ignoreRemoteVersionConflict(b)

// Build the operation
opReq := c.Operation(b)
opReq := c.Operation(b, arguments.ViewHuman)
opReq.ConfigDir = configPath
opReq.ConfigLoader, err = c.initConfigLoader()
opReq.PlanFile = planFile
Expand Down
2 changes: 1 addition & 1 deletion internal/command/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ func (c *ImportCommand) Run(args []string) int {
}

// Build the operation
opReq := c.Operation(b)
opReq := c.Operation(b, arguments.ViewHuman)
opReq.ConfigDir = configPath
opReq.ConfigLoader, err = c.initConfigLoader()
if err != nil {
Expand Down
42 changes: 36 additions & 6 deletions internal/command/meta_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ type BackendOpts struct {
// ForceLocal will force a purely local backend, including state.
// You probably don't want to set this.
ForceLocal bool

// ViewType will set console output format for the
// initialization operation (JSON or human-readable).
ViewType arguments.ViewType
}

// BackendWithRemoteTerraformVersion is a shared interface between the 'remote' and 'cloud' backends
Expand Down Expand Up @@ -391,7 +395,7 @@ func (m *Meta) backendCLIOpts() (*backend.CLIOpts, error) {
// This prepares the operation. After calling this, the caller is expected
// to modify fields of the operation such as Sequence to specify what will
// be called.
func (m *Meta) Operation(b backend.Backend) *backend.Operation {
func (m *Meta) Operation(b backend.Backend, vt arguments.ViewType) *backend.Operation {
schema := b.ConfigSchema()
workspace, err := m.Workspace()
if err != nil {
Expand All @@ -411,7 +415,7 @@ func (m *Meta) Operation(b backend.Backend) *backend.Operation {

stateLocker := clistate.NewNoopLocker()
if m.stateLock {
view := views.NewStateLocker(arguments.ViewHuman, m.View)
view := views.NewStateLocker(vt, m.View)
stateLocker = clistate.NewLocker(m.stateLockTimeout, view)
}

Expand Down Expand Up @@ -611,7 +615,7 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, tfdiags.Di
return nil, diags
}

return m.backend_c_r_S(c, cHash, sMgr, true)
return m.backend_c_r_S(c, cHash, sMgr, true, opts)

// Configuring a backend for the first time or -reconfigure flag was used
case c != nil && s.Backend.Empty():
Expand Down Expand Up @@ -845,9 +849,18 @@ func (m *Meta) backendFromState() (backend.Backend, tfdiags.Diagnostics) {
//-------------------------------------------------------------------

// Unconfiguring a backend (moving from backend => local).
func (m *Meta) backend_c_r_S(c *configs.Backend, cHash int, sMgr *clistate.LocalState, output bool) (backend.Backend, tfdiags.Diagnostics) {
func (m *Meta) backend_c_r_S(
c *configs.Backend, cHash int, sMgr *clistate.LocalState, output bool, opts *BackendOpts) (backend.Backend, tfdiags.Diagnostics) {

var diags tfdiags.Diagnostics

vt := arguments.ViewJSON
// Set default viewtype if none was set as the StateLocker needs to know exactly
// what viewType we want to have.
if opts == nil || opts.ViewType != vt {
vt = arguments.ViewHuman
}

s := sMgr.State()

cloudMode := cloud.DetectConfigChangeType(s.Backend, c, false)
Expand Down Expand Up @@ -885,6 +898,7 @@ func (m *Meta) backend_c_r_S(c *configs.Backend, cHash int, sMgr *clistate.Local
DestinationType: "local",
Source: b,
Destination: localB,
ViewType: vt,
})
if err != nil {
diags = diags.Append(err)
Expand Down Expand Up @@ -916,6 +930,13 @@ func (m *Meta) backend_c_r_S(c *configs.Backend, cHash int, sMgr *clistate.Local
func (m *Meta) backend_C_r_s(c *configs.Backend, cHash int, sMgr *clistate.LocalState, opts *BackendOpts) (backend.Backend, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics

vt := arguments.ViewJSON
// Set default viewtype if none was set as the StateLocker needs to know exactly
// what viewType we want to have.
if opts == nil || opts.ViewType != vt {
vt = arguments.ViewHuman
}

// Grab a purely local backend to get the local state if it exists
localB, localBDiags := m.Backend(&BackendOpts{ForceLocal: true, Init: true})
if localBDiags.HasErrors() {
Expand Down Expand Up @@ -970,6 +991,7 @@ func (m *Meta) backend_C_r_s(c *configs.Backend, cHash int, sMgr *clistate.Local
DestinationType: c.Type,
Source: localB,
Destination: b,
ViewType: vt,
})
if err != nil {
diags = diags.Append(err)
Expand Down Expand Up @@ -1007,7 +1029,7 @@ func (m *Meta) backend_C_r_s(c *configs.Backend, cHash int, sMgr *clistate.Local
}

if m.stateLock {
view := views.NewStateLocker(arguments.ViewHuman, m.View)
view := views.NewStateLocker(vt, m.View)
stateLocker := clistate.NewLocker(m.stateLockTimeout, view)
if err := stateLocker.Lock(sMgr, "backend from plan"); err != nil {
diags = diags.Append(fmt.Errorf("Error locking state: %s", err))
Expand Down Expand Up @@ -1077,6 +1099,13 @@ func (m *Meta) backend_C_r_s(c *configs.Backend, cHash int, sMgr *clistate.Local
func (m *Meta) backend_C_r_S_changed(c *configs.Backend, cHash int, sMgr *clistate.LocalState, output bool, opts *BackendOpts) (backend.Backend, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics

vt := arguments.ViewJSON
// Set default viewtype if none was set as the StateLocker needs to know exactly
// what viewType we want to have.
if opts == nil || opts.ViewType != vt {
vt = arguments.ViewHuman
}

// Get the old state
s := sMgr.State()

Expand Down Expand Up @@ -1136,14 +1165,15 @@ func (m *Meta) backend_C_r_S_changed(c *configs.Backend, cHash int, sMgr *clista
DestinationType: c.Type,
Source: oldB,
Destination: b,
ViewType: vt,
})
if err != nil {
diags = diags.Append(err)
return nil, diags
}

if m.stateLock {
view := views.NewStateLocker(arguments.ViewHuman, m.View)
view := views.NewStateLocker(vt, m.View)
stateLocker := clistate.NewLocker(m.stateLockTimeout, view)
if err := stateLocker.Lock(sMgr, "backend from plan"); err != nil {
diags = diags.Append(fmt.Errorf("Error locking state: %s", err))
Expand Down
10 changes: 8 additions & 2 deletions internal/command/meta_backend_migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
type backendMigrateOpts struct {
SourceType, DestinationType string
Source, Destination backend.Backend
ViewType arguments.ViewType

// Fields below are set internally when migrate is called

Expand Down Expand Up @@ -339,8 +340,13 @@ func (m *Meta) backendMigrateState_s_s(opts *backendMigrateOpts) error {

if m.stateLock {
lockCtx := context.Background()

view := views.NewStateLocker(arguments.ViewHuman, m.View)
vt := arguments.ViewJSON
// Set default viewtype if none was set as the StateLocker needs to know exactly
// what viewType we want to have.
if opts == nil || opts.ViewType != vt {
vt = arguments.ViewHuman
}
view := views.NewStateLocker(vt, m.View)
locker := clistate.NewLocker(m.stateLockTimeout, view)

lockerSource := locker.WithContext(lockCtx)
Expand Down
12 changes: 7 additions & 5 deletions internal/command/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,15 @@ func (c *PlanCommand) Run(rawArgs []string) int {
diags = diags.Append(c.providerDevOverrideRuntimeWarnings())

// Prepare the backend with the backend-specific arguments
be, beDiags := c.PrepareBackend(args.State)
be, beDiags := c.PrepareBackend(args.State, args.ViewType)
diags = diags.Append(beDiags)
if diags.HasErrors() {
view.Diagnostics(diags)
return 1
}

// Build the operation request
opReq, opDiags := c.OperationRequest(be, view, args.Operation, args.OutPath)
opReq, opDiags := c.OperationRequest(be, view, args.ViewType, args.Operation, args.OutPath)
diags = diags.Append(opDiags)
if diags.HasErrors() {
view.Diagnostics(diags)
Expand Down Expand Up @@ -110,7 +110,7 @@ func (c *PlanCommand) Run(rawArgs []string) int {
return op.Result.ExitStatus()
}

func (c *PlanCommand) PrepareBackend(args *arguments.State) (backend.Enhanced, tfdiags.Diagnostics) {
func (c *PlanCommand) PrepareBackend(args *arguments.State, viewType arguments.ViewType) (backend.Enhanced, tfdiags.Diagnostics) {
// FIXME: we need to apply the state arguments to the meta object here
// because they are later used when initializing the backend. Carving a
// path to pass these arguments to the functions that need them is
Expand All @@ -124,7 +124,8 @@ func (c *PlanCommand) PrepareBackend(args *arguments.State) (backend.Enhanced, t

// Load the backend
be, beDiags := c.Backend(&BackendOpts{
Config: backendConfig,
Config: backendConfig,
ViewType: viewType,
})
diags = diags.Append(beDiags)
if beDiags.HasErrors() {
Expand All @@ -137,13 +138,14 @@ func (c *PlanCommand) PrepareBackend(args *arguments.State) (backend.Enhanced, t
func (c *PlanCommand) OperationRequest(
be backend.Enhanced,
view views.Plan,
viewType arguments.ViewType,
args *arguments.Operation,
planOutPath string,
) (*backend.Operation, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics

// Build the operation
opReq := c.Operation(be)
opReq := c.Operation(be, viewType)
opReq.ConfigDir = "."
opReq.PlanMode = args.PlanMode
opReq.Hooks = view.Hooks()
Expand Down
3 changes: 2 additions & 1 deletion internal/command/providers_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os"

"github.com/hashicorp/terraform/internal/backend"
"github.com/hashicorp/terraform/internal/command/arguments"
"github.com/hashicorp/terraform/internal/command/jsonprovider"
"github.com/hashicorp/terraform/internal/tfdiags"
)
Expand Down Expand Up @@ -78,7 +79,7 @@ func (c *ProvidersSchemaCommand) Run(args []string) int {
}

// Build the operation
opReq := c.Operation(b)
opReq := c.Operation(b, arguments.ViewJSON)
opReq.ConfigDir = cwd
opReq.ConfigLoader, err = c.initConfigLoader()
opReq.AllowUnsetVariables = true
Expand Down
13 changes: 7 additions & 6 deletions internal/command/refresh.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,15 @@ func (c *RefreshCommand) Run(rawArgs []string) int {
c.Meta.parallelism = args.Operation.Parallelism

// Prepare the backend with the backend-specific arguments
be, beDiags := c.PrepareBackend(args.State)
be, beDiags := c.PrepareBackend(args.State, args.ViewType)
diags = diags.Append(beDiags)
if diags.HasErrors() {
view.Diagnostics(diags)
return 1
}

// Build the operation request
opReq, opDiags := c.OperationRequest(be, view, args.Operation)
opReq, opDiags := c.OperationRequest(be, view, args.ViewType, args.Operation)
diags = diags.Append(opDiags)
if diags.HasErrors() {
view.Diagnostics(diags)
Expand Down Expand Up @@ -107,7 +107,7 @@ func (c *RefreshCommand) Run(rawArgs []string) int {
return op.Result.ExitStatus()
}

func (c *RefreshCommand) PrepareBackend(args *arguments.State) (backend.Enhanced, tfdiags.Diagnostics) {
func (c *RefreshCommand) PrepareBackend(args *arguments.State, viewType arguments.ViewType) (backend.Enhanced, tfdiags.Diagnostics) {
// FIXME: we need to apply the state arguments to the meta object here
// because they are later used when initializing the backend. Carving a
// path to pass these arguments to the functions that need them is
Expand All @@ -121,7 +121,8 @@ func (c *RefreshCommand) PrepareBackend(args *arguments.State) (backend.Enhanced

// Load the backend
be, beDiags := c.Backend(&BackendOpts{
Config: backendConfig,
Config: backendConfig,
ViewType: viewType,
})
diags = diags.Append(beDiags)
if beDiags.HasErrors() {
Expand All @@ -131,12 +132,12 @@ func (c *RefreshCommand) PrepareBackend(args *arguments.State) (backend.Enhanced
return be, diags
}

func (c *RefreshCommand) OperationRequest(be backend.Enhanced, view views.Refresh, args *arguments.Operation,
func (c *RefreshCommand) OperationRequest(be backend.Enhanced, view views.Refresh, viewType arguments.ViewType, args *arguments.Operation,
) (*backend.Operation, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics

// Build the operation
opReq := c.Operation(be)
opReq := c.Operation(be, viewType)
opReq.ConfigDir = "."
opReq.Hooks = view.Hooks()
opReq.Targets = args.Targets
Expand Down
3 changes: 2 additions & 1 deletion internal/command/state_show.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/backend"
"github.com/hashicorp/terraform/internal/command/arguments"
"github.com/hashicorp/terraform/internal/command/format"
"github.com/hashicorp/terraform/internal/states"
"github.com/mitchellh/cli"
Expand Down Expand Up @@ -71,7 +72,7 @@ func (c *StateShowCommand) Run(args []string) int {
}

// Build the operation (required to get the schemas)
opReq := c.Operation(b)
opReq := c.Operation(b, arguments.ViewHuman)
opReq.AllowUnsetVariables = true
opReq.ConfigDir = cwd

Expand Down