github.com/meteor/terraform@v0.6.15-0.20210412225145-79ec4bc057c6/command/env_delete.go (about)

     1  package command
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"github.com/hashicorp/terraform/command/clistate"
     9  	"github.com/hashicorp/terraform/state"
    10  	"github.com/mitchellh/cli"
    11  )
    12  
    13  type EnvDeleteCommand struct {
    14  	Meta
    15  }
    16  
    17  func (c *EnvDeleteCommand) Run(args []string) int {
    18  	args = c.Meta.process(args, true)
    19  
    20  	force := false
    21  	cmdFlags := c.Meta.flagSet("env")
    22  	cmdFlags.BoolVar(&force, "force", false, "force removal of a non-empty environment")
    23  	cmdFlags.Usage = func() { c.Ui.Error(c.Help()) }
    24  	if err := cmdFlags.Parse(args); err != nil {
    25  		return 1
    26  	}
    27  	args = cmdFlags.Args()
    28  	if len(args) == 0 {
    29  		c.Ui.Error("expected NAME.\n")
    30  		return cli.RunResultHelp
    31  	}
    32  
    33  	delEnv := args[0]
    34  
    35  	if !validEnvName(delEnv) {
    36  		c.Ui.Error(fmt.Sprintf(envInvalidName, delEnv))
    37  		return 1
    38  	}
    39  
    40  	configPath, err := ModulePath(args[1:])
    41  	if err != nil {
    42  		c.Ui.Error(err.Error())
    43  		return 1
    44  	}
    45  
    46  	// Load the backend
    47  	b, err := c.Backend(&BackendOpts{ConfigPath: configPath})
    48  	if err != nil {
    49  		c.Ui.Error(fmt.Sprintf("Failed to load backend: %s", err))
    50  		return 1
    51  	}
    52  
    53  	states, err := b.States()
    54  	if err != nil {
    55  		c.Ui.Error(err.Error())
    56  		return 1
    57  	}
    58  
    59  	exists := false
    60  	for _, s := range states {
    61  		if delEnv == s {
    62  			exists = true
    63  			break
    64  		}
    65  	}
    66  
    67  	if !exists {
    68  		c.Ui.Error(fmt.Sprintf(strings.TrimSpace(envDoesNotExist), delEnv))
    69  		return 1
    70  	}
    71  
    72  	if delEnv == c.Env() {
    73  		c.Ui.Error(fmt.Sprintf(strings.TrimSpace(envDelCurrent), delEnv))
    74  		return 1
    75  	}
    76  
    77  	// we need the actual state to see if it's empty
    78  	sMgr, err := b.State(delEnv)
    79  	if err != nil {
    80  		c.Ui.Error(err.Error())
    81  		return 1
    82  	}
    83  
    84  	if err := sMgr.RefreshState(); err != nil {
    85  		c.Ui.Error(err.Error())
    86  		return 1
    87  	}
    88  
    89  	hasResources := sMgr.State().HasResources()
    90  
    91  	if hasResources && !force {
    92  		c.Ui.Error(fmt.Sprintf(strings.TrimSpace(envNotEmpty), delEnv))
    93  		return 1
    94  	}
    95  
    96  	if c.stateLock {
    97  		lockCtx, cancel := context.WithTimeout(context.Background(), c.stateLockTimeout)
    98  		defer cancel()
    99  
   100  		// Lock the state if we can
   101  		lockInfo := state.NewLockInfo()
   102  		lockInfo.Operation = "env delete"
   103  		lockID, err := clistate.Lock(lockCtx, sMgr, lockInfo, c.Ui, c.Colorize())
   104  		if err != nil {
   105  			c.Ui.Error(fmt.Sprintf("Error locking state: %s", err))
   106  			return 1
   107  		}
   108  		defer clistate.Unlock(sMgr, lockID, c.Ui, c.Colorize())
   109  	}
   110  
   111  	err = b.DeleteState(delEnv)
   112  	if err != nil {
   113  		c.Ui.Error(err.Error())
   114  		return 1
   115  	}
   116  
   117  	c.Ui.Output(
   118  		c.Colorize().Color(
   119  			fmt.Sprintf(envDeleted, delEnv),
   120  		),
   121  	)
   122  
   123  	if hasResources {
   124  		c.Ui.Output(
   125  			c.Colorize().Color(
   126  				fmt.Sprintf(envWarnNotEmpty, delEnv),
   127  			),
   128  		)
   129  	}
   130  
   131  	return 0
   132  }
   133  func (c *EnvDeleteCommand) Help() string {
   134  	helpText := `
   135  Usage: terraform env delete [OPTIONS] NAME [DIR]
   136  
   137    Delete a Terraform environment
   138  
   139  
   140  Options:
   141  
   142      -force    remove a non-empty environment.
   143  `
   144  	return strings.TrimSpace(helpText)
   145  }
   146  
   147  func (c *EnvDeleteCommand) Synopsis() string {
   148  	return "Delete an environment"
   149  }