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 }