mirror of
https://github.com/opentffoundation/opentf.git
synced 2025-12-20 10:19:27 -05:00
165 lines
4.8 KiB
Go
165 lines
4.8 KiB
Go
// Copyright (c) The OpenTofu Authors
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
// Copyright (c) 2023 HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package arguments
|
|
|
|
import (
|
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
|
)
|
|
|
|
// Show represents the command-line arguments for the show command.
|
|
type Show struct {
|
|
// TargetType and TargetArg together describe the object that was
|
|
// requested to be shown.
|
|
//
|
|
// The meaning of TargetArg varies depending on TargetType. Refer to
|
|
// the documentation for each [ShowTargetType] constant for details.
|
|
TargetType ShowTargetType
|
|
TargetArg string
|
|
|
|
// ViewType specifies which output format to use: human, JSON, or "raw".
|
|
ViewType ViewType
|
|
|
|
Vars *Vars
|
|
|
|
// ShowSensitive is used to display the value of variables marked as sensitive.
|
|
ShowSensitive bool
|
|
}
|
|
|
|
// ShowTargetType represents the type of object that is requested to be
|
|
// shown by the "tofu show" command.
|
|
type ShowTargetType int
|
|
|
|
//go:generate go run golang.org/x/tools/cmd/stringer -type=ShowTargetType
|
|
const (
|
|
// ShowUnknownType is the zero value of [ShowTargetType], and represents
|
|
// that the target type is ambiguous and so must be inferred by the
|
|
// caller based on the [Show.TargetArg] value.
|
|
ShowUnknownType ShowTargetType = iota
|
|
|
|
// ShowState represents a request to show the latest state snapshot.
|
|
//
|
|
// This target type does not use [Show.TargetArg].
|
|
ShowState
|
|
|
|
// ShowPlan represents a request to show a plan loaded from a saved
|
|
// plan file.
|
|
//
|
|
// For this target type, [Show.TargetArg] is the plan file to load.
|
|
ShowPlan
|
|
|
|
// ShowConfig represents a request to show the current configuration.
|
|
//
|
|
// This target type does not use [Show.TargetArg].
|
|
ShowConfig
|
|
)
|
|
|
|
// ParseShow processes CLI arguments, returning a Show value and errors.
|
|
// If errors are encountered, a Show value is still returned representing
|
|
// the best effort interpretation of the arguments.
|
|
func ParseShow(args []string) (*Show, tfdiags.Diagnostics) {
|
|
var diags tfdiags.Diagnostics
|
|
show := &Show{
|
|
Vars: &Vars{},
|
|
}
|
|
|
|
var jsonOutput bool
|
|
var stateTarget bool
|
|
var planTarget string
|
|
var configTarget bool
|
|
cmdFlags := extendedFlagSet("show", nil, nil, show.Vars)
|
|
cmdFlags.BoolVar(&jsonOutput, "json", false, "json")
|
|
cmdFlags.BoolVar(&show.ShowSensitive, "show-sensitive", false, "displays sensitive values")
|
|
cmdFlags.BoolVar(&stateTarget, "state", false, "show the latest state snapshot")
|
|
cmdFlags.StringVar(&planTarget, "plan", "", "show the plan from a saved plan file")
|
|
cmdFlags.BoolVar(&configTarget, "config", false, "show the current configuration")
|
|
|
|
if err := cmdFlags.Parse(args); err != nil {
|
|
diags = diags.Append(tfdiags.Sourceless(
|
|
tfdiags.Error,
|
|
"Failed to parse command-line options",
|
|
err.Error(),
|
|
))
|
|
}
|
|
|
|
// If -config is specified, -json is required
|
|
if configTarget && !jsonOutput {
|
|
diags = diags.Append(tfdiags.Sourceless(
|
|
tfdiags.Error,
|
|
"JSON output required for configuration",
|
|
"The -config option requires -json to be specified.",
|
|
))
|
|
return show, diags
|
|
}
|
|
|
|
switch {
|
|
case jsonOutput:
|
|
show.ViewType = ViewJSON
|
|
default:
|
|
show.ViewType = ViewHuman
|
|
}
|
|
|
|
if planTarget == "" && !stateTarget && !configTarget {
|
|
// If none of the target type options was provided then we're
|
|
// in the legacy mode where the target type is implied by
|
|
// the number of arguments.
|
|
args = cmdFlags.Args()
|
|
switch len(args) {
|
|
case 0:
|
|
show.TargetType = ShowState
|
|
show.TargetArg = ""
|
|
case 1:
|
|
// This case is ambiguous: the argument could be either
|
|
// a saved plan file or a local state snapshot such as
|
|
// the output from "tofu state pull". The caller will need
|
|
// to probe TargetArg to decide which it is.
|
|
show.TargetType = ShowUnknownType
|
|
show.TargetArg = args[0]
|
|
default:
|
|
diags = diags.Append(tfdiags.Sourceless(
|
|
tfdiags.Error,
|
|
"Too many command line arguments",
|
|
"Expected at most one positional argument for the legacy positional argument mode.",
|
|
))
|
|
}
|
|
return show, diags
|
|
}
|
|
|
|
// The following handles the modern mode where the target type is
|
|
// chosen based on which target type option was used.
|
|
if len(cmdFlags.Args()) != 0 {
|
|
diags = diags.Append(tfdiags.Sourceless(
|
|
tfdiags.Error,
|
|
"Unexpected command line arguments",
|
|
"This command does not expect any positional arguments when using a target-selection option.",
|
|
))
|
|
return show, diags
|
|
}
|
|
targetTypes := 0
|
|
if stateTarget {
|
|
targetTypes++
|
|
show.TargetType = ShowState
|
|
show.TargetArg = ""
|
|
}
|
|
if planTarget != "" {
|
|
targetTypes++
|
|
show.TargetType = ShowPlan
|
|
show.TargetArg = planTarget
|
|
}
|
|
if configTarget {
|
|
targetTypes++
|
|
show.TargetType = ShowConfig
|
|
show.TargetArg = ""
|
|
}
|
|
if targetTypes != 1 {
|
|
diags = diags.Append(tfdiags.Sourceless(
|
|
tfdiags.Error,
|
|
"Conflicting object types to show",
|
|
"The -state, -plan=FILENAME, and -config options are mutually-exclusive, to specify which kind of object to show.",
|
|
))
|
|
}
|
|
return show, diags
|
|
}
|