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  }