github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/cmd/juju/destroyenvironment.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package main 5 6 import ( 7 "bufio" 8 "errors" 9 "fmt" 10 "io" 11 "strings" 12 13 "launchpad.net/gnuflag" 14 15 "launchpad.net/juju-core/cmd" 16 "launchpad.net/juju-core/environs" 17 "launchpad.net/juju-core/environs/configstore" 18 "launchpad.net/juju-core/juju" 19 "launchpad.net/juju-core/state/api" 20 "launchpad.net/juju-core/state/api/params" 21 ) 22 23 var NoEnvironmentError = errors.New("no environment specified") 24 var DoubleEnvironmentError = errors.New("you cannot supply both -e and the envname as a positional argument") 25 26 // DestroyEnvironmentCommand destroys an environment. 27 type DestroyEnvironmentCommand struct { 28 cmd.CommandBase 29 envName string 30 assumeYes bool 31 force bool 32 } 33 34 func (c *DestroyEnvironmentCommand) Info() *cmd.Info { 35 return &cmd.Info{ 36 Name: "destroy-environment", 37 Args: "<environment name>", 38 Purpose: "terminate all machines and other associated resources for an environment", 39 } 40 } 41 42 func (c *DestroyEnvironmentCommand) SetFlags(f *gnuflag.FlagSet) { 43 f.BoolVar(&c.assumeYes, "y", false, "Do not ask for confirmation") 44 f.BoolVar(&c.assumeYes, "yes", false, "") 45 f.BoolVar(&c.force, "force", false, "Forcefully destroy the environment, directly through the environment provider") 46 f.StringVar(&c.envName, "e", "", "juju environment to operate in") 47 f.StringVar(&c.envName, "environment", "", "juju environment to operate in") 48 } 49 50 func (c *DestroyEnvironmentCommand) Run(ctx *cmd.Context) (result error) { 51 store, err := configstore.Default() 52 if err != nil { 53 return fmt.Errorf("cannot open environment info storage: %v", err) 54 } 55 environ, err := environs.NewFromName(c.envName, store) 56 if err != nil { 57 return err 58 } 59 if !c.assumeYes { 60 fmt.Fprintf(ctx.Stdout, destroyEnvMsg, environ.Name(), environ.Config().Type()) 61 62 scanner := bufio.NewScanner(ctx.Stdin) 63 scanner.Scan() 64 err := scanner.Err() 65 if err != nil && err != io.EOF { 66 return fmt.Errorf("Environment destruction aborted: %s", err) 67 } 68 answer := strings.ToLower(scanner.Text()) 69 if answer != "y" && answer != "yes" { 70 return errors.New("Environment destruction aborted") 71 } 72 } 73 // If --force is supplied, then don't attempt to use the API. 74 // This is necessary to destroy broken environments, where the 75 // API server is inaccessible or faulty. 76 if !c.force { 77 defer func() { 78 if result == nil { 79 return 80 } 81 logger.Errorf(`failed to destroy environment %q 82 83 If the environment is unusable, then you may run 84 85 juju destroy-environment --force 86 87 to forcefully destroy the environment. Upon doing so, review 88 your environment provider console for any resources that need 89 to be cleaned up. 90 91 `, c.envName) 92 }() 93 conn, err := juju.NewAPIConn(environ, api.DefaultDialOpts()) 94 if err != nil { 95 return err 96 } 97 defer conn.Close() 98 err = conn.State.Client().DestroyEnvironment() 99 if err != nil && !params.IsCodeNotImplemented(err) { 100 return fmt.Errorf("destroying environment: %v", err) 101 } 102 } 103 return environs.Destroy(environ, store) 104 } 105 106 func (c *DestroyEnvironmentCommand) Init(args []string) error { 107 if c.envName != "" { 108 logger.Warningf("-e/--environment flag is deprecated in 1.18, " + 109 "please supply environment as a positional parameter") 110 // They supplied the -e flag 111 if len(args) == 0 { 112 // We're happy, we have enough information 113 return nil 114 } 115 // You can't supply -e ENV and ENV as a positional argument 116 return DoubleEnvironmentError 117 } else { 118 // No -e flag means they must supply the environment positionally 119 switch len(args) { 120 case 0: 121 return NoEnvironmentError 122 case 1: 123 c.envName = args[0] 124 return nil 125 default: 126 return cmd.CheckEmpty(args[1:]) 127 } 128 } 129 } 130 131 var destroyEnvMsg = ` 132 WARNING! this command will destroy the %q environment (type: %s) 133 This includes all machines, services, data and other resources. 134 135 Continue [y/N]? `[1:]