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