Skip to content

Commit

Permalink
etcdctl: add flags for specifying password
Browse files Browse the repository at this point in the history
This commit adds two flags to etcdctl:
1. `--password` flag to etcdctl as a global option. It can be used for
specifying password for authentication required for the command
execution.
2. `--new-user-password` flag to `etcdctl user add`. It can be used
for specifying password of newly created user by the command.

The main motivation of the flags is allowing user to have : in its
name.

Fix etcd-io#9691
  • Loading branch information
mitake committed May 21, 2018
1 parent 1b9791c commit 8fcab98
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 21 deletions.
9 changes: 8 additions & 1 deletion Documentation/op-guide/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Creating a user is as easy as
$ etcdctl user add myusername
```

Creating a new user will prompt for a new password. The password can be supplied from standard input when an option `--interactive=false` is given.
Creating a new user will prompt for a new password. The password can be supplied from standard input when an option `--interactive=false` is given. `--new-user-password` can also be used for supplying the password.

Roles can be granted and revoked for a user with:

Expand Down Expand Up @@ -157,6 +157,13 @@ The password can be taken from a prompt:
$ etcdctl --user user get foo
```

The password can also be taken from a command line flag `--password`:

```
$ etcdctl --user user --password password get foo
```


Otherwise, all `etcdctl` commands remain the same. Users and roles can still be created and modified, but require authentication by a user with the root role.

## Using TLS Common Name
Expand Down
28 changes: 19 additions & 9 deletions etcdctl/ctlv3/command/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ type GlobalFlags struct {
OutputFormat string
IsHex bool

User string
User string
Password string

Debug bool
}
Expand Down Expand Up @@ -341,23 +342,32 @@ func authCfgFromCmd(cmd *cobra.Command) *authCfg {
if err != nil {
ExitWithError(ExitBadArgs, err)
}
passwordFlag, err := cmd.Flags().GetString("password")
if err != nil {
ExitWithError(ExitBadArgs, err)
}

if userFlag == "" {
return nil
}

var cfg authCfg

splitted := strings.SplitN(userFlag, ":", 2)
if len(splitted) < 2 {
cfg.username = userFlag
cfg.password, err = speakeasy.Ask("Password: ")
if err != nil {
ExitWithError(ExitError, err)
if passwordFlag == "" {
splitted := strings.SplitN(userFlag, ":", 2)
if len(splitted) < 2 {
cfg.username = userFlag
cfg.password, err = speakeasy.Ask("Password: ")
if err != nil {
ExitWithError(ExitError, err)
}
} else {
cfg.username = splitted[0]
cfg.password = splitted[1]
}
} else {
cfg.username = splitted[0]
cfg.password = splitted[1]
cfg.username = userFlag
cfg.password = passwordFlag
}

return &cfg
Expand Down
29 changes: 18 additions & 11 deletions etcdctl/ctlv3/command/user_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func NewUserCommand() *cobra.Command {

var (
passwordInteractive bool
passwordFromFlag string
)

func newUserAddCommand() *cobra.Command {
Expand All @@ -57,6 +58,7 @@ func newUserAddCommand() *cobra.Command {
}

cmd.Flags().BoolVar(&passwordInteractive, "interactive", true, "Read password from stdin instead of interactive terminal")
cmd.Flags().StringVar(&passwordFromFlag, "new-user-password", "", "Supply password from the command line flag")

return &cmd
}
Expand Down Expand Up @@ -126,19 +128,24 @@ func userAddCommandFunc(cmd *cobra.Command, args []string) {
var password string
var user string

splitted := strings.SplitN(args[0], ":", 2)
if len(splitted) < 2 {
if passwordFromFlag != "" {
user = args[0]
if !passwordInteractive {
fmt.Scanf("%s", &password)
} else {
password = readPasswordInteractive(args[0])
}
password = passwordFromFlag
} else {
user = splitted[0]
password = splitted[1]
if len(user) == 0 {
ExitWithError(ExitBadArgs, fmt.Errorf("empty user name is not allowed."))
splitted := strings.SplitN(args[0], ":", 2)
if len(splitted) < 2 {
user = args[0]
if !passwordInteractive {
fmt.Scanf("%s", &password)
} else {
password = readPasswordInteractive(args[0])
}
} else {
user = splitted[0]
password = splitted[1]
if len(user) == 0 {
ExitWithError(ExitBadArgs, fmt.Errorf("empty user name is not allowed."))
}
}
}

Expand Down
1 change: 1 addition & 0 deletions etcdctl/ctlv3/ctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func init() {
rootCmd.PersistentFlags().StringVar(&globalFlags.TLS.KeyFile, "key", "", "identify secure client using this TLS key file")
rootCmd.PersistentFlags().StringVar(&globalFlags.TLS.TrustedCAFile, "cacert", "", "verify certificates of TLS-enabled secure servers using this CA bundle")
rootCmd.PersistentFlags().StringVar(&globalFlags.User, "user", "", "username[:password] for authentication (prompt if password is not supplied)")
rootCmd.PersistentFlags().StringVar(&globalFlags.Password, "password", "", "password for authentication (if this option is used, --user option shouldn't include password)")
rootCmd.PersistentFlags().StringVarP(&globalFlags.TLS.ServerName, "discovery-srv", "d", "", "domain name to query for SRV records describing cluster endpoints")

rootCmd.AddCommand(
Expand Down

0 comments on commit 8fcab98

Please sign in to comment.