github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/application/removesaas.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package application 5 6 import ( 7 "github.com/juju/cmd" 8 "github.com/juju/errors" 9 "gopkg.in/juju/names.v2" 10 11 "github.com/juju/juju/api/application" 12 "github.com/juju/juju/apiserver/params" 13 jujucmd "github.com/juju/juju/cmd" 14 "github.com/juju/juju/cmd/juju/block" 15 "github.com/juju/juju/cmd/modelcmd" 16 ) 17 18 // NewRemoveSaasCommand returns a command which removes a consumed application. 19 func NewRemoveSaasCommand() cmd.Command { 20 cmd := &removeSaasCommand{} 21 cmd.newAPIFunc = func() (RemoveSaasAPI, error) { 22 root, err := cmd.NewAPIRoot() 23 if err != nil { 24 return nil, errors.Trace(err) 25 } 26 return application.NewClient(root), nil 27 } 28 return modelcmd.Wrap(cmd) 29 } 30 31 // removeSaasCommand causes an existing remote application to be destroyed. 32 type removeSaasCommand struct { 33 modelcmd.ModelCommandBase 34 SaasNames []string 35 36 newAPIFunc func() (RemoveSaasAPI, error) 37 } 38 39 var helpSummaryRmSaas = ` 40 Remove consumed applications (SAAS) from the model.`[1:] 41 42 var helpDetailsRmSaas = ` 43 Removing a consumed (SAAS) application will terminate any relations that 44 application has, potentially leaving any related local applications 45 in a non-functional state. 46 47 Examples: 48 juju remove-saas hosted-mysql 49 juju remove-saas -m test-model hosted-mariadb`[1:] 50 51 func (c *removeSaasCommand) Info() *cmd.Info { 52 return jujucmd.Info(&cmd.Info{ 53 Name: "remove-saas", 54 Args: "<saas-application-name> [<saas-application-name>...]", 55 Aliases: []string{"remove-consumed-application"}, 56 Purpose: helpSummaryRmSaas, 57 Doc: helpDetailsRmSaas, 58 }) 59 } 60 61 func (c *removeSaasCommand) Init(args []string) error { 62 if len(args) == 0 { 63 return errors.Errorf("no SAAS application names specified") 64 } 65 for _, arg := range args { 66 if !names.IsValidApplication(arg) { 67 return errors.Errorf("invalid SAAS application name %q", arg) 68 } 69 } 70 c.SaasNames = args 71 return nil 72 } 73 74 // RemoveSaasAPI defines the API methods that the remove-saas command uses. 75 type RemoveSaasAPI interface { 76 Close() error 77 BestAPIVersion() int 78 DestroyConsumedApplication(...string) ([]params.ErrorResult, error) 79 } 80 81 func (c *removeSaasCommand) Run(ctx *cmd.Context) error { 82 client, err := c.newAPIFunc() 83 if err != nil { 84 return err 85 } 86 defer client.Close() 87 88 if client.BestAPIVersion() < 5 { 89 return errors.New("remove-saas is not supported by this version of Juju") 90 } 91 return c.removeSaass(ctx, client) 92 } 93 94 func (c *removeSaasCommand) removeSaass( 95 ctx *cmd.Context, 96 client RemoveSaasAPI, 97 ) error { 98 results, err := client.DestroyConsumedApplication(c.SaasNames...) 99 if err := block.ProcessBlockedError(err, block.BlockRemove); err != nil { 100 return errors.Trace(err) 101 } 102 anyFailed := false 103 for i, name := range c.SaasNames { 104 result := results[i] 105 if result.Error != nil { 106 ctx.Infof("removing SAAS application %s failed: %s", name, result.Error) 107 anyFailed = true 108 continue 109 } 110 } 111 if anyFailed { 112 return cmd.ErrSilent 113 } 114 return nil 115 }