github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cmd/juju/user/info.go (about)

     1  // Copyright 2012-2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for infos.
     3  
     4  package user
     5  
     6  import (
     7  	"time"
     8  
     9  	"github.com/juju/cmd"
    10  	"github.com/juju/errors"
    11  	"launchpad.net/gnuflag"
    12  
    13  	"github.com/juju/juju/api/usermanager"
    14  	"github.com/juju/juju/apiserver/params"
    15  	"github.com/juju/juju/cmd/juju/common"
    16  	"github.com/juju/juju/cmd/modelcmd"
    17  )
    18  
    19  var helpSummary = `
    20  Show information about a user.`[1:]
    21  
    22  var helpDetails = `
    23  By default, the YAML format is used and the user name is the current
    24  user.
    25  
    26  
    27  Examples:
    28      juju show-user
    29      juju show-user jsmith
    30      juju show-user --format json
    31      juju show-user --format yaml
    32      
    33  See also: 
    34      add-user
    35      register
    36      list-users`[1:]
    37  
    38  // UserInfoAPI defines the API methods that the info command uses.
    39  type UserInfoAPI interface {
    40  	UserInfo([]string, usermanager.IncludeDisabled) ([]params.UserInfo, error)
    41  	Close() error
    42  }
    43  
    44  // infoCommandBase is a common base for 'juju show-user' and 'juju list-user'.
    45  type infoCommandBase struct {
    46  	modelcmd.ControllerCommandBase
    47  	api       UserInfoAPI
    48  	exactTime bool
    49  	out       cmd.Output
    50  }
    51  
    52  func (c *infoCommandBase) SetFlags(f *gnuflag.FlagSet) {
    53  	f.BoolVar(&c.exactTime, "exact-time", false, "Use full timestamp for connection times")
    54  }
    55  
    56  func NewShowUserCommand() cmd.Command {
    57  	return modelcmd.WrapController(&infoCommand{})
    58  }
    59  
    60  // infoCommand retrieves information about a single user.
    61  type infoCommand struct {
    62  	infoCommandBase
    63  	Username string
    64  }
    65  
    66  // UserInfo defines the serialization behaviour of the user information.
    67  type UserInfo struct {
    68  	Username       string `yaml:"user-name" json:"user-name"`
    69  	DisplayName    string `yaml:"display-name" json:"display-name"`
    70  	DateCreated    string `yaml:"date-created" json:"date-created"`
    71  	LastConnection string `yaml:"last-connection" json:"last-connection"`
    72  	Disabled       bool   `yaml:"disabled,omitempty" json:"disabled,omitempty"`
    73  }
    74  
    75  // Info implements Command.Info.
    76  func (c *infoCommand) Info() *cmd.Info {
    77  	return &cmd.Info{
    78  		Name:    "show-user",
    79  		Args:    "[<user name>]",
    80  		Purpose: helpSummary,
    81  		Doc:     helpDetails,
    82  	}
    83  }
    84  
    85  // SetFlags implements Command.SetFlags.
    86  func (c *infoCommand) SetFlags(f *gnuflag.FlagSet) {
    87  	c.infoCommandBase.SetFlags(f)
    88  	c.out.AddFlags(f, "yaml", cmd.DefaultFormatters)
    89  }
    90  
    91  // Init implements Command.Init.
    92  func (c *infoCommand) Init(args []string) (err error) {
    93  	c.Username, err = cmd.ZeroOrOneArgs(args)
    94  	return err
    95  }
    96  
    97  func (c *infoCommandBase) getUserInfoAPI() (UserInfoAPI, error) {
    98  	if c.api != nil {
    99  		return c.api, nil
   100  	}
   101  	return c.NewUserManagerAPIClient()
   102  }
   103  
   104  // Run implements Command.Run.
   105  func (c *infoCommand) Run(ctx *cmd.Context) (err error) {
   106  	client, err := c.getUserInfoAPI()
   107  	if err != nil {
   108  		return err
   109  	}
   110  	defer client.Close()
   111  	username := c.Username
   112  	if username == "" {
   113  		accountDetails, err := c.ClientStore().AccountByName(
   114  			c.ControllerName(), c.AccountName(),
   115  		)
   116  		if err != nil {
   117  			return err
   118  		}
   119  		username = accountDetails.User
   120  	}
   121  	result, err := client.UserInfo([]string{username}, false)
   122  	if err != nil {
   123  		return err
   124  	}
   125  	// Don't output the params type, be explicit. We convert before checking
   126  	// length because we want to reuse the conversion function, and we are
   127  	// pretty sure that there is one value there.
   128  	output := c.apiUsersToUserInfoSlice(result)
   129  	if len(output) != 1 {
   130  		return errors.Errorf("expected 1 result, got %d", len(output))
   131  	}
   132  	return c.out.Write(ctx, output[0])
   133  }
   134  
   135  func (c *infoCommandBase) apiUsersToUserInfoSlice(users []params.UserInfo) []UserInfo {
   136  	var output []UserInfo
   137  	var now = time.Now()
   138  	for _, info := range users {
   139  		outInfo := UserInfo{
   140  			Username:       info.Username,
   141  			DisplayName:    info.DisplayName,
   142  			Disabled:       info.Disabled,
   143  			LastConnection: common.LastConnection(info.LastConnection, now, c.exactTime),
   144  		}
   145  		if c.exactTime {
   146  			outInfo.DateCreated = info.DateCreated.String()
   147  		} else {
   148  			outInfo.DateCreated = common.UserFriendlyDuration(info.DateCreated, now)
   149  		}
   150  
   151  		output = append(output, outInfo)
   152  	}
   153  
   154  	return output
   155  }