4
go.mod
4
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
|
||||
)
|
||||
|
||||
7
go.sum
7
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=
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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=<access-key-id>/<date>/<aws-region>/<aws-service>/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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user