github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/command/state_list.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package command
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  
    10  	"github.com/mitchellh/cli"
    11  	"github.com/terramate-io/tf/addrs"
    12  	"github.com/terramate-io/tf/states"
    13  	"github.com/terramate-io/tf/tfdiags"
    14  )
    15  
    16  // StateListCommand is a Command implementation that lists the resources
    17  // within a state file.
    18  type StateListCommand struct {
    19  	Meta
    20  	StateMeta
    21  }
    22  
    23  func (c *StateListCommand) Run(args []string) int {
    24  	args = c.Meta.process(args)
    25  	var statePath string
    26  	cmdFlags := c.Meta.defaultFlagSet("state list")
    27  	cmdFlags.StringVar(&statePath, "state", "", "path")
    28  	lookupId := cmdFlags.String("id", "", "Restrict output to paths with a resource having the specified ID.")
    29  	if err := cmdFlags.Parse(args); err != nil {
    30  		c.Ui.Error(fmt.Sprintf("Error parsing command-line flags: %s\n", err.Error()))
    31  		return cli.RunResultHelp
    32  	}
    33  	args = cmdFlags.Args()
    34  
    35  	if statePath != "" {
    36  		c.Meta.statePath = statePath
    37  	}
    38  
    39  	// Load the backend
    40  	b, backendDiags := c.Backend(nil)
    41  	if backendDiags.HasErrors() {
    42  		c.showDiagnostics(backendDiags)
    43  		return 1
    44  	}
    45  
    46  	// This is a read-only command
    47  	c.ignoreRemoteVersionConflict(b)
    48  
    49  	// Get the state
    50  	env, err := c.Workspace()
    51  	if err != nil {
    52  		c.Ui.Error(fmt.Sprintf("Error selecting workspace: %s", err))
    53  		return 1
    54  	}
    55  	stateMgr, err := b.StateMgr(env)
    56  	if err != nil {
    57  		c.Ui.Error(fmt.Sprintf(errStateLoadingState, err))
    58  		return 1
    59  	}
    60  	if err := stateMgr.RefreshState(); err != nil {
    61  		c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))
    62  		return 1
    63  	}
    64  
    65  	state := stateMgr.State()
    66  	if state == nil {
    67  		c.Ui.Error(errStateNotFound)
    68  		return 1
    69  	}
    70  
    71  	var addrs []addrs.AbsResourceInstance
    72  	var diags tfdiags.Diagnostics
    73  	if len(args) == 0 {
    74  		addrs, diags = c.lookupAllResourceInstanceAddrs(state)
    75  	} else {
    76  		addrs, diags = c.lookupResourceInstanceAddrs(state, args...)
    77  	}
    78  	if diags.HasErrors() {
    79  		c.showDiagnostics(diags)
    80  		return 1
    81  	}
    82  
    83  	for _, addr := range addrs {
    84  		if is := state.ResourceInstance(addr); is != nil {
    85  			if *lookupId == "" || *lookupId == states.LegacyInstanceObjectID(is.Current) {
    86  				c.Ui.Output(addr.String())
    87  			}
    88  		}
    89  	}
    90  
    91  	c.showDiagnostics(diags)
    92  
    93  	return 0
    94  }
    95  
    96  func (c *StateListCommand) Help() string {
    97  	helpText := `
    98  Usage: terraform [global options] state list [options] [address...]
    99  
   100    List resources in the Terraform state.
   101  
   102    This command lists resource instances in the Terraform state. The address
   103    argument can be used to filter the instances by resource or module. If
   104    no pattern is given, all resource instances are listed.
   105  
   106    The addresses must either be module addresses or absolute resource
   107    addresses, such as:
   108        aws_instance.example
   109        module.example
   110        module.example.module.child
   111        module.example.aws_instance.example
   112  
   113    An error will be returned if any of the resources or modules given as
   114    filter addresses do not exist in the state.
   115  
   116  Options:
   117  
   118    -state=statefile    Path to a Terraform state file to use to look
   119                        up Terraform-managed resources. By default, Terraform
   120                        will consult the state of the currently-selected
   121                        workspace.
   122  
   123    -id=ID              Filters the results to include only instances whose
   124                        resource types have an attribute named "id" whose value
   125                        equals the given id string.
   126  
   127  `
   128  	return strings.TrimSpace(helpText)
   129  }
   130  
   131  func (c *StateListCommand) Synopsis() string {
   132  	return "List resources in the state"
   133  }
   134  
   135  const errStateLoadingState = `Error loading the state: %[1]s
   136  
   137  Please ensure that your Terraform state exists and that you've
   138  configured it properly. You can use the "-state" flag to point
   139  Terraform at another state file.`
   140  
   141  const errStateNotFound = `No state file was found!
   142  
   143  State management commands require a state file. Run this command
   144  in a directory where Terraform has been run or use the -state flag
   145  to point the command to a specific state location.`