github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/cmd/juju/model/grantrevoke.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package model
     5  
     6  import (
     7  	"github.com/juju/cmd"
     8  	"github.com/juju/errors"
     9  
    10  	"github.com/juju/juju/cmd/juju/block"
    11  	"github.com/juju/juju/cmd/modelcmd"
    12  	"github.com/juju/juju/permission"
    13  )
    14  
    15  var usageGrantSummary = `
    16  Grants access level to a Juju user for a model or controller.`[1:]
    17  
    18  var usageGrantDetails = `
    19  By default, the controller is the current controller.
    20  
    21  Users with read access are limited in what they can do with models:
    22  ` + "`juju models`, `juju machines`, and `juju status`" + `.
    23  
    24  Examples:
    25  Grant user 'joe' 'read' access to model 'mymodel':
    26  
    27      juju grant joe read mymodel
    28  
    29  Grant user 'jim' 'write' access to model 'mymodel':
    30  
    31      juju grant jim write mymodel
    32  
    33  Grant user 'sam' 'read' access to models 'model1' and 'model2':
    34  
    35      juju grant sam read model1 model2
    36  
    37  Grant user 'maria' 'addmodel' access to the controller:
    38  
    39      juju grant maria addmodel
    40  
    41  Valid access levels for models are:
    42      read
    43      write
    44      admin
    45  
    46  Valid access levels for controllers are:
    47      login
    48      addmodel
    49      superuser
    50  
    51  See also: 
    52      revoke
    53      add-user`
    54  
    55  var usageRevokeSummary = `
    56  Revokes access from a Juju user for a model or controller`[1:]
    57  
    58  var usageRevokeDetails = `
    59  By default, the controller is the current controller.
    60  
    61  Revoking write access, from a user who has that permission, will leave
    62  that user with read access. Revoking read access, however, also revokes
    63  write access.
    64  
    65  Examples:
    66  Revoke 'read' (and 'write') access from user 'joe' for model 'mymodel':
    67  
    68      juju revoke joe read mymodel
    69  
    70  Revoke 'write' access from user 'sam' for models 'model1' and 'model2':
    71  
    72      juju revoke sam write model1 model2
    73  
    74  Revoke 'addmodel' acces from user 'maria' to the controller:
    75  
    76      juju revoke maria addmodel
    77  
    78  See also: 
    79      grant`[1:]
    80  
    81  type accessCommand struct {
    82  	modelcmd.ControllerCommandBase
    83  
    84  	User        string
    85  	ModelNames  []string
    86  	ModelAccess string
    87  }
    88  
    89  // Init implements cmd.Command.
    90  func (c *accessCommand) Init(args []string) error {
    91  	if len(args) < 1 {
    92  		return errors.New("no user specified")
    93  	}
    94  
    95  	if len(args) < 2 {
    96  		return errors.New("no permission level specified")
    97  	}
    98  
    99  	c.User = args[0]
   100  	c.ModelNames = args[2:]
   101  	c.ModelAccess = args[1]
   102  	if len(c.ModelNames) > 0 {
   103  		err := permission.ValidateModelAccess(permission.Access(c.ModelAccess))
   104  		if err != nil {
   105  			return err
   106  		}
   107  	}
   108  	return nil
   109  }
   110  
   111  // NewGrantCommand returns a new grant command.
   112  func NewGrantCommand() cmd.Command {
   113  	return modelcmd.WrapController(&grantCommand{})
   114  }
   115  
   116  // grantCommand represents the command to grant a user access to one or more models.
   117  type grantCommand struct {
   118  	accessCommand
   119  	api GrantModelAPI
   120  }
   121  
   122  // Info implements Command.Info.
   123  func (c *grantCommand) Info() *cmd.Info {
   124  	return &cmd.Info{
   125  		Name:    "grant",
   126  		Args:    "<user name> <permission> [<model name> ...]",
   127  		Purpose: usageGrantSummary,
   128  		Doc:     usageGrantDetails,
   129  	}
   130  }
   131  
   132  func (c *grantCommand) getModelAPI() (GrantModelAPI, error) {
   133  	if c.api != nil {
   134  		return c.api, nil
   135  	}
   136  	return c.NewModelManagerAPIClient()
   137  }
   138  
   139  func (c *grantCommand) getControllerAPI() (GrantControllerAPI, error) {
   140  	return c.NewControllerAPIClient()
   141  }
   142  
   143  // GrantModelAPI defines the API functions used by the grant command.
   144  type GrantModelAPI interface {
   145  	Close() error
   146  	GrantModel(user, access string, modelUUIDs ...string) error
   147  }
   148  
   149  // GrantControllerAPI defines the API functions used by the grant command.
   150  type GrantControllerAPI interface {
   151  	Close() error
   152  	GrantController(user, access string) error
   153  }
   154  
   155  // Run implements cmd.Command.
   156  func (c *grantCommand) Run(ctx *cmd.Context) error {
   157  	if len(c.ModelNames) > 0 {
   158  		return c.runForModel()
   159  	}
   160  	return c.runForController()
   161  }
   162  
   163  func (c *grantCommand) runForController() error {
   164  	client, err := c.getControllerAPI()
   165  	if err != nil {
   166  		return err
   167  	}
   168  	defer client.Close()
   169  
   170  	return block.ProcessBlockedError(client.GrantController(c.User, c.ModelAccess), block.BlockChange)
   171  }
   172  
   173  func (c *grantCommand) runForModel() error {
   174  	client, err := c.getModelAPI()
   175  	if err != nil {
   176  		return err
   177  	}
   178  	defer client.Close()
   179  
   180  	models, err := c.ModelUUIDs(c.ModelNames)
   181  	if err != nil {
   182  		return err
   183  	}
   184  	return block.ProcessBlockedError(client.GrantModel(c.User, c.ModelAccess, models...), block.BlockChange)
   185  }
   186  
   187  // NewRevokeCommand returns a new revoke command.
   188  func NewRevokeCommand() cmd.Command {
   189  	return modelcmd.WrapController(&revokeCommand{})
   190  }
   191  
   192  // revokeCommand revokes a user's access to models.
   193  type revokeCommand struct {
   194  	accessCommand
   195  	api RevokeModelAPI
   196  }
   197  
   198  // Info implements cmd.Command.
   199  func (c *revokeCommand) Info() *cmd.Info {
   200  	return &cmd.Info{
   201  		Name:    "revoke",
   202  		Args:    "<user> <permission> [<model name> ...]",
   203  		Purpose: usageRevokeSummary,
   204  		Doc:     usageRevokeDetails,
   205  	}
   206  }
   207  
   208  func (c *revokeCommand) getModelAPI() (RevokeModelAPI, error) {
   209  	if c.api != nil {
   210  		return c.api, nil
   211  	}
   212  	return c.NewModelManagerAPIClient()
   213  }
   214  
   215  func (c *revokeCommand) getControllerAPI() (RevokeControllerAPI, error) {
   216  	return c.NewControllerAPIClient()
   217  }
   218  
   219  // RevokeModelAPI defines the API functions used by the revoke command.
   220  type RevokeModelAPI interface {
   221  	Close() error
   222  	RevokeModel(user, access string, modelUUIDs ...string) error
   223  }
   224  
   225  // RevokeControllerAPI defines the API functions used by the revoke command.
   226  type RevokeControllerAPI interface {
   227  	Close() error
   228  	RevokeController(user, access string) error
   229  }
   230  
   231  // Run implements cmd.Command.
   232  func (c *revokeCommand) Run(ctx *cmd.Context) error {
   233  	if len(c.ModelNames) > 0 {
   234  		return c.runForModel()
   235  	}
   236  	return c.runForController()
   237  }
   238  
   239  func (c *revokeCommand) runForController() error {
   240  	client, err := c.getControllerAPI()
   241  	if err != nil {
   242  		return err
   243  	}
   244  	defer client.Close()
   245  
   246  	return block.ProcessBlockedError(client.RevokeController(c.User, c.ModelAccess), block.BlockChange)
   247  }
   248  
   249  func (c *revokeCommand) runForModel() error {
   250  	client, err := c.getModelAPI()
   251  	if err != nil {
   252  		return err
   253  	}
   254  	defer client.Close()
   255  
   256  	models, err := c.ModelUUIDs(c.ModelNames)
   257  	if err != nil {
   258  		return err
   259  	}
   260  	return block.ProcessBlockedError(client.RevokeModel(c.User, c.ModelAccess, models...), block.BlockChange)
   261  }