diff --git a/go.mod b/go.mod index c5a216bf7..2ecd76149 100644 --- a/go.mod +++ b/go.mod @@ -12,9 +12,9 @@ require ( github.com/go-openapi/swag v0.19.8 github.com/go-openapi/validate v0.19.7 github.com/jessevdk/go-flags v1.4.0 - github.com/minio/mc v0.0.0-20200401220942-e05f02d9f459 + github.com/minio/mc v0.0.0-20200403024131-4d36c1f8b856 github.com/minio/minio v0.0.0-20200327214830-6f992134a25f - github.com/minio/minio-go/v6 v6.0.51-0.20200319192131-097caa7760c7 + github.com/minio/minio-go/v6 v6.0.51-0.20200401083717-eadbcae2a0e6 github.com/stretchr/testify v1.5.1 golang.org/x/net v0.0.0-20200301022130-244492dfa37a ) diff --git a/go.sum b/go.sum index 85c93eaab..dca4a45b6 100644 --- a/go.sum +++ b/go.sum @@ -79,6 +79,8 @@ github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dvaldivia/mc v0.0.0-20200402232537-1048833f1701 h1:TaXA4hNW3k99MbCKOFnXsaLr9xsx/kh9YXcUNQ/Q8Wk= +github.com/dvaldivia/mc v0.0.0-20200402232537-1048833f1701/go.mod h1:IDy4dA4aFY6zFFNkYgdUztl0jcYuev/Ubg3NadoaMKc= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-resiliency v1.2.0 h1:v7g92e/KSN71Rq7vSThKaWIq68fL4YHvWyiUKorFR1Q= github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= @@ -383,13 +385,16 @@ github.com/minio/highwayhash v1.0.0 h1:iMSDhgUILCr0TNm8LWlSjF8N0ZIj2qbO8WHp6Q/J2 github.com/minio/highwayhash v1.0.0/go.mod h1:xQboMTeM9nY9v/LlAOxFctujiv5+Aq2hR5dxBpaMbdc= github.com/minio/lsync v1.0.1 h1:AVvILxA976xc27hstd1oR+X9PQG0sPSom1MNb1ImfUs= github.com/minio/lsync v1.0.1/go.mod h1:tCFzfo0dlvdGl70IT4IAK/5Wtgb0/BrTmo/jE8pArKA= -github.com/minio/mc v0.0.0-20200401220942-e05f02d9f459 h1:59+zfhCHdmvCQEs/qUTEqOIKKGc9t6kfYmZRHVqn77E= github.com/minio/mc v0.0.0-20200401220942-e05f02d9f459/go.mod h1:GWohdY5tXSiMnBCofmDRK5yRCihQH2FKNM0eh+UsY5Y= +github.com/minio/mc v0.0.0-20200403024131-4d36c1f8b856 h1:4uIc5fw4tVr5glh2Mc8GFuiY04pTGEhmihPxJPUvCoU= +github.com/minio/mc v0.0.0-20200403024131-4d36c1f8b856/go.mod h1:IDy4dA4aFY6zFFNkYgdUztl0jcYuev/Ubg3NadoaMKc= github.com/minio/minio v0.0.0-20200327214830-6f992134a25f h1:RoOBi0vhXkZqe2b6RTROOsVJUwMqLMoet9r7eL01euo= github.com/minio/minio v0.0.0-20200327214830-6f992134a25f/go.mod h1:BzbIyKUJPp+4f03i2XF7+GsijXnxMakUe5x+lm2WNc8= github.com/minio/minio-go/v6 v6.0.45/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg= github.com/minio/minio-go/v6 v6.0.51-0.20200319192131-097caa7760c7 h1:WQmYVUDRGdcEWhJeb42/Fn1IO7SBLem173DTE4+jp/E= github.com/minio/minio-go/v6 v6.0.51-0.20200319192131-097caa7760c7/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg= +github.com/minio/minio-go/v6 v6.0.51-0.20200401083717-eadbcae2a0e6 h1:7JhqKjmt1Tv6co7eP/40/xtDLrzzWu1UwUNwQzSvcb0= +github.com/minio/minio-go/v6 v6.0.51-0.20200401083717-eadbcae2a0e6/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg= github.com/minio/parquet-go v0.0.0-20200125064549-a1e49702e174 h1:WYFHZIJ5LTWd4C3CW26jguaBLLDdX7l1/Xa3QSKGkIc= github.com/minio/parquet-go v0.0.0-20200125064549-a1e49702e174/go.mod h1:PXYM9yI2l0YPmxHUXe6mFTmkQcyaVasDshAPTbGpDoo= github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU= diff --git a/restapi/client-admin.go b/restapi/client-admin.go index 4c6daf2fa..b75ba3ddb 100644 --- a/restapi/client-admin.go +++ b/restapi/client-admin.go @@ -18,105 +18,21 @@ package restapi import ( "context" - "crypto/tls" - "hash/fnv" - "io" - "net" - "net/http" - "net/url" - "path/filepath" - "runtime" - "sync" - "time" - - "github.com/minio/mc/pkg/httptracer" + mcCmd "github.com/minio/mc/cmd" "github.com/minio/mc/pkg/probe" "github.com/minio/minio/pkg/madmin" + "io" + "path/filepath" + "runtime" ) -const globalAppName = "orchestrator portal" - -// newAdminFactory encloses New function with client cache. -func newAdminFactory() func(config *Config) (*madmin.AdminClient, *probe.Error) { - clientCache := make(map[uint32]*madmin.AdminClient) - mutex := &sync.Mutex{} - - // Return New function. - return func(config *Config) (*madmin.AdminClient, *probe.Error) { - // Creates a parsed URL. - targetURL, e := url.Parse(config.HostURL) - if e != nil { - return nil, probe.NewError(e) - } - // By default enable HTTPs. - useTLS := true - if targetURL.Scheme == "http" { - useTLS = false - } - - // Save if target supports virtual host style. - hostName := targetURL.Host - - // Generate a hash out of s3Conf. - confHash := fnv.New32a() - confHash.Write([]byte(hostName + config.AccessKey + config.SecretKey)) - confSum := confHash.Sum32() - - // Lookup previous cache by hash. - mutex.Lock() - defer mutex.Unlock() - var api *madmin.AdminClient - var found bool - if api, found = clientCache[confSum]; !found { - // Not found. Instantiate a new MinIO - var e error - api, e = madmin.New(hostName, config.AccessKey, config.SecretKey, useTLS) - if e != nil { - return nil, probe.NewError(e) - } - - // Keep TLS config. - tlsConfig := &tls.Config{} - if config.Insecure { - tlsConfig.InsecureSkipVerify = true - } - - var transport http.RoundTripper = &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DialContext: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - }).DialContext, - MaxIdleConns: 100, - IdleConnTimeout: 90 * time.Second, - TLSHandshakeTimeout: 10 * time.Second, - ExpectContinueTimeout: 1 * time.Second, - TLSClientConfig: tlsConfig, - } - - if config.Debug { - transport = httptracer.GetNewTraceTransport(newTraceV4(), transport) - } - - // Set custom transport. - api.SetCustomTransport(transport) - - // Set app info. - api.SetAppInfo(config.AppName, config.AppVersion) - - // Cache the new MinIO Client with hash of config as key. - clientCache[confSum] = api - } - - // Store the new api object. - return api, nil - } -} +const globalAppName = "mcs" // NewAdminClient gives a new client interface -func NewAdminClient(url string, accessKey string, secretKey string) (*madmin.AdminClient, *probe.Error) { +func NewAdminClient(url, accessKey, secretKey string) (*madmin.AdminClient, *probe.Error) { appName := filepath.Base(globalAppName) - s3Client, err := s3AdminNew(&Config{ + + s3Client, err := s3AdminNew(&mcCmd.Config{ HostURL: url, AccessKey: accessKey, SecretKey: secretKey, @@ -132,7 +48,7 @@ func NewAdminClient(url string, accessKey string, secretKey string) (*madmin.Adm // s3AdminNew returns an initialized minioAdmin structure. If debug is enabled, // it also enables an internal trace transport. -var s3AdminNew = newAdminFactory() +var s3AdminNew = mcCmd.NewAdminFactory() // Define MinioAdmin interface with all functions to be implemented // by mock when testing, it should include all MinioAdmin respective api calls diff --git a/restapi/client-s3-trace_v4.go b/restapi/client-s3-trace_v4.go deleted file mode 100644 index f939b603a..000000000 --- a/restapi/client-s3-trace_v4.go +++ /dev/null @@ -1,89 +0,0 @@ -// This file is part of MinIO Orchestrator -// Copyright (c) 2020 MinIO, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package restapi - -import ( - "net/http" - "net/http/httputil" - "regexp" - "strings" - - "github.com/minio/mc/pkg/httptracer" - "github.com/minio/minio/pkg/console" -) - -// traceV4 - tracing structure for signature version '4'. -type traceV4 struct{} - -// newTraceV4 - initialize Trace structure -func newTraceV4() httptracer.HTTPTracer { - return traceV4{} -} - -// Request - Trace HTTP Request -func (t traceV4) Request(req *http.Request) (err error) { - origAuth := req.Header.Get("Authorization") - - printTrace := func() error { - reqTrace, rerr := httputil.DumpRequestOut(req, false) // Only display header - if rerr == nil { - console.Debug(string(reqTrace)) - } - return rerr - } - - if strings.TrimSpace(origAuth) != "" { - // Authorization (S3 v4 signature) Format: - // Authorization: AWS4-HMAC-SHA256 Credential=AKIAJNACEGBGMXBHLEZA/20150524/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=bbfaa693c626021bcb5f911cd898a1a30206c1fad6bad1e0eb89e282173bd24c - - // Strip out accessKeyID from: Credential=////aws4_request - regCred := regexp.MustCompile("Credential=([A-Z0-9]+)/") - newAuth := regCred.ReplaceAllString(origAuth, "Credential=**REDACTED**/") - - // Strip out 256-bit signature from: Signature=<256-bit signature> - regSign := regexp.MustCompile("Signature=([[0-9a-f]+)") - newAuth = regSign.ReplaceAllString(newAuth, "Signature=**REDACTED**") - - // Set a temporary redacted auth - req.Header.Set("Authorization", newAuth) - - err = printTrace() - - // Undo - req.Header.Set("Authorization", origAuth) - } else { - err = printTrace() - } - return err -} - -// Response - Trace HTTP Response -func (t traceV4) Response(resp *http.Response) (err error) { - var respTrace []byte - // For errors we make sure to dump response body as well. - if resp.StatusCode != http.StatusOK && - resp.StatusCode != http.StatusPartialContent && - resp.StatusCode != http.StatusNoContent { - respTrace, err = httputil.DumpResponse(resp, true) - } else { - respTrace, err = httputil.DumpResponse(resp, false) - } - if err == nil { - console.Debug(string(respTrace)) - } - return err -} diff --git a/restapi/client.go b/restapi/client.go index baec2d7c3..517778f3e 100644 --- a/restapi/client.go +++ b/restapi/client.go @@ -28,19 +28,6 @@ func init() { minio.MaxRetry = 1 } -// Config - see http://docs.amazonwebservices.com/AmazonS3/latest/dev/index.html?RESTAuthentication.html -type Config struct { - AccessKey string - SecretKey string - Signature string - HostURL string - AppName string - AppVersion string - AppComments []string - Debug bool - Insecure bool - Lookup minio.BucketLookupType -} // Define MinioClient interface with all functions to be implemented // by mock when testing, it should include all MinioClient respective api calls