mirror of
https://github.com/minio/mc.git
synced 2025-07-31 18:24:21 +03:00
Add newS3Config helper to auto-probe signature type. (#2292)
This commit is contained in:
committed by
Dee Koder
parent
a86080a0b7
commit
aa8d5ed0cc
@ -182,6 +182,7 @@ func newFactory() func(config *Config) (Client, *probe.Error) {
|
|||||||
// Cache the new minio client with hash of config as key.
|
// Cache the new minio client with hash of config as key.
|
||||||
clientCache[confSum] = api
|
clientCache[confSum] = api
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the new api object.
|
// Store the new api object.
|
||||||
s3Clnt.api = api
|
s3Clnt.api = api
|
||||||
|
|
||||||
|
@ -17,11 +17,10 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
urlpkg "net/url"
|
|
||||||
|
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/minio/cli"
|
"github.com/minio/cli"
|
||||||
"github.com/minio/mc/pkg/console"
|
"github.com/minio/mc/pkg/console"
|
||||||
|
"github.com/minio/mc/pkg/probe"
|
||||||
)
|
)
|
||||||
|
|
||||||
var configHostAddCmd = cli.Command{
|
var configHostAddCmd = cli.Command{
|
||||||
@ -53,6 +52,14 @@ EXAMPLES:
|
|||||||
$ {{.HelpName}} mys3-accel https://s3-accelerate.amazonaws.com \
|
$ {{.HelpName}} mys3-accel https://s3-accelerate.amazonaws.com \
|
||||||
BKIKJAA5BMMU2RHO6IBB V8f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
|
BKIKJAA5BMMU2RHO6IBB V8f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
|
||||||
$ set -o history
|
$ set -o history
|
||||||
|
|
||||||
|
3. Add Amazon S3 IAM temporary credentials with limited access, please make sure to override the signature probe by explicitly
|
||||||
|
providing the signature type.
|
||||||
|
$ set +o history
|
||||||
|
$ {{.HelpName}} mys3-iam https://s3.amazonaws.com \
|
||||||
|
BKIKJAA5BMMU2RHO6IBB V8f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12 s3v4
|
||||||
|
$ set -o history
|
||||||
|
|
||||||
`,
|
`,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,36 +123,79 @@ func addHost(alias string, hostCfgV8 hostConfigV8) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newS3Config(args cli.Args) (*Config, *probe.Error) {
|
||||||
|
var (
|
||||||
|
url = args.Get(0)
|
||||||
|
accessKey = args.Get(1)
|
||||||
|
secretKey = args.Get(2)
|
||||||
|
api = args.Get(3)
|
||||||
|
)
|
||||||
|
|
||||||
|
// If api is provided we do not auto probe signature, this is
|
||||||
|
// required in situations when signature type is provided by the user.
|
||||||
|
if api != "" {
|
||||||
|
return &Config{
|
||||||
|
AccessKey: accessKey,
|
||||||
|
SecretKey: secretKey,
|
||||||
|
Signature: api,
|
||||||
|
HostURL: url,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
s3Config := &Config{
|
||||||
|
AccessKey: accessKey,
|
||||||
|
SecretKey: secretKey,
|
||||||
|
Signature: "s3v4",
|
||||||
|
HostURL: urlJoinPath(url, "probe-bucket-sign"),
|
||||||
|
}
|
||||||
|
|
||||||
|
s3Client, err := s3New(s3Config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err.Trace(args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = s3Client.Stat(false); err != nil {
|
||||||
|
switch err.ToGoError().(type) {
|
||||||
|
case BucketDoesNotExist:
|
||||||
|
// Bucket doesn't exist, means signature probing worked V4.
|
||||||
|
default:
|
||||||
|
// Attempt with signature v2, since v4 seem to have failed.
|
||||||
|
s3Config.Signature = "s3v2"
|
||||||
|
s3Client, err = s3New(s3Config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err.Trace(args...)
|
||||||
|
}
|
||||||
|
if _, err = s3Client.Stat(false); err != nil {
|
||||||
|
switch err.ToGoError().(type) {
|
||||||
|
case BucketDoesNotExist:
|
||||||
|
// Bucket doesn't exist, means signature probing worked with V2.
|
||||||
|
default:
|
||||||
|
return nil, err.Trace(args...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the host url with original URL.
|
||||||
|
s3Config.HostURL = url
|
||||||
|
|
||||||
|
// Success.
|
||||||
|
return s3Config, nil
|
||||||
|
}
|
||||||
|
|
||||||
func mainConfigHostAdd(ctx *cli.Context) error {
|
func mainConfigHostAdd(ctx *cli.Context) error {
|
||||||
checkConfigHostAddSyntax(ctx)
|
checkConfigHostAddSyntax(ctx)
|
||||||
|
|
||||||
console.SetColor("HostMessage", color.New(color.FgGreen))
|
console.SetColor("HostMessage", color.New(color.FgGreen))
|
||||||
|
|
||||||
args := ctx.Args()
|
s3Config, err := newS3Config(ctx.Args().Tail())
|
||||||
alias := args.Get(0)
|
fatalIf(err.Trace(ctx.Args()...), "Unable to initialize new config from the provided credentials")
|
||||||
url := args.Get(1)
|
|
||||||
accessKey := args.Get(2)
|
|
||||||
secretKey := args.Get(3)
|
|
||||||
api := args.Get(4)
|
|
||||||
|
|
||||||
parsedURL, _ := urlpkg.Parse(url)
|
addHost(ctx.Args().Get(0), hostConfigV8{
|
||||||
|
URL: s3Config.HostURL,
|
||||||
if isGoogle(parsedURL.Host) {
|
AccessKey: s3Config.AccessKey,
|
||||||
if api == "S3v4" {
|
SecretKey: s3Config.SecretKey,
|
||||||
fatalIf(errInvalidArgument().Trace(api), "Unsupported API signature for url. Please use `mc config host add "+alias+" "+url+" "+accessKey+" "+secretKey+" S3v2` instead.")
|
API: s3Config.Signature,
|
||||||
}
|
}) // Add a host with specified credentials.
|
||||||
api = "S3v2"
|
|
||||||
}
|
|
||||||
|
|
||||||
if api == "" {
|
|
||||||
api = "S3v4"
|
|
||||||
}
|
|
||||||
hostCfg := hostConfigV8{
|
|
||||||
URL: url,
|
|
||||||
AccessKey: accessKey,
|
|
||||||
SecretKey: secretKey,
|
|
||||||
API: api,
|
|
||||||
}
|
|
||||||
addHost(alias, hostCfg) // Add a host with specified credentials.
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -93,8 +93,10 @@ func printHosts(hosts ...hostMessage) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, host := range hosts {
|
for _, host := range hosts {
|
||||||
// Format properly for alignment based on alias length.
|
if !globalJSON {
|
||||||
host.Alias = fmt.Sprintf("%-*.*s:", maxAlias, maxAlias, host.Alias)
|
// Format properly for alignment based on alias length only in non json mode.
|
||||||
|
host.Alias = fmt.Sprintf("%-*.*s:", maxAlias, maxAlias, host.Alias)
|
||||||
|
}
|
||||||
if host.AccessKey == "" || host.SecretKey == "" {
|
if host.AccessKey == "" || host.SecretKey == "" {
|
||||||
host.AccessKey = ""
|
host.AccessKey = ""
|
||||||
host.SecretKey = ""
|
host.SecretKey = ""
|
||||||
|
@ -30,7 +30,7 @@ var (
|
|||||||
}
|
}
|
||||||
|
|
||||||
errInvalidArgument = func() *probe.Error {
|
errInvalidArgument = func() *probe.Error {
|
||||||
return probe.NewError(errors.New("Invalid arguments provided, cannot proceed")).Untrace()
|
return probe.NewError(errors.New("Invalid arguments provided, please refer " + "`mc <command> -h` for relevant documentation.")).Untrace()
|
||||||
}
|
}
|
||||||
|
|
||||||
errUnrecognizedDiffType = func(diff differType) *probe.Error {
|
errUnrecognizedDiffType = func(diff differType) *probe.Error {
|
||||||
|
@ -457,6 +457,29 @@ function test_watch_object()
|
|||||||
log_success "$start_time" "${FUNCNAME[0]}"
|
log_success "$start_time" "${FUNCNAME[0]}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function test_config_host_add()
|
||||||
|
{
|
||||||
|
show "${FUNCNAME[0]}"
|
||||||
|
start_time=$(get_time)
|
||||||
|
|
||||||
|
assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd config host add "${SERVER_ALIAS}1" "$ENDPOINT" "$ACCESS_KEY" "$SECRET_KEY"
|
||||||
|
assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd config host list "${SERVER_ALIAS}1"
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_config_host_add_error()
|
||||||
|
{
|
||||||
|
show "${FUNCNAME[0]}"
|
||||||
|
start_time=$(get_time)
|
||||||
|
|
||||||
|
out=$("${MC_CMD[@]}" --json config host add "${SERVER_ALIAS}1" "$ENDPOINT" "$ACCESS_KEY" "invalid-secret")
|
||||||
|
assert_failure "$start_time" "${FUNCNAME[0]}" fail $? "adding host should fail"
|
||||||
|
got_code=$(echo "$out" | jq -r .error.cause.error.Code)
|
||||||
|
if [ "${got_code}" != "SignatureDoesNotMatch" ]; then
|
||||||
|
assert_failure "$start_time" "${FUNCNAME[0]}" fail 1 "incorrect error code ${got_code} returned by server"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
function run_test()
|
function run_test()
|
||||||
{
|
{
|
||||||
test_make_bucket
|
test_make_bucket
|
||||||
@ -479,6 +502,9 @@ function run_test()
|
|||||||
test_watch_object
|
test_watch_object
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
test_config_host_add
|
||||||
|
test_config_host_add_error
|
||||||
|
|
||||||
teardown
|
teardown
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user