github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cmd/juju/model/users.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for infos. 3 4 package model 5 6 import ( 7 "bytes" 8 "fmt" 9 "text/tabwriter" 10 "time" 11 12 "github.com/juju/cmd" 13 "github.com/juju/errors" 14 "github.com/juju/utils/set" 15 "launchpad.net/gnuflag" 16 17 "github.com/juju/juju/apiserver/params" 18 "github.com/juju/juju/cmd/juju/common" 19 "github.com/juju/juju/cmd/modelcmd" 20 ) 21 22 var usageListSharesSummary = ` 23 Shows all users with access to a model for the current controller.`[1:] 24 25 var usageListSharesDetails = ` 26 By default, the model is the current model. 27 28 Examples: 29 juju list-shares 30 juju list-shares -m mymodel 31 32 See also: 33 grant`[1:] 34 35 func NewUsersCommand() cmd.Command { 36 return modelcmd.Wrap(&usersCommand{}) 37 } 38 39 // usersCommand shows all the users with access to the current model. 40 type usersCommand struct { 41 modelcmd.ModelCommandBase 42 out cmd.Output 43 api UsersAPI 44 } 45 46 // UsersAPI defines the methods on the client API that the 47 // users command calls. 48 type UsersAPI interface { 49 Close() error 50 ModelUserInfo() ([]params.ModelUserInfo, error) 51 } 52 53 func (c *usersCommand) getAPI() (UsersAPI, error) { 54 if c.api != nil { 55 return c.api, nil 56 } 57 return c.NewAPIClient() 58 } 59 60 // Info implements Command.Info. 61 func (c *usersCommand) Info() *cmd.Info { 62 return &cmd.Info{ 63 Name: "list-shares", 64 Purpose: usageListSharesSummary, 65 Doc: usageListSharesDetails, 66 } 67 } 68 69 // SetFlags implements Command.SetFlags. 70 func (c *usersCommand) SetFlags(f *gnuflag.FlagSet) { 71 c.out.AddFlags(f, "tabular", map[string]cmd.Formatter{ 72 "yaml": cmd.FormatYaml, 73 "json": cmd.FormatJson, 74 "tabular": c.formatTabular, 75 }) 76 } 77 78 // Run implements Command.Run. 79 func (c *usersCommand) Run(ctx *cmd.Context) (err error) { 80 client, err := c.getAPI() 81 if err != nil { 82 return err 83 } 84 defer client.Close() 85 86 result, err := client.ModelUserInfo() 87 if err != nil { 88 return err 89 } 90 return c.out.Write(ctx, common.ModelUserInfoFromParams(result, time.Now())) 91 } 92 93 // formatTabular takes an interface{} to adhere to the cmd.Formatter interface 94 func (c *usersCommand) formatTabular(value interface{}) ([]byte, error) { 95 users, ok := value.(map[string]common.ModelUserInfo) 96 if !ok { 97 return nil, errors.Errorf("expected value of type %T, got %T", users, value) 98 } 99 var out bytes.Buffer 100 if err := formatTabularUserInfo(users, &out); err != nil { 101 return nil, errors.Trace(err) 102 } 103 return out.Bytes(), nil 104 } 105 106 func formatTabularUserInfo(users map[string]common.ModelUserInfo, out *bytes.Buffer) error { 107 const ( 108 // To format things into columns. 109 minwidth = 0 110 tabwidth = 1 111 padding = 2 112 padchar = ' ' 113 flags = 0 114 ) 115 names := set.NewStrings() 116 for name := range users { 117 names.Add(name) 118 } 119 tw := tabwriter.NewWriter(out, minwidth, tabwidth, padding, padchar, flags) 120 fmt.Fprintf(tw, "NAME\tACCESS\tLAST CONNECTION\n") 121 for _, name := range names.SortedValues() { 122 user := users[name] 123 displayName := name 124 if user.DisplayName != "" { 125 displayName = fmt.Sprintf("%s (%s)", name, user.DisplayName) 126 } 127 fmt.Fprintf(tw, "%s\t%s\t%s\n", displayName, user.Access, user.LastConnection) 128 } 129 tw.Flush() 130 return nil 131 }