mirror of
https://github.com/pgsty/minio.git
synced 2026-11-02 13:52:08 +03:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 62dc0f7698 | |||
| 2d31d92271 | |||
| 1981fe2072 | |||
| f68bd37acf | |||
| 76877eb6fa | |||
| 3d66d053c7 | |||
| 0d3ae3810f | |||
| 0e31cff762 | |||
| c27110e37d | |||
| 89441a22aa | |||
| 557135185c | |||
| 4d39fd4165 | |||
| f4c03e56b8 | |||
| d2b6aa9033 | |||
| 5dd40b9377 |
@@ -24,6 +24,15 @@ linters:
|
||||
- unconvert
|
||||
- varcheck
|
||||
- gocritic
|
||||
- gofumpt
|
||||
|
||||
linters-settings:
|
||||
gofumpt:
|
||||
lang-version: "1.17"
|
||||
|
||||
# Choose whether or not to use the extra rules that are disabled
|
||||
# by default
|
||||
extra-rules: false
|
||||
|
||||
issues:
|
||||
exclude-use-default: false
|
||||
|
||||
@@ -20,7 +20,6 @@ help: ## print this help
|
||||
getdeps: ## fetch necessary dependencies
|
||||
@mkdir -p ${GOPATH}/bin
|
||||
@echo "Installing golangci-lint" && curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GOPATH)/bin v1.43.0
|
||||
@echo "Installing gofumpt" && go install mvdan.cc/gofumpt@latest
|
||||
@echo "Installing msgp" && go install -v github.com/tinylib/msgp@v1.1.7-0.20211026165309-e818a1881b0e
|
||||
@echo "Installing stringer" && go install -v golang.org/x/tools/cmd/stringer@latest
|
||||
|
||||
@@ -35,9 +34,7 @@ check-gen: ## check for updated autogenerated files
|
||||
|
||||
lint: ## runs golangci-lint suite of linters
|
||||
@echo "Running $@ check"
|
||||
@${GOPATH}/bin/golangci-lint cache clean
|
||||
@${GOPATH}/bin/golangci-lint run --build-tags kqueue --timeout=10m --config ./.golangci.yml
|
||||
@${GOPATH}/bin/gofumpt -l .
|
||||
|
||||
check: test
|
||||
test: verifiers build ## builds minio, runs linters, tests
|
||||
|
||||
@@ -87,7 +87,7 @@ func (a adminAPIHandlers) SRPeerJoin(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := globalSiteReplicationSys.InternalJoinReq(ctx, joinArg); err != nil {
|
||||
if err := globalSiteReplicationSys.PeerJoinReq(ctx, joinArg); err != nil {
|
||||
logger.LogIf(ctx, err)
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
@@ -178,6 +178,10 @@ func (a adminAPIHandlers) SRPeerReplicateIAMItem(w http.ResponseWriter, r *http.
|
||||
err = globalSiteReplicationSys.PeerPolicyMappingHandler(ctx, item.PolicyMapping)
|
||||
case madmin.SRIAMItemSTSAcc:
|
||||
err = globalSiteReplicationSys.PeerSTSAccHandler(ctx, item.STSCredential)
|
||||
case madmin.SRIAMItemIAMUser:
|
||||
err = globalSiteReplicationSys.PeerIAMUserChangeHandler(ctx, item.IAMUser)
|
||||
case madmin.SRIAMItemGroupInfo:
|
||||
err = globalSiteReplicationSys.PeerGroupInfoChangeHandler(ctx, item.GroupInfo)
|
||||
}
|
||||
if err != nil {
|
||||
logger.LogIf(ctx, err)
|
||||
@@ -310,3 +314,49 @@ func parseJSONBody(ctx context.Context, body io.Reader, v interface{}, encryptio
|
||||
|
||||
return json.Unmarshal(data, v)
|
||||
}
|
||||
|
||||
// SiteReplicationStatus - GET /minio/admin/v3/site-replication/status
|
||||
func (a adminAPIHandlers) SiteReplicationStatus(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := newContext(r, w, "SiteReplicationStatus")
|
||||
|
||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||
|
||||
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.SiteReplicationInfoAction)
|
||||
if objectAPI == nil {
|
||||
return
|
||||
}
|
||||
|
||||
info, err := globalSiteReplicationSys.SiteReplicationStatus(ctx, objectAPI)
|
||||
if err != nil {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
if err = json.NewEncoder(w).Encode(info); err != nil {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// SiteReplicationMetaInfo - GET /minio/admin/v3/site-replication/metainfo
|
||||
func (a adminAPIHandlers) SiteReplicationMetaInfo(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := newContext(r, w, "SiteReplicationMetaInfo")
|
||||
|
||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||
|
||||
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.SiteReplicationInfoAction)
|
||||
if objectAPI == nil {
|
||||
return
|
||||
}
|
||||
|
||||
info, err := globalSiteReplicationSys.SiteReplicationMetaInfo(ctx, objectAPI)
|
||||
if err != nil {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
if err = json.NewEncoder(w).Encode(info); err != nil {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,17 @@ func (a adminAPIHandlers) RemoveUser(w http.ResponseWriter, r *http.Request) {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
|
||||
Type: madmin.SRIAMItemIAMUser,
|
||||
IAMUser: &madmin.SRIAMUser{
|
||||
AccessKey: accessKey,
|
||||
IsDeleteReq: true,
|
||||
},
|
||||
}); err != nil {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// ListUsers - GET /minio/admin/v3/list-users?bucket={bucket}
|
||||
@@ -220,11 +231,20 @@ func (a adminAPIHandlers) UpdateGroupMembers(w http.ResponseWriter, r *http.Requ
|
||||
} else {
|
||||
err = globalIAMSys.AddUsersToGroup(ctx, updReq.Group, updReq.Members)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
|
||||
Type: madmin.SRIAMItemGroupInfo,
|
||||
GroupInfo: &madmin.SRGroupInfo{
|
||||
UpdateReq: updReq,
|
||||
},
|
||||
}); err != nil {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// GetGroup - /minio/admin/v3/group?group=mygroup1
|
||||
@@ -427,6 +447,18 @@ func (a adminAPIHandlers) AddUser(w http.ResponseWriter, r *http.Request) {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
|
||||
Type: madmin.SRIAMItemIAMUser,
|
||||
IAMUser: &madmin.SRIAMUser{
|
||||
AccessKey: accessKey,
|
||||
IsDeleteReq: false,
|
||||
UserReq: &ureq,
|
||||
},
|
||||
}); err != nil {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// AddServiceAccount - PUT /minio/admin/v3/add-service-account
|
||||
@@ -585,14 +617,9 @@ func (a adminAPIHandlers) AddServiceAccount(w http.ResponseWriter, r *http.Reque
|
||||
return
|
||||
}
|
||||
|
||||
// Call hook for cluster-replication.
|
||||
//
|
||||
// FIXME: This wont work in an OpenID situation as the parent credential
|
||||
// may not be present on peer clusters to provide inherited policies.
|
||||
// Also, we should not be replicating root user's service account - as
|
||||
// they are not authenticated by a common external IDP, so we skip when
|
||||
// opts.ldapUser == "".
|
||||
if _, isLDAPAccount := opts.claims[ldapUserN]; isLDAPAccount {
|
||||
// Call hook for cluster-replication if the service account is not for a
|
||||
// root user.
|
||||
if newCred.ParentUser != globalActiveCred.AccessKey {
|
||||
err = globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
|
||||
Type: madmin.SRIAMItemSvcAcc,
|
||||
SvcAccChange: &madmin.SRSvcAccChange{
|
||||
|
||||
@@ -193,6 +193,9 @@ func registerAdminRouter(router *mux.Router, enableConfigOps bool) {
|
||||
adminRouter.Methods(http.MethodPut).Path(adminVersion + "/site-replication/add").HandlerFunc(gz(httpTraceHdrs(adminAPI.SiteReplicationAdd)))
|
||||
adminRouter.Methods(http.MethodPut).Path(adminVersion + "/site-replication/disable").HandlerFunc(gz(httpTraceHdrs(adminAPI.SiteReplicationDisable)))
|
||||
adminRouter.Methods(http.MethodGet).Path(adminVersion + "/site-replication/info").HandlerFunc(gz(httpTraceHdrs(adminAPI.SiteReplicationInfo)))
|
||||
adminRouter.Methods(http.MethodGet).Path(adminVersion + "/site-replication/metainfo").HandlerFunc(gz(httpTraceHdrs(adminAPI.SiteReplicationMetaInfo)))
|
||||
adminRouter.Methods(http.MethodGet).Path(adminVersion + "/site-replication/status").HandlerFunc(gz(httpTraceHdrs(adminAPI.SiteReplicationStatus)))
|
||||
|
||||
adminRouter.Methods(http.MethodPut).Path(adminVersion + "/site-replication/peer/join").HandlerFunc(gz(httpTraceHdrs(adminAPI.SRPeerJoin)))
|
||||
adminRouter.Methods(http.MethodPut).Path(adminVersion+"/site-replication/peer/bucket-ops").HandlerFunc(gz(httpTraceHdrs(adminAPI.SRPeerBucketOps))).Queries("bucket", "{bucket:.*}").Queries("operation", "{operation:.*}")
|
||||
adminRouter.Methods(http.MethodPut).Path(adminVersion + "/site-replication/peer/iam-item").HandlerFunc(gz(httpTraceHdrs(adminAPI.SRPeerReplicateIAMItem)))
|
||||
|
||||
@@ -576,6 +576,9 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter,
|
||||
return
|
||||
}
|
||||
|
||||
// Disable timeouts and cancellation
|
||||
ctx = bgContext(ctx)
|
||||
|
||||
deleteList := toNames(objectsToDelete)
|
||||
dObjects, errs := deleteObjectsFn(ctx, bucket, deleteList, ObjectOptions{
|
||||
Versioned: versioned,
|
||||
|
||||
@@ -58,6 +58,10 @@ func (sys *BucketObjectLockSys) Get(bucketName string) (r objectlock.Retention,
|
||||
// enforceRetentionForDeletion checks if it is appropriate to remove an
|
||||
// object according to locking configuration when this is lifecycle/ bucket quota asking.
|
||||
func enforceRetentionForDeletion(ctx context.Context, objInfo ObjectInfo) (locked bool) {
|
||||
if objInfo.DeleteMarker {
|
||||
return false
|
||||
}
|
||||
|
||||
lhold := objectlock.GetObjectLegalHoldMeta(objInfo.UserDefined)
|
||||
if lhold.Status.Valid() && lhold.Status == objectlock.LegalHoldOn {
|
||||
return true
|
||||
|
||||
+5
-9
@@ -154,7 +154,7 @@ func enforceFIFOQuotaBucket(ctx context.Context, objectAPI ObjectLayer, bucket s
|
||||
// ModTime to find the oldest objects in bucket to delete. In
|
||||
// the context of bucket quota enforcement - number of hits are
|
||||
// irrelevant.
|
||||
scorer, err := newFileScorer(toFree, time.Now().Unix(), 1)
|
||||
scorer, err := newFileScorer(toFree, UTCNow().Unix(), 1)
|
||||
if err != nil {
|
||||
logger.LogIf(ctx, err)
|
||||
return
|
||||
@@ -162,11 +162,6 @@ func enforceFIFOQuotaBucket(ctx context.Context, objectAPI ObjectLayer, bucket s
|
||||
|
||||
rcfg, _ := globalBucketObjectLockSys.Get(bucket)
|
||||
for obj := range objInfoCh {
|
||||
if obj.DeleteMarker {
|
||||
// Delete markers are automatically added for FIFO purge.
|
||||
scorer.addFileWithObjInfo(obj, 1)
|
||||
continue
|
||||
}
|
||||
// skip objects currently under retention
|
||||
if rcfg.LockEnabled && enforceRetentionForDeletion(ctx, obj) {
|
||||
continue
|
||||
@@ -178,6 +173,7 @@ func enforceFIFOQuotaBucket(ctx context.Context, objectAPI ObjectLayer, bucket s
|
||||
if scorer.seenBytes <= cfg.Quota {
|
||||
return
|
||||
}
|
||||
|
||||
// Calculate how much we want to delete now.
|
||||
toFreeNow := scorer.seenBytes - cfg.Quota
|
||||
// We were less over quota than we thought. Adjust so we delete less.
|
||||
@@ -211,9 +207,9 @@ func enforceFIFOQuotaBucket(ctx context.Context, objectAPI ObjectLayer, bucket s
|
||||
_, deleteErrs := objectAPI.DeleteObjects(ctx, bucket, objects, ObjectOptions{
|
||||
Versioned: versioned,
|
||||
})
|
||||
for i := range deleteErrs {
|
||||
if deleteErrs[i] != nil {
|
||||
logger.LogIf(ctx, deleteErrs[i])
|
||||
for j := range deleteErrs {
|
||||
if deleteErrs[j] != nil {
|
||||
logger.LogIf(ctx, deleteErrs[j])
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -332,8 +332,10 @@ func (sys *BucketTargetSys) set(bucket BucketInfo, meta BucketMetadata) {
|
||||
}
|
||||
|
||||
// getRemoteTargetInstanceTransport contains a singleton roundtripper.
|
||||
var getRemoteTargetInstanceTransport http.RoundTripper
|
||||
var getRemoteTargetInstanceTransportOnce sync.Once
|
||||
var (
|
||||
getRemoteTargetInstanceTransport http.RoundTripper
|
||||
getRemoteTargetInstanceTransportOnce sync.Once
|
||||
)
|
||||
|
||||
// Returns a minio-go Client configured to access remote host described in replication target config.
|
||||
func (sys *BucketTargetSys) getRemoteTargetClient(tcfg *madmin.BucketTarget) (*TargetClient, error) {
|
||||
|
||||
@@ -49,6 +49,7 @@ import (
|
||||
"github.com/minio/console/restapi"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
"github.com/minio/kes"
|
||||
"github.com/minio/madmin-go"
|
||||
"github.com/minio/minio-go/v7"
|
||||
"github.com/minio/minio-go/v7/pkg/credentials"
|
||||
"github.com/minio/minio-go/v7/pkg/set"
|
||||
@@ -132,6 +133,8 @@ func init() {
|
||||
console.SetColor("Debug", fcolor.New())
|
||||
|
||||
gob.Register(StorageErr(""))
|
||||
gob.Register(madmin.TimeInfo{})
|
||||
gob.Register(map[string]interface{}{})
|
||||
|
||||
defaultAWSCredProvider = []credentials.Provider{
|
||||
&credentials.IAM{
|
||||
@@ -908,3 +911,32 @@ func contextCanceled(ctx context.Context) bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// bgContext returns a context that can be used for async operations.
|
||||
// Cancellation/timeouts are removed, so parent cancellations/timeout will
|
||||
// not propagate from parent.
|
||||
// Context values are preserved.
|
||||
// This can be used for goroutines that live beyond the parent context.
|
||||
func bgContext(parent context.Context) context.Context {
|
||||
return bgCtx{parent: parent}
|
||||
}
|
||||
|
||||
type bgCtx struct {
|
||||
parent context.Context
|
||||
}
|
||||
|
||||
func (a bgCtx) Done() <-chan struct{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a bgCtx) Err() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a bgCtx) Deadline() (deadline time.Time, ok bool) {
|
||||
return time.Time{}, false
|
||||
}
|
||||
|
||||
func (a bgCtx) Value(key interface{}) interface{} {
|
||||
return a.parent.Value(key)
|
||||
}
|
||||
|
||||
@@ -1197,6 +1197,12 @@ func (er erasureObjects) DeleteObjects(ctx context.Context, bucket string, objec
|
||||
continue
|
||||
}
|
||||
for _, v := range dedupVersions[i].Versions {
|
||||
if err == errFileNotFound || err == errFileVersionNotFound {
|
||||
if !dobjects[v.Idx].DeleteMarker {
|
||||
// Not delete marker, if not found, ok.
|
||||
continue
|
||||
}
|
||||
}
|
||||
delObjErrs[index][v.Idx] = err
|
||||
}
|
||||
}
|
||||
|
||||
+17
-9
@@ -974,17 +974,25 @@ func (s *erasureSets) DeleteObjects(ctx context.Context, bucket string, objects
|
||||
|
||||
// Invoke bulk delete on objects per set and save
|
||||
// the result of the delete operation
|
||||
for _, objsGroup := range objSetMap {
|
||||
set := s.getHashedSet(objsGroup[0].object.ObjectName)
|
||||
dobjects, errs := set.DeleteObjects(ctx, bucket, toNames(objsGroup), opts)
|
||||
for i, obj := range objsGroup {
|
||||
delErrs[obj.origIndex] = errs[i]
|
||||
delObjects[obj.origIndex] = dobjects[i]
|
||||
if errs[i] == nil {
|
||||
auditObjectErasureSet(ctx, obj.object.ObjectName, set)
|
||||
var wg sync.WaitGroup
|
||||
var mu sync.Mutex
|
||||
wg.Add(len(objSetMap))
|
||||
for setIdx, objsGroup := range objSetMap {
|
||||
go func(set *erasureObjects, group []delObj) {
|
||||
defer wg.Done()
|
||||
dobjects, errs := set.DeleteObjects(ctx, bucket, toNames(group), opts)
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
for i, obj := range group {
|
||||
delErrs[obj.origIndex] = errs[i]
|
||||
delObjects[obj.origIndex] = dobjects[i]
|
||||
if errs[i] == nil {
|
||||
auditObjectErasureSet(ctx, obj.object.ObjectName, set)
|
||||
}
|
||||
}
|
||||
}
|
||||
}(s.sets[setIdx], objsGroup)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
return delObjects, delErrs
|
||||
}
|
||||
|
||||
@@ -118,6 +118,9 @@ const (
|
||||
|
||||
// diskMinInodes is the minimum number of inodes we want free on a disk to perform writes.
|
||||
diskMinInodes = 1000
|
||||
|
||||
// tlsClientSessionCacheSize is the cache size for client sessions.
|
||||
tlsClientSessionCacheSize = 100
|
||||
)
|
||||
|
||||
var globalCLIContext = struct {
|
||||
|
||||
@@ -636,6 +636,7 @@ func (sys *IAMSys) SetTempUser(ctx context.Context, accessKey string, cred auth.
|
||||
}
|
||||
|
||||
sys.notifyForUser(ctx, cred.AccessKey, true)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -159,10 +159,15 @@ func toObjectErr(err error, params ...string) error {
|
||||
apiErr.Object = decodeDirObject(params[1])
|
||||
}
|
||||
return apiErr
|
||||
case io.ErrUnexpectedEOF.Error(), io.ErrShortWrite.Error():
|
||||
return IncompleteBody{}
|
||||
case context.Canceled.Error(), context.DeadlineExceeded.Error():
|
||||
return IncompleteBody{}
|
||||
case io.ErrUnexpectedEOF.Error(), io.ErrShortWrite.Error(), context.Canceled.Error(), context.DeadlineExceeded.Error():
|
||||
apiErr := IncompleteBody{}
|
||||
if len(params) >= 1 {
|
||||
apiErr.Bucket = params[0]
|
||||
}
|
||||
if len(params) >= 2 {
|
||||
apiErr.Object = decodeDirObject(params[1])
|
||||
}
|
||||
return apiErr
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -422,12 +422,21 @@ func (client *peerRESTClient) GetSELinuxInfo(ctx context.Context) (info madmin.S
|
||||
|
||||
// GetSysConfig - fetch sys config for a remote node.
|
||||
func (client *peerRESTClient) GetSysConfig(ctx context.Context) (info madmin.SysConfig, err error) {
|
||||
sent := time.Now()
|
||||
respBody, err := client.callWithContext(ctx, peerRESTMethodSysConfig, nil, nil, -1)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
roundtrip := int32(time.Since(sent).Milliseconds())
|
||||
defer http.DrainBody(respBody)
|
||||
|
||||
err = gob.NewDecoder(respBody).Decode(&info)
|
||||
cfg := info.Config["time-info"]
|
||||
if cfg != nil {
|
||||
ti := cfg.(madmin.TimeInfo)
|
||||
ti.RoundtripDuration = roundtrip
|
||||
info.Config["time-info"] = ti
|
||||
}
|
||||
return info, err
|
||||
}
|
||||
|
||||
|
||||
+8
-6
@@ -181,15 +181,17 @@ func serverHandleCmdArgs(ctx *cli.Context) {
|
||||
|
||||
// allow transport to be HTTP/1.1 for proxying.
|
||||
globalProxyTransport = newCustomHTTPProxyTransport(&tls.Config{
|
||||
RootCAs: globalRootCAs,
|
||||
CipherSuites: fips.CipherSuitesTLS(),
|
||||
CurvePreferences: fips.EllipticCurvesTLS(),
|
||||
RootCAs: globalRootCAs,
|
||||
CipherSuites: fips.CipherSuitesTLS(),
|
||||
CurvePreferences: fips.EllipticCurvesTLS(),
|
||||
ClientSessionCache: tls.NewLRUClientSessionCache(tlsClientSessionCacheSize),
|
||||
}, rest.DefaultTimeout)()
|
||||
globalProxyEndpoints = GetProxyEndpoints(globalEndpoints)
|
||||
globalInternodeTransport = newInternodeHTTPTransport(&tls.Config{
|
||||
RootCAs: globalRootCAs,
|
||||
CipherSuites: fips.CipherSuitesTLS(),
|
||||
CurvePreferences: fips.EllipticCurvesTLS(),
|
||||
RootCAs: globalRootCAs,
|
||||
CipherSuites: fips.CipherSuitesTLS(),
|
||||
CurvePreferences: fips.EllipticCurvesTLS(),
|
||||
ClientSessionCache: tls.NewLRUClientSessionCache(tlsClientSessionCacheSize),
|
||||
}, rest.DefaultTimeout)()
|
||||
|
||||
// On macOS, if a process already listens on LOCALIPADDR:PORT, net.Listen() falls back
|
||||
|
||||
+655
-32
@@ -28,6 +28,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -41,7 +42,9 @@ import (
|
||||
"github.com/minio/minio/internal/auth"
|
||||
sreplication "github.com/minio/minio/internal/bucket/replication"
|
||||
"github.com/minio/minio/internal/logger"
|
||||
"github.com/minio/minio/internal/sync/errgroup"
|
||||
"github.com/minio/pkg/bucket/policy"
|
||||
bktpolicy "github.com/minio/pkg/bucket/policy"
|
||||
iampolicy "github.com/minio/pkg/iam/policy"
|
||||
)
|
||||
|
||||
@@ -510,9 +513,9 @@ func (c *SiteReplicationSys) AddPeerClusters(ctx context.Context, psites []madmi
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// InternalJoinReq - internal API handler to respond to a peer cluster's request
|
||||
// PeerJoinReq - internal API handler to respond to a peer cluster's request
|
||||
// to join.
|
||||
func (c *SiteReplicationSys) InternalJoinReq(ctx context.Context, arg madmin.SRPeerJoinReq) error {
|
||||
func (c *SiteReplicationSys) PeerJoinReq(ctx context.Context, arg madmin.SRPeerJoinReq) error {
|
||||
var ourName string
|
||||
for d, p := range arg.Peers {
|
||||
if d == globalDeploymentID {
|
||||
@@ -549,13 +552,19 @@ func (c *SiteReplicationSys) InternalJoinReq(ctx context.Context, arg madmin.SRP
|
||||
// GetIDPSettings returns info about the configured identity provider. It is
|
||||
// used to validate that all peers have the same IDP.
|
||||
func (c *SiteReplicationSys) GetIDPSettings(ctx context.Context) madmin.IDPSettings {
|
||||
return madmin.IDPSettings{
|
||||
s := madmin.IDPSettings{}
|
||||
s.LDAP = madmin.LDAPSettings{
|
||||
IsLDAPEnabled: globalLDAPConfig.Enabled,
|
||||
LDAPUserDNSearchBase: globalLDAPConfig.UserDNSearchBaseDN,
|
||||
LDAPUserDNSearchFilter: globalLDAPConfig.UserDNSearchFilter,
|
||||
LDAPGroupSearchBase: globalLDAPConfig.GroupSearchBaseDistName,
|
||||
LDAPGroupSearchFilter: globalLDAPConfig.GroupSearchFilter,
|
||||
}
|
||||
s.OpenID = globalOpenIDConfig.GetSettings()
|
||||
if s.OpenID.Enabled {
|
||||
s.OpenID.Region = globalSite.Region
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (c *SiteReplicationSys) validateIDPSettings(ctx context.Context, peers []PeerSiteInfo) (bool, error) {
|
||||
@@ -578,13 +587,8 @@ func (c *SiteReplicationSys) validateIDPSettings(ctx context.Context, peers []Pe
|
||||
s = append(s, is)
|
||||
}
|
||||
|
||||
for _, v := range s {
|
||||
if !v.IsLDAPEnabled {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
for i := 1; i < len(s); i++ {
|
||||
if s[i] != s[0] {
|
||||
if !reflect.DeepEqual(s[i], s[0]) {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
@@ -982,12 +986,8 @@ func (c *SiteReplicationSys) PeerBucketDeleteHandler(ctx context.Context, bucket
|
||||
// OpenID, such mappings are provided from the IDP directly and so are not
|
||||
// applicable here.
|
||||
//
|
||||
// Only certain service accounts can be replicated:
|
||||
//
|
||||
// Service accounts created for STS credentials using an external IDP: such STS
|
||||
// credentials would be valid on the peer clusters as they are assumed to be
|
||||
// using the same external IDP. Service accounts when using internal IDP or for
|
||||
// root user will not be replicated.
|
||||
// Service accounts are replicated as long as they are not meant for the root
|
||||
// user.
|
||||
//
|
||||
// STS accounts are replicated, but only if the session token is verifiable
|
||||
// using the local cluster's root credential.
|
||||
@@ -1029,6 +1029,44 @@ func (c *SiteReplicationSys) PeerAddPolicyHandler(ctx context.Context, policyNam
|
||||
return nil
|
||||
}
|
||||
|
||||
// PeerIAMUserChangeHandler - copies IAM user to local.
|
||||
func (c *SiteReplicationSys) PeerIAMUserChangeHandler(ctx context.Context, change *madmin.SRIAMUser) error {
|
||||
if change == nil {
|
||||
return errSRInvalidRequest(errInvalidArgument)
|
||||
}
|
||||
var err error
|
||||
if change.IsDeleteReq {
|
||||
err = globalIAMSys.DeleteUser(ctx, change.AccessKey, true)
|
||||
} else {
|
||||
if change.UserReq == nil {
|
||||
return errSRInvalidRequest(errInvalidArgument)
|
||||
}
|
||||
err = globalIAMSys.CreateUser(ctx, change.AccessKey, *change.UserReq)
|
||||
}
|
||||
if err != nil {
|
||||
return wrapSRErr(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PeerGroupInfoChangeHandler - copies group changes to local.
|
||||
func (c *SiteReplicationSys) PeerGroupInfoChangeHandler(ctx context.Context, change *madmin.SRGroupInfo) error {
|
||||
if change == nil {
|
||||
return errSRInvalidRequest(errInvalidArgument)
|
||||
}
|
||||
updReq := change.UpdateReq
|
||||
var err error
|
||||
if updReq.IsRemove {
|
||||
err = globalIAMSys.RemoveUsersFromGroup(ctx, updReq.Group, updReq.Members)
|
||||
} else {
|
||||
err = globalIAMSys.AddUsersToGroup(ctx, updReq.Group, updReq.Members)
|
||||
}
|
||||
if err != nil {
|
||||
return wrapSRErr(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PeerSvcAccChangeHandler - copies service-account change to local.
|
||||
func (c *SiteReplicationSys) PeerSvcAccChangeHandler(ctx context.Context, change *madmin.SRSvcAccChange) error {
|
||||
if change == nil {
|
||||
@@ -1118,31 +1156,31 @@ func (c *SiteReplicationSys) PeerSTSAccHandler(ctx context.Context, stsCred *mad
|
||||
return fmt.Errorf("Expiry claim was not found: %v", mapClaims)
|
||||
}
|
||||
|
||||
// Extract the username and lookup DN and groups in LDAP.
|
||||
ldapUser, ok := claims.Lookup(ldapUserN)
|
||||
if !ok {
|
||||
return fmt.Errorf("Could not find LDAP username in claims: %v", mapClaims)
|
||||
}
|
||||
|
||||
// Need to lookup the groups from LDAP.
|
||||
ldapUserDN, ldapGroups, err := globalLDAPConfig.LookupUserDN(ldapUser)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to query LDAP server for %s: %v", ldapUser, err)
|
||||
}
|
||||
|
||||
cred := auth.Credentials{
|
||||
AccessKey: stsCred.AccessKey,
|
||||
SecretKey: stsCred.SecretKey,
|
||||
Expiration: time.Unix(expiry, 0).UTC(),
|
||||
SessionToken: stsCred.SessionToken,
|
||||
ParentUser: stsCred.ParentUser,
|
||||
Status: auth.AccountOn,
|
||||
ParentUser: ldapUserDN,
|
||||
Groups: ldapGroups,
|
||||
}
|
||||
|
||||
// Extract the username and lookup DN and groups in LDAP.
|
||||
ldapUser, isLDAPSTS := claims.Lookup(ldapUserN)
|
||||
switch {
|
||||
case isLDAPSTS:
|
||||
// Need to lookup the groups from LDAP.
|
||||
_, ldapGroups, err := globalLDAPConfig.LookupUserDN(ldapUser)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to query LDAP server for %s: %v", ldapUser, err)
|
||||
}
|
||||
|
||||
cred.Groups = ldapGroups
|
||||
}
|
||||
|
||||
// Set these credentials to IAM.
|
||||
if err := globalIAMSys.SetTempUser(ctx, cred.AccessKey, cred, ""); err != nil {
|
||||
return fmt.Errorf("unable to save STS credential: %v", err)
|
||||
if err := globalIAMSys.SetTempUser(ctx, cred.AccessKey, cred, stsCred.ParentPolicyMapping); err != nil {
|
||||
return fmt.Errorf("unable to save STS credential and/or parent policy mapping: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -1495,6 +1533,11 @@ func (c *SiteReplicationSys) syncLocalToPeers(ctx context.Context) error {
|
||||
return errSRBackendIssue(err)
|
||||
}
|
||||
for user, acc := range serviceAccounts {
|
||||
if user == siteReplicatorSvcAcc {
|
||||
// skip the site replicate svc account as it is
|
||||
// already replicated.
|
||||
continue
|
||||
}
|
||||
claims, err := globalIAMSys.GetClaimsForSvcAcc(ctx, acc.AccessKey)
|
||||
if err != nil {
|
||||
return errSRBackendIssue(err)
|
||||
@@ -1640,7 +1683,8 @@ func newRemoteClusterHTTPTransport() *http.Transport {
|
||||
tr := &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
TLSClientConfig: &tls.Config{
|
||||
RootCAs: globalRootCAs,
|
||||
RootCAs: globalRootCAs,
|
||||
ClientSessionCache: tls.NewLRUClientSessionCache(tlsClientSessionCacheSize),
|
||||
},
|
||||
}
|
||||
return tr
|
||||
@@ -1689,3 +1733,582 @@ func getMissingSiteNames(oldDeps, newDeps set.StringSet, currSites []madmin.Peer
|
||||
}
|
||||
return diffSlc
|
||||
}
|
||||
|
||||
type srBucketMetaInfo struct {
|
||||
madmin.SRBucketInfo
|
||||
DeploymentID string
|
||||
}
|
||||
|
||||
type srPolicy struct {
|
||||
policy json.RawMessage
|
||||
DeploymentID string
|
||||
}
|
||||
|
||||
type srUserPolicyMapping struct {
|
||||
madmin.SRPolicyMapping
|
||||
DeploymentID string
|
||||
}
|
||||
|
||||
type srGroupPolicyMapping struct {
|
||||
madmin.SRPolicyMapping
|
||||
DeploymentID string
|
||||
}
|
||||
|
||||
// SiteReplicationStatus returns the site replication status across clusters participating in site replication.
|
||||
func (c *SiteReplicationSys) SiteReplicationStatus(ctx context.Context, objAPI ObjectLayer) (info madmin.SRStatusInfo, err error) {
|
||||
c.RLock()
|
||||
defer c.RUnlock()
|
||||
if !c.enabled {
|
||||
return info, err
|
||||
}
|
||||
|
||||
sris := make([]madmin.SRInfo, len(c.state.Peers))
|
||||
sriErrs := make([]error, len(c.state.Peers))
|
||||
g := errgroup.WithNErrs(len(c.state.Peers))
|
||||
var depIDs []string
|
||||
for d := range c.state.Peers {
|
||||
depIDs = append(depIDs, d)
|
||||
}
|
||||
for index := range depIDs {
|
||||
index := index
|
||||
if depIDs[index] == globalDeploymentID {
|
||||
g.Go(func() error {
|
||||
sris[index], sriErrs[index] = c.SiteReplicationMetaInfo(ctx, objAPI)
|
||||
return nil
|
||||
}, index)
|
||||
continue
|
||||
}
|
||||
g.Go(func() error {
|
||||
admClient, err := c.getAdminClient(ctx, depIDs[index])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sris[index], sriErrs[index] = admClient.SRMetaInfo(ctx)
|
||||
return nil
|
||||
}, index)
|
||||
}
|
||||
// Wait for the go routines.
|
||||
g.Wait()
|
||||
|
||||
for _, serr := range sriErrs {
|
||||
if serr != nil {
|
||||
return info, errSRBackendIssue(serr)
|
||||
}
|
||||
}
|
||||
info.Enabled = true
|
||||
info.Sites = make(map[string]madmin.PeerInfo, len(c.state.Peers))
|
||||
for d, peer := range c.state.Peers {
|
||||
info.Sites[d] = peer
|
||||
}
|
||||
|
||||
var maxBuckets int
|
||||
depIdxes := make(map[string]int)
|
||||
for i, sri := range sris {
|
||||
depIdxes[sri.DeploymentID] = i
|
||||
if len(sri.Buckets) > maxBuckets {
|
||||
maxBuckets = len(sri.Buckets)
|
||||
}
|
||||
}
|
||||
// mapping b/w entity and entity config across sites
|
||||
bucketStats := make(map[string][]srBucketMetaInfo)
|
||||
policyStats := make(map[string][]srPolicy)
|
||||
userPolicyStats := make(map[string][]srUserPolicyMapping)
|
||||
groupPolicyStats := make(map[string][]srGroupPolicyMapping)
|
||||
|
||||
numSites := len(sris)
|
||||
for _, sri := range sris {
|
||||
for b, si := range sri.Buckets {
|
||||
if _, ok := bucketStats[si.Bucket]; !ok {
|
||||
bucketStats[b] = make([]srBucketMetaInfo, 0, numSites)
|
||||
}
|
||||
bucketStats[b] = append(bucketStats[b], srBucketMetaInfo{SRBucketInfo: si, DeploymentID: sri.DeploymentID})
|
||||
}
|
||||
for pname, policy := range sri.Policies {
|
||||
if _, ok := policyStats[pname]; !ok {
|
||||
policyStats[pname] = make([]srPolicy, 0, numSites)
|
||||
}
|
||||
policyStats[pname] = append(policyStats[pname], srPolicy{policy: policy, DeploymentID: sri.DeploymentID})
|
||||
}
|
||||
for user, policy := range sri.UserPolicies {
|
||||
if _, ok := userPolicyStats[user]; !ok {
|
||||
userPolicyStats[user] = make([]srUserPolicyMapping, 0, numSites)
|
||||
}
|
||||
userPolicyStats[user] = append(userPolicyStats[user], srUserPolicyMapping{SRPolicyMapping: policy, DeploymentID: sri.DeploymentID})
|
||||
}
|
||||
for group, policy := range sri.GroupPolicies {
|
||||
if _, ok := userPolicyStats[group]; !ok {
|
||||
groupPolicyStats[group] = make([]srGroupPolicyMapping, 0, numSites)
|
||||
}
|
||||
groupPolicyStats[group] = append(groupPolicyStats[group], srGroupPolicyMapping{SRPolicyMapping: policy, DeploymentID: sri.DeploymentID})
|
||||
}
|
||||
}
|
||||
info.StatsSummary = make(map[string]madmin.SRSiteSummary, len(c.state.Peers))
|
||||
info.BucketMismatches = make(map[string]map[string]madmin.SRBucketStatsSummary)
|
||||
info.PolicyMismatches = make(map[string]map[string]madmin.SRPolicyStatsSummary)
|
||||
info.UserMismatches = make(map[string]map[string]madmin.SRUserStatsSummary)
|
||||
info.GroupMismatches = make(map[string]map[string]madmin.SRGroupStatsSummary)
|
||||
// collect user policy mapping replication status across sites
|
||||
for u, pslc := range userPolicyStats {
|
||||
policySet := set.NewStringSet()
|
||||
uPolicyCount := 0
|
||||
for _, ps := range pslc {
|
||||
policyBytes, err := json.Marshal(ps)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
uPolicyCount++
|
||||
if policyStr := string(policyBytes); !policySet.Contains(policyStr) {
|
||||
policySet.Add(policyStr)
|
||||
}
|
||||
}
|
||||
policyMismatch := !isReplicated(uPolicyCount, numSites, policySet)
|
||||
if policyMismatch {
|
||||
for _, ps := range pslc {
|
||||
dID := depIdxes[ps.DeploymentID]
|
||||
_, hasUser := sris[dID].UserPolicies[u]
|
||||
|
||||
info.UserMismatches[u][ps.DeploymentID] = madmin.SRUserStatsSummary{
|
||||
PolicyMismatch: policyMismatch,
|
||||
UserMissing: !hasUser,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// collect user policy mapping replication status across sites
|
||||
|
||||
for g, pslc := range groupPolicyStats {
|
||||
policySet := set.NewStringSet()
|
||||
gPolicyCount := 0
|
||||
for _, ps := range pslc {
|
||||
policyBytes, err := json.Marshal(ps)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
gPolicyCount++
|
||||
if policyStr := string(policyBytes); !policySet.Contains(policyStr) {
|
||||
policySet.Add(policyStr)
|
||||
}
|
||||
}
|
||||
policyMismatch := !isReplicated(gPolicyCount, numSites, policySet)
|
||||
if policyMismatch {
|
||||
for _, ps := range pslc {
|
||||
dID := depIdxes[ps.DeploymentID]
|
||||
_, hasGroup := sris[dID].GroupPolicies[g]
|
||||
|
||||
info.GroupMismatches[g][ps.DeploymentID] = madmin.SRGroupStatsSummary{
|
||||
PolicyMismatch: policyMismatch,
|
||||
GroupMissing: !hasGroup,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// collect IAM policy replication status across sites
|
||||
|
||||
for p, pslc := range policyStats {
|
||||
var policies []*iampolicy.Policy
|
||||
uPolicyCount := 0
|
||||
for _, ps := range pslc {
|
||||
plcy, err := iampolicy.ParseConfig(bytes.NewReader(ps.policy))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
policies = append(policies, plcy)
|
||||
uPolicyCount++
|
||||
sum := info.StatsSummary[ps.DeploymentID]
|
||||
sum.TotalIAMPoliciesCount++
|
||||
info.StatsSummary[ps.DeploymentID] = sum
|
||||
}
|
||||
policyMismatch := !isIAMPolicyReplicated(uPolicyCount, numSites, policies)
|
||||
switch {
|
||||
case policyMismatch:
|
||||
for _, ps := range pslc {
|
||||
dID := depIdxes[ps.DeploymentID]
|
||||
_, hasPolicy := sris[dID].Policies[p]
|
||||
if len(info.PolicyMismatches[p]) == 0 {
|
||||
info.PolicyMismatches[p] = make(map[string]madmin.SRPolicyStatsSummary)
|
||||
}
|
||||
info.PolicyMismatches[p][ps.DeploymentID] = madmin.SRPolicyStatsSummary{
|
||||
PolicyMismatch: policyMismatch,
|
||||
PolicyMissing: !hasPolicy,
|
||||
}
|
||||
}
|
||||
default:
|
||||
// no mismatch
|
||||
for _, s := range pslc {
|
||||
sum := info.StatsSummary[s.DeploymentID]
|
||||
if !policyMismatch {
|
||||
sum.ReplicatedIAMPolicies++
|
||||
}
|
||||
info.StatsSummary[s.DeploymentID] = sum
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// collect bucket metadata replication stats across sites
|
||||
for b, slc := range bucketStats {
|
||||
tagSet := set.NewStringSet()
|
||||
olockConfigSet := set.NewStringSet()
|
||||
var policies []*bktpolicy.Policy
|
||||
var replCfgs []*sreplication.Config
|
||||
sseCfgSet := set.NewStringSet()
|
||||
var tagCount, olockCfgCount, sseCfgCount int
|
||||
for _, s := range slc {
|
||||
if s.ReplicationConfig != nil {
|
||||
cfgBytes, err := base64.StdEncoding.DecodeString(*s.ReplicationConfig)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
cfg, err := sreplication.ParseConfig(bytes.NewReader(cfgBytes))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
replCfgs = append(replCfgs, cfg)
|
||||
}
|
||||
if s.Tags != nil {
|
||||
tagBytes, err := base64.StdEncoding.DecodeString(*s.Tags)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
tagCount++
|
||||
if !tagSet.Contains(string(tagBytes)) {
|
||||
tagSet.Add(string(tagBytes))
|
||||
}
|
||||
}
|
||||
if len(s.Policy) > 0 {
|
||||
plcy, err := bktpolicy.ParseConfig(bytes.NewReader(s.Policy), b)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
policies = append(policies, plcy)
|
||||
}
|
||||
if s.ObjectLockConfig != nil {
|
||||
olockCfgCount++
|
||||
if !olockConfigSet.Contains(*s.ObjectLockConfig) {
|
||||
olockConfigSet.Add(*s.ObjectLockConfig)
|
||||
}
|
||||
}
|
||||
if s.SSEConfig != nil {
|
||||
if !sseCfgSet.Contains(*s.SSEConfig) {
|
||||
sseCfgSet.Add(*s.SSEConfig)
|
||||
}
|
||||
sseCfgCount++
|
||||
}
|
||||
ss, ok := info.StatsSummary[s.DeploymentID]
|
||||
if !ok {
|
||||
ss = madmin.SRSiteSummary{}
|
||||
}
|
||||
// increment total number of replicated buckets
|
||||
if len(slc) == numSites {
|
||||
ss.ReplicatedBuckets++
|
||||
}
|
||||
ss.TotalBucketsCount++
|
||||
if tagCount > 0 {
|
||||
ss.TotalTagsCount++
|
||||
}
|
||||
if olockCfgCount > 0 {
|
||||
ss.TotalLockConfigCount++
|
||||
}
|
||||
if sseCfgCount > 0 {
|
||||
ss.TotalSSEConfigCount++
|
||||
}
|
||||
if len(policies) > 0 {
|
||||
ss.TotalBucketPoliciesCount++
|
||||
}
|
||||
info.StatsSummary[s.DeploymentID] = ss
|
||||
}
|
||||
tagMismatch := !isReplicated(tagCount, numSites, tagSet)
|
||||
olockCfgMismatch := !isReplicated(olockCfgCount, numSites, olockConfigSet)
|
||||
sseCfgMismatch := !isReplicated(sseCfgCount, numSites, sseCfgSet)
|
||||
policyMismatch := !isBktPolicyReplicated(numSites, policies)
|
||||
replCfgMismatch := !isBktReplCfgReplicated(numSites, replCfgs)
|
||||
switch {
|
||||
case tagMismatch, olockCfgMismatch, sseCfgMismatch, policyMismatch, replCfgMismatch:
|
||||
info.BucketMismatches[b] = make(map[string]madmin.SRBucketStatsSummary, numSites)
|
||||
for _, s := range slc {
|
||||
dID := depIdxes[s.DeploymentID]
|
||||
_, hasBucket := sris[dID].Buckets[s.Bucket]
|
||||
info.BucketMismatches[b][s.DeploymentID] = madmin.SRBucketStatsSummary{
|
||||
DeploymentID: s.DeploymentID,
|
||||
HasBucket: hasBucket,
|
||||
TagMismatch: tagMismatch,
|
||||
OLockConfigMismatch: olockCfgMismatch,
|
||||
SSEConfigMismatch: sseCfgMismatch,
|
||||
PolicyMismatch: policyMismatch,
|
||||
ReplicationCfgMismatch: replCfgMismatch,
|
||||
HasReplicationCfg: len(replCfgs) > 0,
|
||||
}
|
||||
}
|
||||
fallthrough
|
||||
default:
|
||||
// no mismatch
|
||||
for _, s := range slc {
|
||||
sum := info.StatsSummary[s.DeploymentID]
|
||||
if !olockCfgMismatch && olockCfgCount == numSites {
|
||||
sum.ReplicatedLockConfig++
|
||||
}
|
||||
if !sseCfgMismatch && sseCfgCount == numSites {
|
||||
sum.ReplicatedSSEConfig++
|
||||
}
|
||||
if !policyMismatch && len(policies) == numSites {
|
||||
sum.ReplicatedBucketPolicies++
|
||||
}
|
||||
if !tagMismatch && tagCount == numSites {
|
||||
sum.ReplicatedTags++
|
||||
}
|
||||
info.StatsSummary[s.DeploymentID] = sum
|
||||
}
|
||||
}
|
||||
}
|
||||
// maximum buckets users etc seen across sites
|
||||
info.MaxBuckets = len(bucketStats)
|
||||
info.MaxUsers = len(userPolicyStats)
|
||||
info.MaxGroups = len(groupPolicyStats)
|
||||
info.MaxPolicies = len(policyStats)
|
||||
return
|
||||
}
|
||||
|
||||
// isReplicated returns true if count of replicated matches the number of
|
||||
// sites and there is atmost one unique entry in the set.
|
||||
func isReplicated(cntReplicated, total int, valSet set.StringSet) bool {
|
||||
if cntReplicated > 0 && cntReplicated < total {
|
||||
return false
|
||||
}
|
||||
if len(valSet) > 1 {
|
||||
// mismatch - one or more sites has differing tags/policy
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// isIAMPolicyReplicated returns true if count of replicated IAM policies matches total
|
||||
// number of sites and IAM policies are identical.
|
||||
func isIAMPolicyReplicated(cntReplicated, total int, policies []*iampolicy.Policy) bool {
|
||||
if cntReplicated > 0 && cntReplicated != total {
|
||||
return false
|
||||
}
|
||||
// check if policies match between sites
|
||||
var prev *iampolicy.Policy
|
||||
for i, p := range policies {
|
||||
if i == 0 {
|
||||
prev = p
|
||||
continue
|
||||
}
|
||||
if !prev.Equals(*p) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// isBktPolicyReplicated returns true if count of replicated bucket policies matches total
|
||||
// number of sites and bucket policies are identical.
|
||||
func isBktPolicyReplicated(total int, policies []*bktpolicy.Policy) bool {
|
||||
if len(policies) > 0 && len(policies) != total {
|
||||
return false
|
||||
}
|
||||
// check if policies match between sites
|
||||
var prev *bktpolicy.Policy
|
||||
for i, p := range policies {
|
||||
if i == 0 {
|
||||
prev = p
|
||||
continue
|
||||
}
|
||||
if !prev.Equals(*p) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// isBktReplCfgReplicated returns true if all the sites have same number
|
||||
// of replication rules with all replication features enabled.
|
||||
func isBktReplCfgReplicated(total int, cfgs []*sreplication.Config) bool {
|
||||
cntReplicated := len(cfgs)
|
||||
if cntReplicated > 0 && cntReplicated != len(cfgs) {
|
||||
return false
|
||||
}
|
||||
// check if policies match between sites
|
||||
var prev *sreplication.Config
|
||||
for i, c := range cfgs {
|
||||
if i == 0 {
|
||||
prev = c
|
||||
continue
|
||||
}
|
||||
if len(prev.Rules) != len(c.Rules) {
|
||||
return false
|
||||
}
|
||||
if len(c.Rules) != total-1 {
|
||||
return false
|
||||
}
|
||||
for _, r := range c.Rules {
|
||||
if !strings.HasPrefix(r.ID, "site-repl-") {
|
||||
return false
|
||||
}
|
||||
if r.DeleteMarkerReplication.Status == sreplication.Disabled ||
|
||||
r.DeleteReplication.Status == sreplication.Disabled ||
|
||||
r.ExistingObjectReplication.Status == sreplication.Disabled ||
|
||||
r.SourceSelectionCriteria.ReplicaModifications.Status == sreplication.Disabled {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// SiteReplicationMetaInfo returns the metadata info on buckets, policies etc for the replicated site
|
||||
func (c *SiteReplicationSys) SiteReplicationMetaInfo(ctx context.Context, objAPI ObjectLayer) (info madmin.SRInfo, err error) {
|
||||
if objAPI == nil {
|
||||
return info, errSRObjectLayerNotReady
|
||||
}
|
||||
|
||||
c.RLock()
|
||||
defer c.RUnlock()
|
||||
if !c.enabled {
|
||||
return info, nil
|
||||
}
|
||||
buckets, err := objAPI.ListBuckets(ctx)
|
||||
if err != nil {
|
||||
return info, errSRBackendIssue(err)
|
||||
}
|
||||
info.DeploymentID = globalDeploymentID
|
||||
|
||||
info.Buckets = make(map[string]madmin.SRBucketInfo, len(buckets))
|
||||
for _, bucketInfo := range buckets {
|
||||
bucket := bucketInfo.Name
|
||||
bms := madmin.SRBucketInfo{Bucket: bucket}
|
||||
// Get bucket policy if present.
|
||||
policy, err := globalPolicySys.Get(bucket)
|
||||
found := true
|
||||
if _, ok := err.(BucketPolicyNotFound); ok {
|
||||
found = false
|
||||
} else if err != nil {
|
||||
return info, errSRBackendIssue(err)
|
||||
}
|
||||
if found {
|
||||
policyJSON, err := json.Marshal(policy)
|
||||
if err != nil {
|
||||
return info, wrapSRErr(err)
|
||||
}
|
||||
bms.Policy = policyJSON
|
||||
}
|
||||
|
||||
// Get bucket tags if present.
|
||||
tags, err := globalBucketMetadataSys.GetTaggingConfig(bucket)
|
||||
found = true
|
||||
if _, ok := err.(BucketTaggingNotFound); ok {
|
||||
found = false
|
||||
} else if err != nil {
|
||||
return info, errSRBackendIssue(err)
|
||||
}
|
||||
if found {
|
||||
tagBytes, err := xml.Marshal(tags)
|
||||
if err != nil {
|
||||
return info, wrapSRErr(err)
|
||||
}
|
||||
tagCfgStr := base64.StdEncoding.EncodeToString(tagBytes)
|
||||
bms.Tags = &tagCfgStr
|
||||
}
|
||||
|
||||
// Get object-lock config if present.
|
||||
objLockCfg, err := globalBucketMetadataSys.GetObjectLockConfig(bucket)
|
||||
found = true
|
||||
if _, ok := err.(BucketObjectLockConfigNotFound); ok {
|
||||
found = false
|
||||
} else if err != nil {
|
||||
return info, errSRBackendIssue(err)
|
||||
}
|
||||
if found {
|
||||
objLockCfgData, err := xml.Marshal(objLockCfg)
|
||||
if err != nil {
|
||||
return info, wrapSRErr(err)
|
||||
}
|
||||
objLockStr := base64.StdEncoding.EncodeToString(objLockCfgData)
|
||||
bms.ObjectLockConfig = &objLockStr
|
||||
}
|
||||
|
||||
// Get existing bucket bucket encryption settings
|
||||
sseConfig, err := globalBucketMetadataSys.GetSSEConfig(bucket)
|
||||
found = true
|
||||
if _, ok := err.(BucketSSEConfigNotFound); ok {
|
||||
found = false
|
||||
} else if err != nil {
|
||||
return info, errSRBackendIssue(err)
|
||||
}
|
||||
if found {
|
||||
sseConfigData, err := xml.Marshal(sseConfig)
|
||||
if err != nil {
|
||||
return info, wrapSRErr(err)
|
||||
}
|
||||
sseConfigStr := base64.StdEncoding.EncodeToString(sseConfigData)
|
||||
bms.SSEConfig = &sseConfigStr
|
||||
}
|
||||
// Get replication config if present
|
||||
rcfg, err := globalBucketMetadataSys.GetReplicationConfig(ctx, bucket)
|
||||
found = true
|
||||
if _, ok := err.(BucketReplicationConfigNotFound); ok {
|
||||
found = false
|
||||
} else if err != nil {
|
||||
return info, errSRBackendIssue(err)
|
||||
}
|
||||
if found {
|
||||
rcfgXML, err := xml.Marshal(rcfg)
|
||||
if err != nil {
|
||||
return info, wrapSRErr(err)
|
||||
}
|
||||
rcfgXMLStr := base64.StdEncoding.EncodeToString(rcfgXML)
|
||||
bms.ReplicationConfig = &rcfgXMLStr
|
||||
}
|
||||
info.Buckets[bucket] = bms
|
||||
}
|
||||
|
||||
{
|
||||
// Replicate IAM policies on local to all peers.
|
||||
allPolicies, err := globalIAMSys.ListPolicies(ctx, "")
|
||||
if err != nil {
|
||||
return info, errSRBackendIssue(err)
|
||||
}
|
||||
info.Policies = make(map[string]json.RawMessage, len(allPolicies))
|
||||
for pname, policy := range allPolicies {
|
||||
policyJSON, err := json.Marshal(policy)
|
||||
if err != nil {
|
||||
return info, wrapSRErr(err)
|
||||
}
|
||||
info.Policies[pname] = json.RawMessage(policyJSON)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Replicate policy mappings on local to all peers.
|
||||
userPolicyMap := make(map[string]MappedPolicy)
|
||||
groupPolicyMap := make(map[string]MappedPolicy)
|
||||
globalIAMSys.store.rlock()
|
||||
errU := globalIAMSys.store.loadMappedPolicies(ctx, stsUser, false, userPolicyMap)
|
||||
errG := globalIAMSys.store.loadMappedPolicies(ctx, stsUser, true, groupPolicyMap)
|
||||
globalIAMSys.store.runlock()
|
||||
if errU != nil {
|
||||
return info, errSRBackendIssue(errU)
|
||||
}
|
||||
if errG != nil {
|
||||
return info, errSRBackendIssue(errG)
|
||||
}
|
||||
info.UserPolicies = make(map[string]madmin.SRPolicyMapping, len(userPolicyMap))
|
||||
info.GroupPolicies = make(map[string]madmin.SRPolicyMapping, len(c.state.Peers))
|
||||
for user, mp := range userPolicyMap {
|
||||
info.UserPolicies[user] = madmin.SRPolicyMapping{
|
||||
IsGroup: false,
|
||||
UserOrGroup: user,
|
||||
Policy: mp.Policies,
|
||||
}
|
||||
}
|
||||
|
||||
for group, mp := range groupPolicyMap {
|
||||
info.UserPolicies[group] = madmin.SRPolicyMapping{
|
||||
IsGroup: true,
|
||||
UserOrGroup: group,
|
||||
Policy: mp.Policies,
|
||||
}
|
||||
}
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
|
||||
@@ -611,6 +611,9 @@ func (client *storageRESTClient) DeleteVersions(ctx context.Context, volume stri
|
||||
respBody, err := client.call(ctx, storageRESTMethodDeleteVersions, values, &buffer, -1)
|
||||
defer xhttp.DrainBody(respBody)
|
||||
if err != nil {
|
||||
if contextCanceled(ctx) {
|
||||
err = ctx.Err()
|
||||
}
|
||||
for i := range errs {
|
||||
errs[i] = err
|
||||
}
|
||||
|
||||
+50
-2
@@ -278,6 +278,22 @@ func (sts *stsAPIHandlers) AssumeRole(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Call hook for site replication.
|
||||
if cred.ParentUser != globalActiveCred.AccessKey {
|
||||
if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
|
||||
Type: madmin.SRIAMItemSTSAcc,
|
||||
STSCredential: &madmin.SRSTSCredential{
|
||||
AccessKey: cred.AccessKey,
|
||||
SecretKey: cred.SecretKey,
|
||||
SessionToken: cred.SessionToken,
|
||||
ParentUser: cred.ParentUser,
|
||||
},
|
||||
}); err != nil {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
assumeRoleResponse := &AssumeRoleResponse{
|
||||
Result: AssumeRoleResult{
|
||||
Credentials: cred,
|
||||
@@ -497,6 +513,21 @@ func (sts *stsAPIHandlers) AssumeRoleWithSSO(w http.ResponseWriter, r *http.Requ
|
||||
return
|
||||
}
|
||||
|
||||
// Call hook for site replication.
|
||||
if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
|
||||
Type: madmin.SRIAMItemSTSAcc,
|
||||
STSCredential: &madmin.SRSTSCredential{
|
||||
AccessKey: cred.AccessKey,
|
||||
SecretKey: cred.SecretKey,
|
||||
SessionToken: cred.SessionToken,
|
||||
ParentUser: cred.ParentUser,
|
||||
ParentPolicyMapping: policyName,
|
||||
},
|
||||
}); err != nil {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
var encodedSuccessResponse []byte
|
||||
switch action {
|
||||
case clientGrants:
|
||||
@@ -653,13 +684,14 @@ func (sts *stsAPIHandlers) AssumeRoleWithLDAPIdentity(w http.ResponseWriter, r *
|
||||
return
|
||||
}
|
||||
|
||||
// Call hook for cluster-replication.
|
||||
// Call hook for site replication.
|
||||
if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
|
||||
Type: madmin.SRIAMItemSTSAcc,
|
||||
STSCredential: &madmin.SRSTSCredential{
|
||||
AccessKey: cred.AccessKey,
|
||||
SecretKey: cred.SecretKey,
|
||||
SessionToken: cred.SessionToken,
|
||||
ParentUser: cred.ParentUser,
|
||||
},
|
||||
}); err != nil {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
@@ -805,12 +837,28 @@ func (sts *stsAPIHandlers) AssumeRoleWithCertificate(w http.ResponseWriter, r *h
|
||||
}
|
||||
|
||||
tmpCredentials.ParentUser = parentUser
|
||||
err = globalIAMSys.SetTempUser(ctx, tmpCredentials.AccessKey, tmpCredentials, certificate.Subject.CommonName)
|
||||
policyName := certificate.Subject.CommonName
|
||||
err = globalIAMSys.SetTempUser(ctx, tmpCredentials.AccessKey, tmpCredentials, policyName)
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInternalError, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Call hook for site replication.
|
||||
if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
|
||||
Type: madmin.SRIAMItemSTSAcc,
|
||||
STSCredential: &madmin.SRSTSCredential{
|
||||
AccessKey: tmpCredentials.AccessKey,
|
||||
SecretKey: tmpCredentials.SecretKey,
|
||||
SessionToken: tmpCredentials.SessionToken,
|
||||
ParentUser: tmpCredentials.ParentUser,
|
||||
ParentPolicyMapping: policyName,
|
||||
},
|
||||
}); err != nil {
|
||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
response := new(AssumeRoleWithCertificateResponse)
|
||||
response.Result.Credentials = tmpCredentials
|
||||
response.Metadata.RequestID = w.Header().Get(xhttp.AmzRequestID)
|
||||
|
||||
@@ -256,8 +256,10 @@ const (
|
||||
// Random number state.
|
||||
// We generate random temporary file names so that there's a good
|
||||
// chance the file doesn't exist yet.
|
||||
var randN uint32
|
||||
var randmu sync.Mutex
|
||||
var (
|
||||
randN uint32
|
||||
randmu sync.Mutex
|
||||
)
|
||||
|
||||
// Temp files created in default Tmp dir
|
||||
var globalTestTmpDir = os.TempDir()
|
||||
|
||||
+2
-1
@@ -417,7 +417,8 @@ func getUpdateTransport(timeout time.Duration) http.RoundTripper {
|
||||
TLSHandshakeTimeout: timeout,
|
||||
ExpectContinueTimeout: timeout,
|
||||
TLSClientConfig: &tls.Config{
|
||||
RootCAs: globalRootCAs,
|
||||
RootCAs: globalRootCAs,
|
||||
ClientSessionCache: tls.NewLRUClientSessionCache(tlsClientSessionCacheSize),
|
||||
},
|
||||
DisableCompression: true,
|
||||
}
|
||||
|
||||
+9
-4
@@ -406,8 +406,10 @@ type minioProfiler interface {
|
||||
}
|
||||
|
||||
// Global profiler to be used by service go-routine.
|
||||
var globalProfiler map[string]minioProfiler
|
||||
var globalProfilerMu sync.Mutex
|
||||
var (
|
||||
globalProfiler map[string]minioProfiler
|
||||
globalProfilerMu sync.Mutex
|
||||
)
|
||||
|
||||
// dump the request into a string in JSON format.
|
||||
func dumpRequest(r *http.Request) string {
|
||||
@@ -613,7 +615,8 @@ func NewGatewayHTTPTransport() *http.Transport {
|
||||
|
||||
func newGatewayHTTPTransport(timeout time.Duration) *http.Transport {
|
||||
tr := newCustomHTTPTransport(&tls.Config{
|
||||
RootCAs: globalRootCAs,
|
||||
RootCAs: globalRootCAs,
|
||||
ClientSessionCache: tls.NewLRUClientSessionCache(tlsClientSessionCacheSize),
|
||||
}, defaultDialTimeout)()
|
||||
|
||||
// Customize response header timeout for gateway transport.
|
||||
@@ -639,7 +642,8 @@ func NewRemoteTargetHTTPTransport() *http.Transport {
|
||||
TLSHandshakeTimeout: 5 * time.Second,
|
||||
ExpectContinueTimeout: 5 * time.Second,
|
||||
TLSClientConfig: &tls.Config{
|
||||
RootCAs: globalRootCAs,
|
||||
RootCAs: globalRootCAs,
|
||||
ClientSessionCache: tls.NewLRUClientSessionCache(tlsClientSessionCacheSize),
|
||||
},
|
||||
// Go net/http automatically unzip if content-type is
|
||||
// gzip disable this feature, as we are always interested
|
||||
@@ -1135,6 +1139,7 @@ func newTLSConfig(getCert certs.GetCertificateFunc) *tls.Config {
|
||||
MinVersion: tls.VersionTLS12,
|
||||
NextProtos: []string{"http/1.1", "h2"},
|
||||
GetCertificate: getCert,
|
||||
ClientSessionCache: tls.NewLRUClientSessionCache(tlsClientSessionCacheSize),
|
||||
}
|
||||
|
||||
tlsClientIdentity := env.Get(xtls.EnvIdentityTLSEnabled, "") == config.EnableOn
|
||||
|
||||
@@ -943,6 +943,10 @@ func (s *xlStorage) DeleteVersions(ctx context.Context, volume string, versions
|
||||
errs := make([]error, len(versions))
|
||||
|
||||
for i, fiv := range versions {
|
||||
if contextCanceled(ctx) {
|
||||
errs[i] = ctx.Err()
|
||||
continue
|
||||
}
|
||||
if err := s.deleteVersions(ctx, volume, fiv.Name, fiv.Versions...); err != nil {
|
||||
errs[i] = err
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ version: '3.7'
|
||||
|
||||
# Settings and configurations that are common for all containers
|
||||
x-minio-common: &minio-common
|
||||
image: quay.io/minio/minio:RELEASE.2021-12-29T06-49-06Z
|
||||
image: quay.io/minio/minio:RELEASE.2022-01-04T07-41-07Z
|
||||
command: server --console-address ":9001" http://minio{1...4}/data{1...2}
|
||||
expose:
|
||||
- "9000"
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
This feature allows multiple independent MinIO sites (or clusters) that are using the same external IDentity Provider (IDP) to be configured as replicas. In this situation the set of replica sites are referred to as peer sites or just sites. When site-replication is enabled on a set of sites, the following changes are replicated to all other sites:
|
||||
|
||||
- Creation and deletion of buckets and objects
|
||||
- Creation and deletion of all IAM policies
|
||||
- Creation and deletion of all IAM users, groups, policies and their mappings to users or groups
|
||||
- Creation of STS credentials
|
||||
- Creation and deletion of service accounts (for users authenticated by an external IDP)
|
||||
- Creation and deletion of service accounts (except those owned by the root user)
|
||||
- Changes to Bucket features such as:
|
||||
- Bucket Policies
|
||||
- Bucket Tags
|
||||
@@ -21,13 +21,12 @@ The following Bucket features will **not be replicated**, is designed to differ
|
||||
## Pre-requisites
|
||||
|
||||
- Initially, only **one** of the sites added for replication may have data. After site-replication is successfully configured, this data is replicated to the other (initially empty) sites. Subsequently, objects may be written to any of the sites, and they will be replicated to all other sites.
|
||||
- Replication of **LDAP IDP** is currently supported, support for OIDC (OpenID) is in progress.
|
||||
- All sites **must** have the same deployment credentials, i.e (MINIO_ROOT_USER, MINIO_ROOT_PASSWORD).
|
||||
- All sites **must** have the same deployment credentials (i.e. `MINIO_ROOT_USER`, `MINIO_ROOT_PASSWORD`).
|
||||
- **Removing a site** is not allowed from a set of replicated sites once configured.
|
||||
- [SSE-S3 or SSE-KMS encryption via KMS](https://docs.min.io/docs/minio-kms-quickstart-guide.html "MinIO KMS Guide"), all sites **must** have access to a central KMS deployment. This can be achieved via a central KES server or multiple KES servers (say one per site) connected via a central KMS (Vault) server.
|
||||
- All sites must be using the **same** external IDP(s) if any.
|
||||
- For [SSE-S3 or SSE-KMS encryption via KMS](https://docs.min.io/docs/minio-kms-quickstart-guide.html "MinIO KMS Guide"), all sites **must** have access to a central KMS deployment. This can be achieved via a central KES server or multiple KES servers (say one per site) connected via a central KMS (Vault) server.
|
||||
|
||||
## Configuring Site Replication
|
||||
To configure site replication, ensure that all MinIO sites are using the same external IDP.
|
||||
|
||||
- Configure an alias in `mc` for each of the sites. For example if you have three MinIO sites, you may run:
|
||||
|
||||
|
||||
@@ -23,14 +23,14 @@ require (
|
||||
github.com/djherbis/atime v1.0.0
|
||||
github.com/dswarbrick/smart v0.0.0-20190505152634-909a45200d6d
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/eclipse/paho.mqtt.golang v1.3.0
|
||||
github.com/eclipse/paho.mqtt.golang v1.3.5
|
||||
github.com/elastic/go-elasticsearch/v7 v7.12.0
|
||||
github.com/fatih/color v1.13.0
|
||||
github.com/go-ldap/ldap/v3 v3.2.4
|
||||
github.com/go-openapi/loads v0.20.2
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/golang-jwt/jwt/v4 v4.1.0
|
||||
github.com/gomodule/redigo v2.0.0+incompatible
|
||||
github.com/gomodule/redigo v1.8.8
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/hashicorp/golang-lru v0.5.4
|
||||
@@ -45,11 +45,11 @@ require (
|
||||
github.com/lib/pq v1.9.0
|
||||
github.com/miekg/dns v1.1.43
|
||||
github.com/minio/cli v1.22.0
|
||||
github.com/minio/console v0.13.1
|
||||
github.com/minio/console v0.13.2
|
||||
github.com/minio/csvparser v1.0.0
|
||||
github.com/minio/highwayhash v1.0.2
|
||||
github.com/minio/kes v0.14.0
|
||||
github.com/minio/madmin-go v1.1.23
|
||||
github.com/minio/madmin-go v1.2.4
|
||||
github.com/minio/minio-go/v7 v7.0.20
|
||||
github.com/minio/parquet-go v1.1.0
|
||||
github.com/minio/pkg v1.1.11
|
||||
@@ -231,5 +231,3 @@ require (
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.0 // indirect
|
||||
sigs.k8s.io/yaml v1.2.0 // indirect
|
||||
)
|
||||
|
||||
replace github.com/gomodule/redigo v2.0.0+incompatible => github.com/gomodule/redigo v1.8.5
|
||||
|
||||
@@ -210,6 +210,7 @@ github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edY
|
||||
github.com/bits-and-blooms/bloom/v3 v3.0.1 h1:Inlf0YXbgehxVjMPmCGv86iMCKMGPPrPSHtBF5yRHwA=
|
||||
github.com/bits-and-blooms/bloom/v3 v3.0.1/go.mod h1:MC8muvBzzPOFsrcdND/A7kU7kMhkqb9KI70JlZCP+C8=
|
||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
|
||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
|
||||
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
@@ -333,8 +334,8 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/eclipse/paho.mqtt.golang v1.3.0 h1:MU79lqr3FKNKbSrGN7d7bNYqh8MwWW7Zcx0iG+VIw9I=
|
||||
github.com/eclipse/paho.mqtt.golang v1.3.0/go.mod h1:eTzb4gxwwyWpqBUHGQZ4ABAV7+Jgm1PklsYT/eo8Hcc=
|
||||
github.com/eclipse/paho.mqtt.golang v1.3.5 h1:sWtmgNxYM9P2sP+xEItMozsR3w0cqZFlqnNN1bdl41Y=
|
||||
github.com/eclipse/paho.mqtt.golang v1.3.5/go.mod h1:eTzb4gxwwyWpqBUHGQZ4ABAV7+Jgm1PklsYT/eo8Hcc=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/elastic/go-elasticsearch/v7 v7.12.0 h1:j4tvcMrZJLp39L2NYvBb7f+lHKPqPHSL3nvB8+/DV+s=
|
||||
github.com/elastic/go-elasticsearch/v7 v7.12.0/go.mod h1:OJ4wdbtDNk5g503kvlHLyErCgQwwzmDtaFC4XyOxXA4=
|
||||
@@ -639,8 +640,8 @@ github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bz
|
||||
github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4=
|
||||
github.com/golangci/revgrep v0.0.0-20180812185044-276a5c0a1039/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4=
|
||||
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ=
|
||||
github.com/gomodule/redigo v1.8.5 h1:nRAxCa+SVsyjSBrtZmG/cqb6VbTmuRzpg/PoTFlpumc=
|
||||
github.com/gomodule/redigo v1.8.5/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
|
||||
github.com/gomodule/redigo v1.8.8 h1:f6cXq6RRfiyrOJEV7p3JhLDlmawGBVBBP1MggY8Mo4E=
|
||||
github.com/gomodule/redigo v1.8.8/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
@@ -715,6 +716,7 @@ github.com/gookit/color v1.2.4/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1K
|
||||
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20190328170749-bb2674552d8f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20220104163920-15ed2e8cf2bd/go.mod h1:cz9oNYuRUWGdHmLF2IodMLkAhcPtXeULvcBNagUrxTI=
|
||||
github.com/goreleaser/goreleaser v0.136.0/go.mod h1:wiKrPUeSNh6Wu8nUHxZydSOVQ/OZvOaO7DTtFqie904=
|
||||
github.com/goreleaser/nfpm v1.2.1/go.mod h1:TtWrABZozuLOttX2uDlYyECfQX7x5XYkVxhjYcR6G9w=
|
||||
github.com/goreleaser/nfpm v1.3.0/go.mod h1:w0p7Kc9TAUgWMyrub63ex3M2Mgw88M4GZXoTq5UCb40=
|
||||
@@ -960,6 +962,7 @@ github.com/klauspost/reedsolomon v1.9.15/go.mod h1:eqPAcE7xar5CIzcdfwydOEdcmchAK
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
@@ -1006,6 +1009,7 @@ github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0Q
|
||||
github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
@@ -1071,8 +1075,8 @@ github.com/minio/cli v1.22.0 h1:VTQm7lmXm3quxO917X3p+el1l0Ca5X3S4PM2ruUYO68=
|
||||
github.com/minio/cli v1.22.0/go.mod h1:bYxnK0uS629N3Bq+AOZZ+6lwF77Sodk4+UL9vNuXhOY=
|
||||
github.com/minio/colorjson v1.0.1 h1:+hvfP8C1iMB95AT+ZFDRE+Knn9QPd9lg0CRJY9DRpos=
|
||||
github.com/minio/colorjson v1.0.1/go.mod h1:oPM3zQQY8Gz9NGtgvuBEjQ+gPZLKAGc7T+kjMlwtOgs=
|
||||
github.com/minio/console v0.13.1 h1:/T/k9DeAqcBfAz7e314WwXreN3iMSiOHgIFlKF//Q+E=
|
||||
github.com/minio/console v0.13.1/go.mod h1:Igh8I8l0O6pNmzOJVMSIk/ftoCt635LGUJ//ShzFXhw=
|
||||
github.com/minio/console v0.13.2 h1:8dgHnT/hLN5ubCx49hR19KBLUGS+i0E37Nx1gPiTVlE=
|
||||
github.com/minio/console v0.13.2/go.mod h1:jXzCkW7CbIZjlNQ9zMbUd9sQk/f9B7zJ6ieSl9fWioM=
|
||||
github.com/minio/csvparser v1.0.0 h1:xJEHcYK8ZAjeW4hNV9Zu30u+/2o4UyPnYgyjWp8b7ZU=
|
||||
github.com/minio/csvparser v1.0.0/go.mod h1:lKXskSLzPgC5WQyzP7maKH7Sl1cqvANXo9YCto8zbtM=
|
||||
github.com/minio/direct-csi v1.3.5-0.20210601185811-f7776f7961bf h1:wylCc/PdvdTIqYqVNEU9LJAZBanvfGY1TwTnjM3zQaA=
|
||||
@@ -1087,10 +1091,9 @@ github.com/minio/kes v0.14.0 h1:plCGm4LwR++T1P1sXsJbyFRX54CE1WRuo9PAPj6MC3Q=
|
||||
github.com/minio/kes v0.14.0/go.mod h1:OUensXz2BpgMfiogslKxv7Anyx/wj+6bFC6qA7BQcfA=
|
||||
github.com/minio/madmin-go v1.0.12/go.mod h1:BK+z4XRx7Y1v8SFWXsuLNqQqnq5BO/axJ8IDJfgyvfs=
|
||||
github.com/minio/madmin-go v1.1.15/go.mod h1:Iu0OnrMWNBYx1lqJTW+BFjBMx0Hi0wjw8VmqhiOs2Jo=
|
||||
github.com/minio/madmin-go v1.1.19/go.mod h1:Iu0OnrMWNBYx1lqJTW+BFjBMx0Hi0wjw8VmqhiOs2Jo=
|
||||
github.com/minio/madmin-go v1.1.21/go.mod h1:vIDiJEjYOG27M/CgZPmxBdgdn3Yz5SIwtXtMzGAsqsA=
|
||||
github.com/minio/madmin-go v1.1.23 h1:VO/K+cFpX3HbNaLBEILd18V09ZpoSCE90522nHtmxdQ=
|
||||
github.com/minio/madmin-go v1.1.23/go.mod h1:wv8zCroSCnpjjQdmgsdJEkFH2oD4w9J40OZqbhxjiJ4=
|
||||
github.com/minio/madmin-go v1.2.4 h1:o+0X6ENO/AtkRxCbD4FXT6YCRIH7HgDGb+WzfJFDzMQ=
|
||||
github.com/minio/madmin-go v1.2.4/go.mod h1:/rOfQv4ohkXJ+7EaSnhg9IJEX7cobX08zkSLfh8G3Ks=
|
||||
github.com/minio/mc v0.0.0-20211207230606-23a05f5a17f2 h1:xocb1RGyrDJ8PxkNn0NSbaBlfdU6J/Ag9QK62pb7nR8=
|
||||
github.com/minio/mc v0.0.0-20211207230606-23a05f5a17f2/go.mod h1:siI9jWTzj1KsNXgz6NOL/S7OTaAUM0OMi+zEkF08gnA=
|
||||
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
|
||||
@@ -1099,7 +1102,6 @@ github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEp
|
||||
github.com/minio/minio-go/v7 v7.0.10/go.mod h1:td4gW1ldOsj1PbSNS+WYK43j+P1XVhX/8W8awaYlBFo=
|
||||
github.com/minio/minio-go/v7 v7.0.11-0.20210302210017-6ae69c73ce78/go.mod h1:mTh2uJuAbEqdhMVl6CMIIZLUeiMiWtJR4JB8/5g2skw=
|
||||
github.com/minio/minio-go/v7 v7.0.16-0.20211108161804-a7a36ee131df/go.mod h1:pUV0Pc+hPd1nccgmzQF/EXh48l/Z/yps6QPF1aaie4g=
|
||||
github.com/minio/minio-go/v7 v7.0.18/go.mod h1:SyQ1IFeJuaa+eV5yEDxW7hYE1s5VVq5sgImDe27R+zg=
|
||||
github.com/minio/minio-go/v7 v7.0.20 h1:0+Xt1SkCKDgcx5cmo3UxXcJ37u5Gy+/2i/+eQYqmYJw=
|
||||
github.com/minio/minio-go/v7 v7.0.20/go.mod h1:ei5JjmxwHaMrgsMrn4U/+Nmg+d8MKS1U2DAn1ou4+Do=
|
||||
github.com/minio/operator v0.0.0-20211011212245-31460bbbc4b7 h1:dkfuMNslMjGoJ4ArAMSoQhidYNdm3SgzLBP+f96O3/E=
|
||||
@@ -1112,7 +1114,6 @@ github.com/minio/pkg v1.0.3/go.mod h1:obU54TZ9QlMv0TRaDgQ/JTzf11ZSXxnSfLrm4tMtBP
|
||||
github.com/minio/pkg v1.0.4/go.mod h1:obU54TZ9QlMv0TRaDgQ/JTzf11ZSXxnSfLrm4tMtBP8=
|
||||
github.com/minio/pkg v1.0.11/go.mod h1:32x/3OmGB0EOi1N+3ggnp+B5VFkSBBB9svPMVfpnf14=
|
||||
github.com/minio/pkg v1.1.3/go.mod h1:32x/3OmGB0EOi1N+3ggnp+B5VFkSBBB9svPMVfpnf14=
|
||||
github.com/minio/pkg v1.1.10/go.mod h1:3I8LLp1/HDhNKl35I8ve0mhzp7+bvVTrJmLqkdkOHME=
|
||||
github.com/minio/pkg v1.1.11 h1:FQMYrOZzZenQUVwvxM0YjoAZB15Wb+m3TZSu33Lynx0=
|
||||
github.com/minio/pkg v1.1.11/go.mod h1:2WJAxesjzmPK9MnLZKm5n1hVYfBg04f2GQs6N5ImNU8=
|
||||
github.com/minio/selfupdate v0.3.1/go.mod h1:b8ThJzzH7u2MkF6PcIra7KaXO9Khf6alWPvMSyTDCFM=
|
||||
@@ -1203,6 +1204,8 @@ github.com/nats-io/stan.go v0.8.3/go.mod h1:Ejm8bbHnMTSptU6uNMAVuxeapMJYBB/Ml3ej
|
||||
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
|
||||
github.com/ncw/directio v1.0.5 h1:JSUBhdjEvVaJvOoyPAbcW0fnd0tvRXD76wEfZ1KcQz4=
|
||||
github.com/ncw/directio v1.0.5/go.mod h1:rX/pKEYkOXBGOggmcyJeJGloCkleSvphPx2eV3t6ROk=
|
||||
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
|
||||
github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
|
||||
@@ -1256,6 +1259,7 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
|
||||
github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
|
||||
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
|
||||
github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs=
|
||||
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw=
|
||||
@@ -1274,6 +1278,7 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||
github.com/pkg/profile v1.6.0 h1:hUDfIISABYI59DyeB3OTay/HxSRwTQ8rB/H83k6r5dM=
|
||||
github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
|
||||
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
||||
github.com/pkg/xattr v0.4.3 h1:5Jx4GCg5ABtqWZH8WLzeI4fOtM1HyX4RBawuCoua1es=
|
||||
github.com/pkg/xattr v0.4.3/go.mod h1:sBD3RAqlr8Q+RC3FutZcikpT8nyDrIEEBw2J744gVWs=
|
||||
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
@@ -1390,8 +1395,11 @@ github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9Nz
|
||||
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shopspring/decimal v0.0.0-20200419222939-1884f454f8ea/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
||||
github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
||||
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
@@ -1416,12 +1424,14 @@ github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0b
|
||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
|
||||
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
@@ -1433,6 +1443,7 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
|
||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
|
||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
@@ -1546,6 +1557,7 @@ go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQc
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0-beta.4/go.mod h1:a+pbz+UrcOpvve1Qxf6tGovi15PjgtRhi0QTO2Nlc4U=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0 h1:2aQv6F436YnN7I4VbI8PPYrBhu+SmrTaADcf8Mi/6PU=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0-beta.4/go.mod h1:0L1RulN1QSXq6uKPMUSX+OTAYyFkapMK7iUHXXIH/1E=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0 h1:62Eh0XOro+rDwkrypAGDfgmNh5Joq+z+W9HZdlXMzek=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
|
||||
@@ -1639,6 +1651,7 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP
|
||||
golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b h1:QAqMVf3pSa6eeTsuklijukjXBlj7Es2QQplab+/RbQ4=
|
||||
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
@@ -1759,6 +1772,7 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
@@ -2054,6 +2068,7 @@ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34q
|
||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
|
||||
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
|
||||
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
|
||||
google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
|
||||
google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=
|
||||
google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
|
||||
@@ -2210,6 +2225,7 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.63.2 h1:tGK/CyBg7SMzb60vP1M03vNZ3VDu3wGQJwn7Sxi9r3c=
|
||||
gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw=
|
||||
|
||||
Binary file not shown.
@@ -1,8 +1,8 @@
|
||||
apiVersion: v1
|
||||
description: Multi-Cloud Object Storage
|
||||
name: minio
|
||||
version: 3.4.4
|
||||
appVersion: RELEASE.2021-12-29T06-49-06Z
|
||||
version: 3.4.5
|
||||
appVersion: RELEASE.2022-01-04T07-41-07Z
|
||||
keywords:
|
||||
- minio
|
||||
- storage
|
||||
|
||||
+55
-33
@@ -1,9 +1,31 @@
|
||||
apiVersion: v1
|
||||
entries:
|
||||
minio:
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2022-01-04T07-41-07Z
|
||||
created: "2022-01-05T11:32:39.397078964-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: bacd140f0016fab35f516bde787da6449b3a960c071fad9e4b6563118033ac84
|
||||
home: https://min.io
|
||||
icon: https://min.io/resources/img/logo/MINIO_wordmark.png
|
||||
keywords:
|
||||
- minio
|
||||
- storage
|
||||
- object-storage
|
||||
- s3
|
||||
- cluster
|
||||
maintainers:
|
||||
- email: dev@minio.io
|
||||
name: MinIO, Inc
|
||||
name: minio
|
||||
sources:
|
||||
- https://github.com/minio/minio
|
||||
urls:
|
||||
- https://charts.min.io/helm-releases/minio-3.4.5.tgz
|
||||
version: 3.4.5
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-12-29T06-49-06Z
|
||||
created: "2021-12-30T20:21:09.814024764-08:00"
|
||||
created: "2022-01-05T11:32:39.396093317-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: 48a453ea5ffeef25933904caefd9470bfb26224dfc2d1096bd0031467ba53007
|
||||
home: https://min.io
|
||||
@@ -25,7 +47,7 @@ entries:
|
||||
version: 3.4.4
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-12-20T22-07-16Z
|
||||
created: "2021-12-30T20:21:09.812545203-08:00"
|
||||
created: "2022-01-05T11:32:39.395038813-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: 47ef4a930713b98f9438ceca913c6e700f85bb25dba5624b056486254b5f0c60
|
||||
home: https://min.io
|
||||
@@ -47,7 +69,7 @@ entries:
|
||||
version: 3.4.3
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-12-20T22-07-16Z
|
||||
created: "2021-12-30T20:21:09.811535356-08:00"
|
||||
created: "2022-01-05T11:32:39.392092639-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: d6763f7e2ea66810bd55eb225579a9c3b968f9ae1256f45fd469362e55d846ff
|
||||
home: https://min.io
|
||||
@@ -69,7 +91,7 @@ entries:
|
||||
version: 3.4.2
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-12-10T23-03-39Z
|
||||
created: "2021-12-30T20:21:09.810563403-08:00"
|
||||
created: "2022-01-05T11:32:39.386229629-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: 2fb822c87216ba3fc2ae51a54a0a3e239aa560d86542991504a841cc2a2b9a37
|
||||
home: https://min.io
|
||||
@@ -91,7 +113,7 @@ entries:
|
||||
version: 3.4.1
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-12-18T04-42-33Z
|
||||
created: "2021-12-30T20:21:09.809615092-08:00"
|
||||
created: "2022-01-05T11:32:39.385314326-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: fa8ba1aeb1a15316c6be8403416a5e6b5e6139b7166592087e7bddc9e6db5453
|
||||
home: https://min.io
|
||||
@@ -113,7 +135,7 @@ entries:
|
||||
version: 3.4.0
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-12-10T23-03-39Z
|
||||
created: "2021-12-30T20:21:09.808700764-08:00"
|
||||
created: "2022-01-05T11:32:39.384402307-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: b9b0af9ca50b8d00868e1f1b989dca275829d9110af6de91bb9b3a398341e894
|
||||
home: https://min.io
|
||||
@@ -135,7 +157,7 @@ entries:
|
||||
version: 3.3.4
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-12-10T23-03-39Z
|
||||
created: "2021-12-30T20:21:09.807776353-08:00"
|
||||
created: "2022-01-05T11:32:39.383443694-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: f8b22a5b8fe95a7ddf61b825e17d11c9345fb10e4c126b0d78381608aa300a08
|
||||
home: https://min.io
|
||||
@@ -157,7 +179,7 @@ entries:
|
||||
version: 3.3.3
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-12-10T23-03-39Z
|
||||
created: "2021-12-30T20:21:09.806769822-08:00"
|
||||
created: "2022-01-05T11:32:39.382488898-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: c48d474f269427abe5ab446f00687d0625b3d1adfc5c73bdb4b21ca9e42853fb
|
||||
home: https://min.io
|
||||
@@ -179,7 +201,7 @@ entries:
|
||||
version: 3.3.2
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-11-24T23-19-33Z
|
||||
created: "2021-12-30T20:21:09.805267453-08:00"
|
||||
created: "2022-01-05T11:32:39.381498938-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: 7c3da39d9b0090cbf5efedf0cc163a1e2df05becc5152c3add8e837384690bc4
|
||||
home: https://min.io
|
||||
@@ -201,7 +223,7 @@ entries:
|
||||
version: 3.3.1
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-11-24T23-19-33Z
|
||||
created: "2021-12-30T20:21:09.804381117-08:00"
|
||||
created: "2022-01-05T11:32:39.379903729-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: 50d6590b4cc779c40f81cc13b1586fbe508aa7f3230036c760bfc5f4154fbce4
|
||||
home: https://min.io
|
||||
@@ -223,7 +245,7 @@ entries:
|
||||
version: 3.3.0
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-10-13T00-23-17Z
|
||||
created: "2021-12-30T20:21:09.803489407-08:00"
|
||||
created: "2022-01-05T11:32:39.379008717-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: 5b797b7208cd904c11a76cd72938c8652160cb5fcd7f09fa41e4e703e6d64054
|
||||
home: https://min.io
|
||||
@@ -245,7 +267,7 @@ entries:
|
||||
version: 3.2.0
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-10-10T16-53-30Z
|
||||
created: "2021-12-30T20:21:09.80272052-08:00"
|
||||
created: "2022-01-05T11:32:39.378110405-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: e084ac4bb095f071e59f8f08bd092e4ab2404c1ddadacfdce7dbe248f1bafff8
|
||||
home: https://min.io
|
||||
@@ -267,7 +289,7 @@ entries:
|
||||
version: 3.1.9
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-10-06T23-36-31Z
|
||||
created: "2021-12-30T20:21:09.801935192-08:00"
|
||||
created: "2022-01-05T11:32:39.377199371-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: 2890430a8d9487d1fa5508c26776e4881d0086b2c052aa6bdc65c0e4423b9159
|
||||
home: https://min.io
|
||||
@@ -289,7 +311,7 @@ entries:
|
||||
version: 3.1.8
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-10-02T16-31-05Z
|
||||
created: "2021-12-30T20:21:09.800951056-08:00"
|
||||
created: "2022-01-05T11:32:39.376277102-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: 01a92196af6c47e3a01e1c68d7cf693a8bc487cba810c2cecff155071e4d6a11
|
||||
home: https://min.io
|
||||
@@ -311,7 +333,7 @@ entries:
|
||||
version: 3.1.7
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-09-18T18-09-59Z
|
||||
created: "2021-12-30T20:21:09.799490743-08:00"
|
||||
created: "2022-01-05T11:32:39.375328694-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: e779d73f80b75f33b9c9d995ab10fa455c9c57ee575ebc54e06725a64cd04310
|
||||
home: https://min.io
|
||||
@@ -333,7 +355,7 @@ entries:
|
||||
version: 3.1.6
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-09-18T18-09-59Z
|
||||
created: "2021-12-30T20:21:09.798345086-08:00"
|
||||
created: "2022-01-05T11:32:39.374195493-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: 19de4bbc8a400f0c2a94c5e85fc25c9bfc666e773fb3e368dd621d5a57dd1c2a
|
||||
home: https://min.io
|
||||
@@ -355,7 +377,7 @@ entries:
|
||||
version: 3.1.5
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-09-18T18-09-59Z
|
||||
created: "2021-12-30T20:21:09.797387621-08:00"
|
||||
created: "2022-01-05T11:32:39.372924905-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: f789d93a171296dd01af0105a5ce067c663597afbb2432faeda293b752b355c0
|
||||
home: https://min.io
|
||||
@@ -377,7 +399,7 @@ entries:
|
||||
version: 3.1.4
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-09-09T21-37-07Z
|
||||
created: "2021-12-30T20:21:09.796480538-08:00"
|
||||
created: "2022-01-05T11:32:39.372163928-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: e2eb34d31560b012ef6581f0ff6004ea4376c968cbe0daed2d8f3a614a892afb
|
||||
home: https://min.io
|
||||
@@ -399,7 +421,7 @@ entries:
|
||||
version: 3.1.3
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-09-09T21-37-07Z
|
||||
created: "2021-12-30T20:21:09.795481913-08:00"
|
||||
created: "2022-01-05T11:32:39.371263273-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: 8d7e0cc46b3583abd71b97dc0c071f98321101f90eca17348f1e9e0831be64cd
|
||||
home: https://min.io
|
||||
@@ -421,7 +443,7 @@ entries:
|
||||
version: 3.1.2
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-09-09T21-37-07Z
|
||||
created: "2021-12-30T20:21:09.794528744-08:00"
|
||||
created: "2022-01-05T11:32:39.370334869-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: 50dcbf366b1b21f4a6fc429d0b884c0c7ff481d0fb95c5e9b3ae157c348dd124
|
||||
home: https://min.io
|
||||
@@ -443,7 +465,7 @@ entries:
|
||||
version: 3.1.1
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-09-09T21-37-07Z
|
||||
created: "2021-12-30T20:21:09.793548717-08:00"
|
||||
created: "2022-01-05T11:32:39.367649887-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: 6c01af55d2e2e5f716eabf6fef3a92a8464d0674529e9bacab292e5478a73b7a
|
||||
home: https://min.io
|
||||
@@ -465,7 +487,7 @@ entries:
|
||||
version: 3.1.0
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-09-03T03-56-13Z
|
||||
created: "2021-12-30T20:21:09.792120406-08:00"
|
||||
created: "2022-01-05T11:32:39.36660403-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: 18e10be4d0458bc590ca9abf753227e0c70f60511495387b8d4fb15a4daf932e
|
||||
home: https://min.io
|
||||
@@ -487,7 +509,7 @@ entries:
|
||||
version: 3.0.2
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-08-31T05-46-54Z
|
||||
created: "2021-12-30T20:21:09.79122611-08:00"
|
||||
created: "2022-01-05T11:32:39.365037889-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: f5b6e7f6272a9e71aef3b75555f6f756a39eef65cb78873f26451dba79b19906
|
||||
home: https://min.io
|
||||
@@ -509,7 +531,7 @@ entries:
|
||||
version: 3.0.1
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-08-31T05-46-54Z
|
||||
created: "2021-12-30T20:21:09.790246931-08:00"
|
||||
created: "2022-01-05T11:32:39.364114151-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: 6d2ee1336c412affaaf209fdb80215be2a6ebb23ab2443adbaffef9e7df13fab
|
||||
home: https://min.io
|
||||
@@ -531,7 +553,7 @@ entries:
|
||||
version: 3.0.0
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-08-31T05-46-54Z
|
||||
created: "2021-12-30T20:21:09.789285188-08:00"
|
||||
created: "2022-01-05T11:32:39.36316085-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: 0a004aaf5bb61deed6a5c88256d1695ebe2f9ff1553874a93e4acfd75e8d339b
|
||||
home: https://min.io
|
||||
@@ -551,7 +573,7 @@ entries:
|
||||
version: 2.0.1
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-08-25T00-41-18Z
|
||||
created: "2021-12-30T20:21:09.78838079-08:00"
|
||||
created: "2022-01-05T11:32:39.362224907-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: fcd944e837ee481307de6aa3d387ea18c234f995a84c15abb211aab4a4054afc
|
||||
home: https://min.io
|
||||
@@ -571,7 +593,7 @@ entries:
|
||||
version: 2.0.0
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-08-25T00-41-18Z
|
||||
created: "2021-12-30T20:21:09.787445226-08:00"
|
||||
created: "2022-01-05T11:32:39.361269015-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: 7b6c033d43a856479eb493ab8ca05b230f77c3e42e209e8f298fac6af1a9796f
|
||||
home: https://min.io
|
||||
@@ -591,7 +613,7 @@ entries:
|
||||
version: 1.0.5
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-08-25T00-41-18Z
|
||||
created: "2021-12-30T20:21:09.786381619-08:00"
|
||||
created: "2022-01-05T11:32:39.36037317-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: abd221245ace16c8e0c6c851cf262d1474a5219dcbf25c4b2e7b77142f9c59ed
|
||||
home: https://min.io
|
||||
@@ -611,7 +633,7 @@ entries:
|
||||
version: 1.0.4
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-08-20T18-32-01Z
|
||||
created: "2021-12-30T20:21:09.78261465-08:00"
|
||||
created: "2022-01-05T11:32:39.359327826-08:00"
|
||||
description: Multi-Cloud Object Storage
|
||||
digest: 922a333f5413d1042f7aa81929f43767f6ffca9b260c46713f04ce1dda86d57d
|
||||
home: https://min.io
|
||||
@@ -631,7 +653,7 @@ entries:
|
||||
version: 1.0.3
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-08-20T18-32-01Z
|
||||
created: "2021-12-30T20:21:09.781652009-08:00"
|
||||
created: "2022-01-05T11:32:39.353680391-08:00"
|
||||
description: High Performance, Kubernetes Native Object Storage
|
||||
digest: 10e22773506bbfb1c66442937956534cf4057b94f06a977db78b8cd223588388
|
||||
home: https://min.io
|
||||
@@ -651,7 +673,7 @@ entries:
|
||||
version: 1.0.2
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-08-20T18-32-01Z
|
||||
created: "2021-12-30T20:21:09.78072724-08:00"
|
||||
created: "2022-01-05T11:32:39.352750567-08:00"
|
||||
description: High Performance, Kubernetes Native Object Storage
|
||||
digest: ef86ab6df23d6942705da9ef70991b649638c51bc310587d37a425268ba4a06c
|
||||
home: https://min.io
|
||||
@@ -671,7 +693,7 @@ entries:
|
||||
version: 1.0.1
|
||||
- apiVersion: v1
|
||||
appVersion: RELEASE.2021-08-17T20-53-08Z
|
||||
created: "2021-12-30T20:21:09.779819888-08:00"
|
||||
created: "2022-01-05T11:32:39.351852438-08:00"
|
||||
description: High Performance, Kubernetes Native Object Storage
|
||||
digest: 1add7608692cbf39aaf9b1252530e566f7b2f306a14e390b0f49b97a20f2b188
|
||||
home: https://min.io
|
||||
@@ -689,4 +711,4 @@ entries:
|
||||
urls:
|
||||
- https://charts.min.io/helm-releases/minio-1.0.0.tgz
|
||||
version: 1.0.0
|
||||
generated: "2021-12-30T20:21:09.778763929-08:00"
|
||||
generated: "2022-01-05T11:32:39.350778967-08:00"
|
||||
|
||||
@@ -20,6 +20,7 @@ package openid
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
@@ -33,6 +34,7 @@ import (
|
||||
"time"
|
||||
|
||||
jwtgo "github.com/golang-jwt/jwt/v4"
|
||||
"github.com/minio/madmin-go"
|
||||
"github.com/minio/minio/internal/arn"
|
||||
"github.com/minio/minio/internal/auth"
|
||||
"github.com/minio/minio/internal/config"
|
||||
@@ -369,6 +371,40 @@ func (Config) ID() ID {
|
||||
return "jwt"
|
||||
}
|
||||
|
||||
// GetSettings - fetches OIDC settings for site-replication related validation.
|
||||
// NOTE that region must be populated by caller as this package does not know.
|
||||
func (r *Config) GetSettings() madmin.OpenIDSettings {
|
||||
res := madmin.OpenIDSettings{}
|
||||
if !r.Enabled {
|
||||
return res
|
||||
}
|
||||
|
||||
hashedSecret := ""
|
||||
{
|
||||
h := sha256.New()
|
||||
h.Write([]byte(r.ClientSecret))
|
||||
bs := h.Sum(nil)
|
||||
hashedSecret = base64.RawURLEncoding.EncodeToString(bs)
|
||||
}
|
||||
if r.RolePolicy != "" {
|
||||
res.Roles = make(map[string]madmin.OpenIDProviderSettings)
|
||||
res.Roles[r.roleArn.String()] = madmin.OpenIDProviderSettings{
|
||||
ClaimUserinfoEnabled: r.ClaimUserinfo,
|
||||
RolePolicy: r.RolePolicy,
|
||||
ClientID: r.ClientID,
|
||||
HashedClientSecret: hashedSecret,
|
||||
}
|
||||
} else {
|
||||
res.ClaimProvider = madmin.OpenIDProviderSettings{
|
||||
ClaimName: r.ClaimName,
|
||||
ClaimUserinfoEnabled: r.ClaimUserinfo,
|
||||
ClientID: r.ClientID,
|
||||
HashedClientSecret: hashedSecret,
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// OpenID keys and envs.
|
||||
const (
|
||||
JwksURL = "jwks_url"
|
||||
|
||||
@@ -209,8 +209,12 @@ func NewMQTTTarget(id string, args MQTTArgs, doneCh <-chan struct{}, loggerOnce
|
||||
args.MaxReconnectInterval = 10 * time.Minute
|
||||
}
|
||||
|
||||
if args.KeepAlive == 0 {
|
||||
args.KeepAlive = 10 * time.Second
|
||||
}
|
||||
|
||||
options := mqtt.NewClientOptions().
|
||||
SetClientID("").
|
||||
SetClientID(id).
|
||||
SetCleanSession(true).
|
||||
SetUsername(args.User).
|
||||
SetPassword(args.Password).
|
||||
|
||||
@@ -32,14 +32,16 @@ type Target interface {
|
||||
Send(entry interface{}, errKind string) error
|
||||
}
|
||||
|
||||
// swapMu must be held while reading slice info or swapping targets or auditTargets.
|
||||
var swapMu sync.Mutex
|
||||
var (
|
||||
// swapMu must be held while reading slice info or swapping targets or auditTargets.
|
||||
swapMu sync.Mutex
|
||||
|
||||
// targets is the set of enabled loggers.
|
||||
// Must be immutable at all times.
|
||||
// Can be swapped to another while holding swapMu
|
||||
var targets = []Target{}
|
||||
var nTargets int32 // atomic count of len(targets)
|
||||
// targets is the set of enabled loggers.
|
||||
// Must be immutable at all times.
|
||||
// Can be swapped to another while holding swapMu
|
||||
targets = []Target{}
|
||||
nTargets int32 // atomic count of len(targets)
|
||||
)
|
||||
|
||||
// Targets returns active targets.
|
||||
// Returned slice may not be modified in any way.
|
||||
@@ -70,8 +72,10 @@ func AuditTargets() []Target {
|
||||
// auditTargets is the list of enabled audit loggers
|
||||
// Must be immutable at all times.
|
||||
// Can be swapped to another while holding swapMu
|
||||
var auditTargets = []Target{}
|
||||
var nAuditTargets int32 // atomic count of len(auditTargets)
|
||||
var (
|
||||
auditTargets = []Target{}
|
||||
nAuditTargets int32 // atomic count of len(auditTargets)
|
||||
)
|
||||
|
||||
// AddAuditTarget adds a new audit logger target to the
|
||||
// list of enabled loggers
|
||||
|
||||
Reference in New Issue
Block a user