31
33
# Add user "foobar"
32
34
juju add-user foobar
34
# Add user and share model.
35
juju add-user foobar --share somemodel
36
# Add user with default (read) access to models "qa" and "prod".
37
juju add-user foobar --models qa,prod
39
# Add user with write access to model "devel".
40
juju add-user foobar --models devel --acl write
43
48
// AddUserAPI defines the usermanager API methods that the add command uses.
44
49
type AddUserAPI interface {
45
AddUser(username, displayName, password string, modelUUIDs ...string) (names.UserTag, []byte, error)
50
AddUser(username, displayName, password, access string, modelUUIDs ...string) (names.UserTag, []byte, error)
62
68
func (c *addCommand) SetFlags(f *gnuflag.FlagSet) {
63
f.StringVar(&c.ModelName, "share", "", "share a model with the new user")
69
f.StringVar(&c.ModelNames, "models", "", "models the new user is granted access to")
70
f.StringVar(&c.ModelAccess, "acl", "read", "access controls")
66
73
// Info implements Command.Info.
67
74
func (c *addCommand) Info() *cmd.Info {
70
Args: "<username> [<display name>] [--share <model name>]",
71
Purpose: "adds a user to a controller and optionally shares a model",
77
Args: "<username> [<display name>] [--models <model1> [<m2> .. <mN>] ] [--acl <read|write>]",
78
Purpose: "adds a user to a controller, optionally with access to models",
72
79
Doc: useraddCommandDoc,
78
85
if len(args) == 0 {
79
86
return fmt.Errorf("no username supplied")
89
_, err := permission.ParseModelAccess(c.ModelAccess)
81
94
c.User, args = args[0], args[1:]
83
96
c.DisplayName, args = args[0], args[1:]
100
// If we need to share a model, look up the model UUID from the supplied name.
101
var modelUUIDs []string
102
if c.ModelName != "" {
103
store := c.ClientStore()
104
controllerName := c.ControllerName()
105
accountName := c.AccountName()
106
model, err := store.ModelByName(controllerName, accountName, c.ModelName)
107
if errors.IsNotFound(err) {
108
// The model isn't known locally, so query the models available in the controller.
109
ctx.Verbosef("model %q not cached locally, refreshing models from controller", c.ModelName)
110
if err := c.RefreshModels(store, controllerName, accountName); err != nil {
111
return errors.Annotate(err, "refreshing models")
113
model, err = store.ModelByName(controllerName, accountName, c.ModelName)
118
modelUUIDs = []string{model.ModelUUID}
113
var modelNames []string
114
for _, modelArg := range strings.Split(c.ModelNames, ",") {
115
modelArg = strings.TrimSpace(modelArg)
116
if len(modelArg) > 0 {
117
modelNames = append(modelNames, modelArg)
121
// If we need to share a model, look up the model UUIDs from the supplied names.
122
modelUUIDs, err := c.ModelUUIDs(modelNames)
124
return errors.Trace(err)
121
127
// Add a user without a password. This will generate a temporary
122
128
// secret key, which we'll print out for the user to supply to
123
129
// "juju register".
124
_, secretKey, err := api.AddUser(c.User, c.DisplayName, "", modelUUIDs...)
130
_, secretKey, err := api.AddUser(c.User, c.DisplayName, "", c.ModelAccess, modelUUIDs...)
126
132
return block.ProcessBlockedError(err, block.BlockChange)
134
140
// Generate the base64-encoded string for the user to pass to
135
141
// "juju register". We marshal the information using ASN.1
136
142
// to keep the size down, since we need to encode binary data.
137
info, err := c.ConnectionInfo()
143
controllerDetails, err := c.ClientStore().ControllerByName(c.ControllerName())
139
145
return errors.Trace(err)
141
147
registrationInfo := jujuclient.RegistrationInfo{
143
Addrs: info.APIEndpoint().Addresses,
149
Addrs: controllerDetails.APIEndpoints,
144
150
SecretKey: secretKey,
146
152
registrationData, err := asn1.Marshal(registrationInfo)
166
172
fmt.Fprintf(ctx.Stdout, "User %q added\n", displayName)
167
if c.ModelName != "" {
168
fmt.Fprintf(ctx.Stdout, "Model %q is now shared\n", c.ModelName)
173
for _, modelName := range modelNames {
174
fmt.Fprintf(ctx.Stdout, "User %q granted %s access to model %q\n", displayName, c.ModelAccess, modelName)
170
176
fmt.Fprintf(ctx.Stdout, "Please send this command to %v:\n", c.User)
171
177
fmt.Fprintf(ctx.Stdout, " juju register %s\n",
172
178
base64RegistrationData,
180
if len(modelNames) == 0 {
181
fmt.Fprintf(ctx.Stdout, `
182
%q has not been granted access to any models. You can use "juju grant" to grant access.