~juju-qa/ubuntu/xenial/juju/2.0-rc2

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/cmd/juju/user/list.go

  • Committer: Nicholas Skaggs
  • Date: 2016-09-30 14:39:30 UTC
  • mfrom: (1.8.1)
  • Revision ID: nicholas.skaggs@canonical.com-20160930143930-vwwhrefh6ftckccy
import upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
package user
5
5
 
6
6
import (
7
 
        "fmt"
8
7
        "io"
9
8
 
 
9
        "github.com/juju/ansiterm"
10
10
        "github.com/juju/cmd"
11
11
        "github.com/juju/errors"
12
12
        "github.com/juju/gnuflag"
 
13
        "github.com/juju/utils/clock"
 
14
        "github.com/juju/utils/set"
13
15
        "gopkg.in/juju/names.v2"
14
16
 
15
17
        "github.com/juju/juju/api/usermanager"
 
18
        "github.com/juju/juju/apiserver/params"
 
19
        "github.com/juju/juju/cmd/juju/common"
16
20
        "github.com/juju/juju/cmd/modelcmd"
17
21
        "github.com/juju/juju/cmd/output"
18
22
)
34
38
    enable-user`[1:]
35
39
 
36
40
func NewListCommand() cmd.Command {
37
 
        return modelcmd.WrapController(&listCommand{})
 
41
        return modelcmd.WrapController(&listCommand{
 
42
                infoCommandBase: infoCommandBase{
 
43
                        clock: clock.WallClock,
 
44
                },
 
45
        })
38
46
}
39
47
 
40
48
// listCommand shows all the users in the Juju server.
41
49
type listCommand struct {
42
50
        infoCommandBase
43
 
        All bool
 
51
        modelUserAPI modelUsersAPI
 
52
 
 
53
        All         bool
 
54
        modelName   string
 
55
        currentUser string
 
56
}
 
57
 
 
58
// ModelUsersAPI defines the methods on the client API that the
 
59
// users command calls.
 
60
type modelUsersAPI interface {
 
61
        Close() error
 
62
        ModelUserInfo() ([]params.ModelUserInfo, error)
 
63
}
 
64
 
 
65
func (c *listCommand) getModelAPI() (modelUsersAPI, error) {
 
66
        if c.modelUserAPI != nil {
 
67
                return c.modelUserAPI, nil
 
68
        }
 
69
        conn, err := c.NewModelAPIRoot(c.modelName)
 
70
        if err != nil {
 
71
                return nil, errors.Trace(err)
 
72
        }
 
73
        return conn.Client(), nil
44
74
}
45
75
 
46
76
// Info implements Command.Info.
64
94
        })
65
95
}
66
96
 
 
97
// Init implements Command.Init.
 
98
func (c *listCommand) Init(args []string) (err error) {
 
99
        c.modelName, err = cmd.ZeroOrOneArgs(args)
 
100
        if err != nil {
 
101
                return err
 
102
        }
 
103
        return err
 
104
}
 
105
 
67
106
// Run implements Command.Run.
68
107
func (c *listCommand) Run(ctx *cmd.Context) (err error) {
 
108
        if c.out.Name() == "tabular" {
 
109
                // Only the tabular outputters need to know the current user,
 
110
                // but both of them do, so do it in one place.
 
111
                accountDetails, err := c.ClientStore().AccountDetails(c.ControllerName())
 
112
                if err != nil {
 
113
                        return err
 
114
                }
 
115
                c.currentUser = names.NewUserTag(accountDetails.User).Canonical()
 
116
        }
 
117
        if c.modelName == "" {
 
118
                return c.controllerUsers(ctx)
 
119
        }
 
120
        return c.modelUsers(ctx)
 
121
}
 
122
 
 
123
func (c *listCommand) modelUsers(ctx *cmd.Context) error {
 
124
        client, err := c.getModelAPI()
 
125
        if err != nil {
 
126
                return err
 
127
        }
 
128
        defer client.Close()
 
129
 
 
130
        result, err := client.ModelUserInfo()
 
131
        if err != nil {
 
132
                return err
 
133
        }
 
134
        if len(result) == 0 {
 
135
                ctx.Infof("No users to display.")
 
136
                return nil
 
137
        }
 
138
        return c.out.Write(ctx, common.ModelUserInfoFromParams(result, c.clock.Now()))
 
139
}
 
140
 
 
141
func (c *listCommand) controllerUsers(ctx *cmd.Context) error {
69
142
        // Note: the InfoCommandBase and the UserInfo struct are defined
70
143
        // in info.go.
71
144
        client, err := c.getUserInfoAPI()
79
152
                return err
80
153
        }
81
154
 
 
155
        if len(result) == 0 {
 
156
                ctx.Infof("No users to display.")
 
157
                return nil
 
158
        }
 
159
 
82
160
        return c.out.Write(ctx, c.apiUsersToUserInfoSlice(result))
83
161
}
84
162
 
85
163
func (c *listCommand) formatTabular(writer io.Writer, value interface{}) error {
 
164
        if c.modelName == "" {
 
165
                return c.formatControllerUsers(writer, value)
 
166
        }
 
167
        return c.formatModelUsers(writer, value)
 
168
}
 
169
 
 
170
func (c *listCommand) isLoggedInUser(username string) bool {
 
171
        tag := names.NewUserTag(username)
 
172
        return tag.Canonical() == c.currentUser
 
173
}
 
174
 
 
175
func (c *listCommand) formatModelUsers(writer io.Writer, value interface{}) error {
 
176
        users, ok := value.(map[string]common.ModelUserInfo)
 
177
        if !ok {
 
178
                return errors.Errorf("expected value of type %T, got %T", users, value)
 
179
        }
 
180
        modelUsers := set.NewStrings()
 
181
        for name := range users {
 
182
                modelUsers.Add(name)
 
183
        }
 
184
        tw := output.TabWriter(writer)
 
185
        w := output.Wrapper{tw}
 
186
        w.Println("NAME", "DISPLAY NAME", "ACCESS", "LAST CONNECTION")
 
187
        for _, name := range modelUsers.SortedValues() {
 
188
                user := users[name]
 
189
 
 
190
                var highlight *ansiterm.Context
 
191
                userName := name
 
192
                if c.isLoggedInUser(name) {
 
193
                        userName += "*"
 
194
                        highlight = output.CurrentHighlight
 
195
                }
 
196
                w.PrintColor(highlight, userName)
 
197
                w.Println(user.DisplayName, user.Access, user.LastConnection)
 
198
        }
 
199
        tw.Flush()
 
200
        return nil
 
201
}
 
202
 
 
203
func (c *listCommand) formatControllerUsers(writer io.Writer, value interface{}) error {
86
204
        users, valueConverted := value.([]UserInfo)
87
205
        if !valueConverted {
88
206
                return errors.Errorf("expected value of type %T, got %T", users, value)
89
207
        }
90
 
        accountDetails, err := c.ClientStore().AccountDetails(c.ControllerName())
91
 
        if err != nil {
92
 
                return err
93
 
        }
94
 
        loggedInUser := names.NewUserTag(accountDetails.User).Canonical()
95
208
 
96
209
        tw := output.TabWriter(writer)
97
 
        fmt.Fprintf(tw, "CONTROLLER: %v\n", c.ControllerName())
98
 
        fmt.Fprint(tw, "\n")
99
 
        fmt.Fprint(tw, "NAME\tDISPLAY NAME\tACCESS\tDATE CREATED\tLAST CONNECTION\n")
 
210
        w := output.Wrapper{tw}
 
211
        w.Println("CONTROLLER: " + c.ControllerName())
 
212
        w.Println()
 
213
        w.Println("NAME", "DISPLAY NAME", "ACCESS", "DATE CREATED", "LAST CONNECTION")
100
214
        for _, user := range users {
101
215
                conn := user.LastConnection
102
216
                if user.Disabled {
103
217
                        conn += " (disabled)"
104
218
                }
 
219
                var highlight *ansiterm.Context
105
220
                userName := user.Username
106
 
                if loggedInUser == names.NewUserTag(user.Username).Canonical() {
 
221
                if c.isLoggedInUser(user.Username) {
107
222
                        userName += "*"
108
 
                        output.CurrentHighlight.Fprintf(tw, "%s\t", userName)
109
 
                } else {
110
 
                        fmt.Fprintf(tw, "%s\t", userName)
 
223
                        highlight = output.CurrentHighlight
111
224
                }
112
 
                fmt.Fprintf(tw, "%s\t%s\t%s\t%s\n", user.DisplayName, user.Access, user.DateCreated, conn)
 
225
                w.PrintColor(highlight, userName)
 
226
                w.Println(user.DisplayName, user.Access, user.DateCreated, conn)
113
227
        }
114
228
        tw.Flush()
115
229
        return nil