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