mirror of
https://github.com/minio/mc.git
synced 2025-11-28 08:03:56 +03:00
Secret key prompt (#3083)
This commit is contained in:
@@ -17,7 +17,9 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
@@ -25,6 +27,7 @@ import (
|
|||||||
json "github.com/minio/mc/pkg/colorjson"
|
json "github.com/minio/mc/pkg/colorjson"
|
||||||
"github.com/minio/mc/pkg/probe"
|
"github.com/minio/mc/pkg/probe"
|
||||||
"github.com/minio/minio/pkg/console"
|
"github.com/minio/minio/pkg/console"
|
||||||
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
)
|
)
|
||||||
|
|
||||||
var adminUserAddCmd = cli.Command{
|
var adminUserAddCmd = cli.Command{
|
||||||
@@ -53,13 +56,23 @@ EXAMPLES:
|
|||||||
{{.DisableHistory}}
|
{{.DisableHistory}}
|
||||||
{{.Prompt}} {{.HelpName}} myminio foobar foo12345
|
{{.Prompt}} {{.HelpName}} myminio foobar foo12345
|
||||||
{{.EnableHistory}}
|
{{.EnableHistory}}
|
||||||
|
2. Add a new user 'foobar' to MinIO server, prompting for keys.
|
||||||
|
{{.Prompt}} {{.HelpName}} myminio
|
||||||
|
Enter Access Key: foobar
|
||||||
|
Enter Secret Key: foobar12345
|
||||||
|
3. Add a new user 'foobar' to MinIO server using piped keys.
|
||||||
|
{{.DisableHistory}}
|
||||||
|
{{.Prompt}} echo -e "foobar\nfoobar12345" | {{.HelpName}} myminio
|
||||||
|
{{.EnableHistory}}
|
||||||
`,
|
`,
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkAdminUserAddSyntax - validate all the passed arguments
|
// checkAdminUserAddSyntax - validate all the passed arguments
|
||||||
func checkAdminUserAddSyntax(ctx *cli.Context) {
|
func checkAdminUserAddSyntax(ctx *cli.Context) {
|
||||||
if len(ctx.Args()) != 3 {
|
argsNr := len(ctx.Args())
|
||||||
cli.ShowCommandHelpAndExit(ctx, "add", 1) // last argument is exit code
|
if argsNr > 3 || argsNr < 1 {
|
||||||
|
fatalIf(errInvalidArgument().Trace(ctx.Args().Tail()...),
|
||||||
|
"Incorrect number of arguments for user add command.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,6 +128,43 @@ func (u userMessage) JSON() string {
|
|||||||
return string(jsonMessageBytes)
|
return string(jsonMessageBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fetchUserKeys - returns the access and secret key
|
||||||
|
func fetchUserKeys(args cli.Args) (string, string) {
|
||||||
|
accessKey := ""
|
||||||
|
secretKey := ""
|
||||||
|
console.SetColor(cred, color.New(color.FgYellow, color.Italic))
|
||||||
|
isTerminal := terminal.IsTerminal(int(os.Stdin.Fd()))
|
||||||
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
|
||||||
|
argCount := len(args)
|
||||||
|
|
||||||
|
if argCount == 1 {
|
||||||
|
if isTerminal {
|
||||||
|
fmt.Printf("%s", console.Colorize(cred, "Enter Access Key: "))
|
||||||
|
}
|
||||||
|
value, _, _ := reader.ReadLine()
|
||||||
|
accessKey = string(value)
|
||||||
|
} else {
|
||||||
|
accessKey = args.Get(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if argCount == 1 || argCount == 2 {
|
||||||
|
if isTerminal {
|
||||||
|
fmt.Printf("%s", console.Colorize(cred, "Enter Secret Key: "))
|
||||||
|
bytePassword, _ := terminal.ReadPassword(int(os.Stdin.Fd()))
|
||||||
|
fmt.Printf("\n")
|
||||||
|
secretKey = string(bytePassword)
|
||||||
|
} else {
|
||||||
|
value, _, _ := reader.ReadLine()
|
||||||
|
secretKey = string(value)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
secretKey = args.Get(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
return accessKey, secretKey
|
||||||
|
}
|
||||||
|
|
||||||
// mainAdminUserAdd is the handle for "mc admin user add" command.
|
// mainAdminUserAdd is the handle for "mc admin user add" command.
|
||||||
func mainAdminUserAdd(ctx *cli.Context) error {
|
func mainAdminUserAdd(ctx *cli.Context) error {
|
||||||
checkAdminUserAddSyntax(ctx)
|
checkAdminUserAddSyntax(ctx)
|
||||||
@@ -124,17 +174,18 @@ func mainAdminUserAdd(ctx *cli.Context) error {
|
|||||||
// Get the alias parameter from cli
|
// Get the alias parameter from cli
|
||||||
args := ctx.Args()
|
args := ctx.Args()
|
||||||
aliasedURL := args.Get(0)
|
aliasedURL := args.Get(0)
|
||||||
|
accessKey, secretKey := fetchUserKeys(args)
|
||||||
|
|
||||||
// Create a new MinIO Admin Client
|
// Create a new MinIO Admin Client
|
||||||
client, err := newAdminClient(aliasedURL)
|
client, err := newAdminClient(aliasedURL)
|
||||||
fatalIf(err, "Unable to initialize admin connection.")
|
fatalIf(err, "Unable to initialize admin connection.")
|
||||||
|
|
||||||
fatalIf(probe.NewError(client.AddUser(args.Get(1), args.Get(2))).Trace(args...), "Cannot add new user")
|
fatalIf(probe.NewError(client.AddUser(accessKey, secretKey)).Trace(args...), "Cannot add new user")
|
||||||
|
|
||||||
printMsg(userMessage{
|
printMsg(userMessage{
|
||||||
op: "add",
|
op: "add",
|
||||||
AccessKey: args.Get(1),
|
AccessKey: accessKey,
|
||||||
SecretKey: args.Get(2),
|
SecretKey: secretKey,
|
||||||
UserStatus: "enabled",
|
UserStatus: "enabled",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -17,15 +17,21 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/minio/cli"
|
"github.com/minio/cli"
|
||||||
"github.com/minio/mc/pkg/probe"
|
"github.com/minio/mc/pkg/probe"
|
||||||
"github.com/minio/minio/pkg/console"
|
"github.com/minio/minio/pkg/console"
|
||||||
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const cred = "YellowItalics"
|
||||||
|
|
||||||
var hostAddFlags = []cli.Flag{
|
var hostAddFlags = []cli.Flag{
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "lookup",
|
Name: "lookup",
|
||||||
@@ -71,24 +77,34 @@ EXAMPLES:
|
|||||||
{{.Prompt}} {{.HelpName}} mys3 https://s3.amazonaws.com \
|
{{.Prompt}} {{.HelpName}} mys3 https://s3.amazonaws.com \
|
||||||
BKIKJAA5BMMU2RHO6IBB V8f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
|
BKIKJAA5BMMU2RHO6IBB V8f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
|
||||||
{{.EnableHistory}}
|
{{.EnableHistory}}
|
||||||
|
|
||||||
|
4. Add Amazon S3 storage service under "mys3" alias, prompting for keys.
|
||||||
|
{{.Prompt}} {{.HelpName}} mys3 https://s3.amazonaws.com --api "s3v4" --lookup "dns"
|
||||||
|
Enter Access Key: BKIKJAA5BMMU2RHO6IBB
|
||||||
|
Enter Secret Key: V8f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
|
||||||
|
|
||||||
|
5. Add Amazon S3 storage service under "mys3" alias using piped keys.
|
||||||
|
{{.DisableHistory}}
|
||||||
|
{{.Prompt}} echo -e "BKIKJAA5BMMU2RHO6IBB\nV8f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12" | \
|
||||||
|
{{.HelpName}} mys3 https://s3.amazonaws.com --api "s3v4" --lookup "dns"
|
||||||
|
{{.EnableHistory}}
|
||||||
`,
|
`,
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkConfigHostAddSyntax - verifies input arguments to 'config host add'.
|
// checkConfigHostAddSyntax - verifies input arguments to 'config host add'.
|
||||||
func checkConfigHostAddSyntax(ctx *cli.Context) {
|
func checkConfigHostAddSyntax(ctx *cli.Context, accessKey string, secretKey string) {
|
||||||
args := ctx.Args()
|
args := ctx.Args()
|
||||||
argsNr := len(args)
|
argsNr := len(args)
|
||||||
if argsNr < 4 || argsNr > 5 {
|
if argsNr > 4 || argsNr < 2 {
|
||||||
fatalIf(errInvalidArgument().Trace(ctx.Args().Tail()...),
|
fatalIf(errInvalidArgument().Trace(ctx.Args().Tail()...),
|
||||||
"Incorrect number of arguments for host add command.")
|
"Incorrect number of arguments for host add command.")
|
||||||
}
|
}
|
||||||
|
|
||||||
alias := args.Get(0)
|
alias := args.Get(0)
|
||||||
url := args.Get(1)
|
url := args.Get(1)
|
||||||
accessKey := args.Get(2)
|
|
||||||
secretKey := args.Get(3)
|
|
||||||
api := ctx.String("api")
|
api := ctx.String("api")
|
||||||
bucketLookup := ctx.String("lookup")
|
bucketLookup := ctx.String("lookup")
|
||||||
|
|
||||||
if !isValidAlias(alias) {
|
if !isValidAlias(alias) {
|
||||||
fatalIf(errInvalidAlias(alias), "Invalid alias.")
|
fatalIf(errInvalidAlias(alias), "Invalid alias.")
|
||||||
}
|
}
|
||||||
@@ -213,18 +229,54 @@ func buildS3Config(url, accessKey, secretKey, api, lookup string) (*Config, *pro
|
|||||||
return s3Config, nil
|
return s3Config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fetchHostKeys - returns the user accessKey and secretKey
|
||||||
|
func fetchHostKeys(args cli.Args) (string, string) {
|
||||||
|
accessKey := ""
|
||||||
|
secretKey := ""
|
||||||
|
console.SetColor(cred, color.New(color.FgYellow, color.Italic))
|
||||||
|
isTerminal := terminal.IsTerminal(int(os.Stdin.Fd()))
|
||||||
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
|
||||||
|
argsNr := len(args)
|
||||||
|
|
||||||
|
if argsNr == 2 {
|
||||||
|
if isTerminal {
|
||||||
|
fmt.Printf("%s", console.Colorize(cred, "Enter Access Key: "))
|
||||||
|
}
|
||||||
|
value, _, _ := reader.ReadLine()
|
||||||
|
accessKey = string(value)
|
||||||
|
} else {
|
||||||
|
accessKey = args.Get(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
if argsNr == 2 || argsNr == 3 {
|
||||||
|
if isTerminal {
|
||||||
|
fmt.Printf("%s", console.Colorize(cred, "Enter Secret Key: "))
|
||||||
|
bytePassword, _ := terminal.ReadPassword(int(os.Stdin.Fd()))
|
||||||
|
fmt.Printf("\n")
|
||||||
|
secretKey = string(bytePassword)
|
||||||
|
} else {
|
||||||
|
value, _, _ := reader.ReadLine()
|
||||||
|
secretKey = string(value)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
secretKey = args.Get(3)
|
||||||
|
}
|
||||||
|
|
||||||
|
return accessKey, secretKey
|
||||||
|
}
|
||||||
|
|
||||||
func mainConfigHostAdd(ctx *cli.Context) error {
|
func mainConfigHostAdd(ctx *cli.Context) error {
|
||||||
checkConfigHostAddSyntax(ctx)
|
|
||||||
|
|
||||||
console.SetColor("HostMessage", color.New(color.FgGreen))
|
console.SetColor("HostMessage", color.New(color.FgGreen))
|
||||||
var (
|
var (
|
||||||
args = ctx.Args()
|
args = ctx.Args()
|
||||||
url = trimTrailingSeparator(args.Get(1))
|
url = trimTrailingSeparator(args.Get(1))
|
||||||
accessKey = args.Get(2)
|
|
||||||
secretKey = args.Get(3)
|
|
||||||
api = ctx.String("api")
|
api = ctx.String("api")
|
||||||
lookup = ctx.String("lookup")
|
lookup = ctx.String("lookup")
|
||||||
)
|
)
|
||||||
|
accessKey, secretKey := fetchHostKeys(args)
|
||||||
|
checkConfigHostAddSyntax(ctx, accessKey, secretKey)
|
||||||
|
|
||||||
s3Config, err := buildS3Config(url, accessKey, secretKey, api, lookup)
|
s3Config, err := buildS3Config(url, accessKey, secretKey, api, lookup)
|
||||||
fatalIf(err.Trace(ctx.Args()...), "Unable to initialize new config from the provided credentials.")
|
fatalIf(err.Trace(ctx.Args()...), "Unable to initialize new config from the provided credentials.")
|
||||||
|
|||||||
@@ -99,15 +99,36 @@ MinIO server displays URL, access and secret keys.
|
|||||||
#### Usage
|
#### Usage
|
||||||
|
|
||||||
```
|
```
|
||||||
mc config host add <ALIAS> <YOUR-MINIO-ENDPOINT> <YOUR-ACCESS-KEY> <YOUR-SECRET-KEY>
|
mc config host add <ALIAS> <YOUR-MINIO-ENDPOINT> [YOUR-ACCESS-KEY] [YOUR-SECRET-KEY]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Keys must be supplied by argument or standard input.
|
||||||
|
|
||||||
Alias is simply a short name to your MinIO service. MinIO end-point, access and secret keys are supplied by your MinIO service. Admin API uses "S3v4" signature and cannot be changed.
|
Alias is simply a short name to your MinIO service. MinIO end-point, access and secret keys are supplied by your MinIO service. Admin API uses "S3v4" signature and cannot be changed.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
1. Keys by argument
|
||||||
|
|
||||||
```
|
```
|
||||||
mc config host add minio http://192.168.1.51:9000 BKIKJAA5BMMU2RHO6IBB V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
|
mc config host add minio http://192.168.1.51:9000 BKIKJAA5BMMU2RHO6IBB V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
|
||||||
```
|
```
|
||||||
|
|
||||||
|
2. Keys by prompt
|
||||||
|
|
||||||
|
```
|
||||||
|
mc config host add minio http://192.168.1.51:9000
|
||||||
|
Enter Access Key: BKIKJAA5BMMU2RHO6IBB
|
||||||
|
Enter Secret Key: V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Keys by pipe
|
||||||
|
|
||||||
|
```
|
||||||
|
echo -e "BKIKJAA5BMMU2RHO6IBB\nV7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12" | \
|
||||||
|
mc config host add minio http://192.168.1.51:9000
|
||||||
|
```
|
||||||
|
|
||||||
## 4. Test Your Setup
|
## 4. Test Your Setup
|
||||||
|
|
||||||
*Example:*
|
*Example:*
|
||||||
@@ -439,6 +460,14 @@ COMMANDS:
|
|||||||
mc admin user add myminio/ newuser newuser123
|
mc admin user add myminio/ newuser newuser123
|
||||||
```
|
```
|
||||||
|
|
||||||
|
*Example: Add a new user 'newuser' on MinIO, using standard input.*
|
||||||
|
|
||||||
|
```
|
||||||
|
mc admin user add myminio/
|
||||||
|
Enter Access Key: newuser
|
||||||
|
Enter Secret Key: newuser123
|
||||||
|
```
|
||||||
|
|
||||||
*Example: Disable a user 'newuser' on MinIO.*
|
*Example: Disable a user 'newuser' on MinIO.*
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -119,9 +119,11 @@ To add one or more Amazon S3 compatible hosts, please follow the instructions be
|
|||||||
#### Usage
|
#### Usage
|
||||||
|
|
||||||
```
|
```
|
||||||
mc config host add <ALIAS> <YOUR-S3-ENDPOINT> <YOUR-ACCESS-KEY> <YOUR-SECRET-KEY> <API-SIGNATURE>
|
mc config host add <ALIAS> <YOUR-S3-ENDPOINT> [YOUR-ACCESS-KEY] [YOUR-SECRET-KEY] [--api API-SIGNATURE]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Keys must be supplied by argument or standard input.
|
||||||
|
|
||||||
Alias is simply a short name to your cloud storage service. S3 end-point, access and secret keys are supplied by your cloud storage provider. API signature is an optional argument. By default, it is set to "S3v4".
|
Alias is simply a short name to your cloud storage service. S3 end-point, access and secret keys are supplied by your cloud storage provider. API signature is an optional argument. By default, it is set to "S3v4".
|
||||||
|
|
||||||
### Example - MinIO Cloud Storage
|
### Example - MinIO Cloud Storage
|
||||||
@@ -146,6 +148,23 @@ Get your AccessKeyID and SecretAccessKey by following [Google Credentials Guide]
|
|||||||
mc config host add gcs https://storage.googleapis.com BKIKJAA5BMMU2RHO6IBB V8f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
|
mc config host add gcs https://storage.googleapis.com BKIKJAA5BMMU2RHO6IBB V8f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Example - Specify keys using standard input
|
||||||
|
|
||||||
|
1. Prompt
|
||||||
|
|
||||||
|
```
|
||||||
|
mc config host add minio http://192.168.1.51 --api S3v4
|
||||||
|
Enter Access Key: BKIKJAA5BMMU2RHO6IBB
|
||||||
|
Enter Secret Key: V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Pipe
|
||||||
|
|
||||||
|
```
|
||||||
|
echo -e "BKIKJAA5BMMU2RHO6IBB\nV7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12" | \
|
||||||
|
mc config host add minio http://192.168.1.51 --api S3v4
|
||||||
|
```
|
||||||
|
|
||||||
### Specify host configuration through environment variable
|
### Specify host configuration through environment variable
|
||||||
```
|
```
|
||||||
export MC_HOST_<alias>=https://<Access Key>:<Secret Key>@<YOUR-S3-ENDPOINT>
|
export MC_HOST_<alias>=https://<Access Key>:<Secret Key>@<YOUR-S3-ENDPOINT>
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -24,7 +24,7 @@ require (
|
|||||||
github.com/rjeczalik/notify v0.9.2
|
github.com/rjeczalik/notify v0.9.2
|
||||||
github.com/ugorji/go v1.1.7 // indirect
|
github.com/ugorji/go v1.1.7 // indirect
|
||||||
go.uber.org/zap v1.11.0 // indirect
|
go.uber.org/zap v1.11.0 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6 // indirect
|
golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2
|
golang.org/x/net v0.0.0-20200202094626-16171245cfb2
|
||||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 // indirect
|
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 // indirect
|
||||||
golang.org/x/text v0.3.2
|
golang.org/x/text v0.3.2
|
||||||
|
|||||||
Reference in New Issue
Block a user