1
0
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:
Harshavardhana
2017-10-20 13:51:56 -07:00
committed by Dee Koder
parent a86080a0b7
commit aa8d5ed0cc
5 changed files with 109 additions and 30 deletions

View File

@ -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

View File

@ -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
} }

View File

@ -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 = ""

View File

@ -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 {

View File

@ -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
} }