github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/cmd/juju/user/remove.go (about)

     1  // Copyright 2012-2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  package user
     4  
     5  import (
     6  	"bufio"
     7  	"fmt"
     8  	"io"
     9  	"strings"
    10  
    11  	"github.com/juju/cmd"
    12  	"github.com/juju/errors"
    13  	"github.com/juju/gnuflag"
    14  
    15  	"github.com/juju/juju/cmd/juju/block"
    16  	"github.com/juju/juju/cmd/modelcmd"
    17  )
    18  
    19  var removeUsageSummary = `
    20  Deletes a Juju user from a controller.`[1:]
    21  
    22  // TODO(redir): Get updated copy for add-user as that may need updates, too.
    23  var removeUsageDetails = `
    24  This removes a user permanently.
    25  
    26  By default, the controller is the current controller.
    27  
    28  Examples:
    29      juju remove-user bob
    30      juju remove-user bob --yes
    31  
    32  See also: 
    33      unregister
    34      revoke
    35      show-user
    36      list-users
    37      switch-user
    38      disable-user
    39      enable-user
    40      change-user-password`[1:]
    41  
    42  var removeUserMsg = `
    43  WARNING! This command will remove the user %q from the %q controller.
    44  
    45  Continue (y/N)? `[1:]
    46  
    47  // RemoveUserAPI defines the usermanager API methods that the remove command
    48  // uses.
    49  type RemoveUserAPI interface {
    50  	RemoveUser(username string) error
    51  	Close() error
    52  }
    53  
    54  // NewRemoveCommand constructs a wrapped unexported removeCommand.
    55  func NewRemoveCommand() cmd.Command {
    56  	return modelcmd.WrapController(&removeCommand{})
    57  }
    58  
    59  // removeCommand deletes a user from a Juju controller.
    60  type removeCommand struct {
    61  	modelcmd.ControllerCommandBase
    62  	api           RemoveUserAPI
    63  	UserName      string
    64  	ConfirmDelete bool
    65  }
    66  
    67  // SetFlags adds command specific flags and then returns the flagset.
    68  func (c *removeCommand) SetFlags(f *gnuflag.FlagSet) {
    69  	c.ControllerCommandBase.SetFlags(f)
    70  	f.BoolVar(&c.ConfirmDelete, "y", false, "Confirm deletion of the user")
    71  	f.BoolVar(&c.ConfirmDelete, "yes", false, "")
    72  }
    73  
    74  // Info implements Command.Info.
    75  func (c *removeCommand) Info() *cmd.Info {
    76  	return &cmd.Info{
    77  		Name:    "remove-user",
    78  		Args:    "<user name>",
    79  		Purpose: removeUsageSummary,
    80  		Doc:     removeUsageDetails,
    81  	}
    82  }
    83  
    84  // Init implements Command.Init.
    85  func (c *removeCommand) Init(args []string) error {
    86  	if len(args) == 0 {
    87  		return errors.Errorf("no username supplied")
    88  	}
    89  	c.UserName = args[0]
    90  	return cmd.CheckEmpty(args[1:])
    91  }
    92  
    93  // Run implements Command.Run.
    94  func (c *removeCommand) Run(ctx *cmd.Context) error {
    95  	api := c.api // This is for testing.
    96  
    97  	if api == nil { // The real McCoy.
    98  		var err error
    99  		api, err = c.NewUserManagerAPIClient()
   100  		if err != nil {
   101  			return errors.Trace(err)
   102  		}
   103  		defer api.Close()
   104  	}
   105  
   106  	// Confirm deletion if the user didn't specify -y/--yes in the command.
   107  	if !c.ConfirmDelete {
   108  		if err := confirmDelete(ctx, c.ControllerName(), c.UserName); err != nil {
   109  			return err
   110  		}
   111  	}
   112  
   113  	err := api.RemoveUser(c.UserName)
   114  	if err != nil {
   115  		return block.ProcessBlockedError(err, block.BlockChange)
   116  	}
   117  
   118  	fmt.Fprintf(ctx.Stdout, "User %q removed\n", c.UserName)
   119  
   120  	return nil
   121  }
   122  
   123  func confirmDelete(ctx *cmd.Context, controller, username string) error {
   124  	// Get confirmation from the user that they want to continue
   125  	fmt.Fprintf(ctx.Stdout, removeUserMsg, username, controller)
   126  
   127  	scanner := bufio.NewScanner(ctx.Stdin)
   128  	scanner.Scan()
   129  	err := scanner.Err()
   130  	if err != nil && err != io.EOF {
   131  		return errors.Annotate(err, "user deletion aborted")
   132  	}
   133  	answer := strings.ToLower(scanner.Text())
   134  	if answer != "y" && answer != "yes" {
   135  		return errors.New("user deletion aborted")
   136  	}
   137  	return nil
   138  }