github.com/andrewrynhard/terraform@v0.9.5-0.20170502003928-8d286b83eae4/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 }