forked from juju/juju
/
add.go
133 lines (113 loc) · 3.33 KB
/
add.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright 2012-2014 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.
package user
import (
"fmt"
"github.com/juju/cmd/v3"
"github.com/juju/errors"
"github.com/juju/names/v4"
"github.com/DavinZhang/juju/apiserver/params"
jujucmd "github.com/DavinZhang/juju/cmd"
"github.com/DavinZhang/juju/cmd/juju/block"
"github.com/DavinZhang/juju/cmd/juju/common"
"github.com/DavinZhang/juju/cmd/modelcmd"
)
var usageSummary = `
Adds a Juju user to a controller.`[1:]
const usageDetails = `The user's details are stored within the controller and
will be removed when the controller is destroyed.
A user unique registration string will be printed. This registration string
must be used by the newly added user as supplied to
complete the registration process.
Some machine providers will require the user to be in possession of certain
credentials in order to create a model.
Examples:
juju add-user bob
juju add-user --controller mycontroller bob
See also:
register
grant
users
show-user
disable-user
enable-user
change-user-password
remove-user`
// AddUserAPI defines the usermanager API methods that the add command uses.
type AddUserAPI interface {
AddUser(username, displayName, password string) (names.UserTag, []byte, error)
Close() error
}
func NewAddCommand() cmd.Command {
return modelcmd.WrapController(&addCommand{})
}
// addCommand adds new users into a Juju Server.
type addCommand struct {
modelcmd.ControllerCommandBase
api AddUserAPI
User string
DisplayName string
}
// Info implements Command.Info.
func (c *addCommand) Info() *cmd.Info {
return jujucmd.Info(&cmd.Info{
Name: "add-user",
Args: "<user name> [<display name>]",
Purpose: usageSummary,
Doc: usageDetails,
})
}
// Init implements Command.Init.
func (c *addCommand) Init(args []string) error {
if len(args) == 0 {
return errors.Errorf("no username supplied")
}
c.User, args = args[0], args[1:]
if len(args) > 0 {
c.DisplayName, args = args[0], args[1:]
}
return cmd.CheckEmpty(args)
}
// Run implements Command.Run.
func (c *addCommand) Run(ctx *cmd.Context) error {
api := c.api
if api == nil {
var err error
api, err = c.NewUserManagerAPIClient()
if err != nil {
return errors.Trace(err)
}
defer api.Close()
}
// Add a user without a password. This will generate a temporary
// secret key, which we'll print out for the user to supply to
// "juju register".
_, secretKey, err := api.AddUser(c.User, c.DisplayName, "")
if err != nil {
if params.IsCodeUnauthorized(err) {
common.PermissionsMessage(ctx.Stderr, "add a user")
}
return block.ProcessBlockedError(err, block.BlockChange)
}
displayName := c.User
if c.DisplayName != "" {
displayName = fmt.Sprintf("%s (%s)", c.DisplayName, c.User)
}
base64RegistrationData, err := generateUserControllerAccessToken(
c.ControllerCommandBase,
c.User,
secretKey,
)
if err != nil {
return errors.Annotate(err, "generating controller user access token")
}
fmt.Fprintf(ctx.Stdout, "User %q added\n", displayName)
fmt.Fprintf(ctx.Stdout, "Please send this command to %v:\n", c.User)
fmt.Fprintf(ctx.Stdout, " juju register %s\n",
base64RegistrationData,
)
fmt.Fprintf(ctx.Stdout, `
%q has not been granted access to any models. You can use "juju grant" to grant access.
`, displayName)
return nil
}