diff --git a/api/admin_client_mock.go b/api/admin_client_mock.go index f1dea3e638..dc2dfc6ae1 100644 --- a/api/admin_client_mock.go +++ b/api/admin_client_mock.go @@ -18,332 +18,18 @@ package api import ( "context" - "io" - "time" "github.com/minio/madmin-go/v3" - iampolicy "github.com/minio/pkg/v3/policy" ) -type AdminClientMock struct{} - -var ( - MinioServerInfoMock func(ctx context.Context) (madmin.InfoMessage, error) - minioChangePasswordMock func(ctx context.Context, accessKey, secretKey string) error - - minioHelpConfigKVMock func(subSys, key string, envOnly bool) (madmin.Help, error) - minioGetConfigKVMock func(key string) ([]byte, error) - minioSetConfigKVMock func(kv string) (restart bool, err error) - minioDelConfigKVMock func(name string) (err error) - minioHelpConfigKVGlobalMock func(envOnly bool) (madmin.Help, error) - - minioGetLogsMock func(ctx context.Context, node string, lineCnt int, logKind string) <-chan madmin.LogInfo - - minioListGroupsMock func() ([]string, error) - minioUpdateGroupMembersMock func(madmin.GroupAddRemove) error - minioGetGroupDescriptionMock func(group string) (*madmin.GroupDesc, error) - minioSetGroupStatusMock func(group string, status madmin.GroupStatus) error - - minioHealMock func(ctx context.Context, bucket, prefix string, healOpts madmin.HealOpts, clientToken string, - forceStart, forceStop bool) (healStart madmin.HealStartSuccess, healTaskStatus madmin.HealTaskStatus, err error) - - minioServerHealthInfoMock func(ctx context.Context, deadline time.Duration) (interface{}, string, error) - - minioListPoliciesMock func() (map[string]*iampolicy.Policy, error) - minioGetPolicyMock func(name string) (*iampolicy.Policy, error) - minioRemovePolicyMock func(name string) error - minioAddPolicyMock func(name string, policy *iampolicy.Policy) error - minioSetPolicyMock func(policyName, entityName string, isGroup bool) error - - minioStartProfiling func(profiler madmin.ProfilerType, duration time.Duration) (io.ReadCloser, error) - - minioServiceRestartMock func(ctx context.Context) error - - getSiteReplicationInfo func(ctx context.Context) (*madmin.SiteReplicationInfo, error) - addSiteReplicationInfo func(ctx context.Context, sites []madmin.PeerSite) (*madmin.ReplicateAddStatus, error) - editSiteReplicationInfo func(ctx context.Context, site madmin.PeerInfo) (*madmin.ReplicateEditStatus, error) - deleteSiteReplicationInfoMock func(ctx context.Context, removeReq madmin.SRRemoveReq) (*madmin.ReplicateRemoveStatus, error) - getSiteReplicationStatus func(ctx context.Context, params madmin.SRStatusOptions) (*madmin.SRStatusInfo, error) - - minioListTiersMock func(ctx context.Context) ([]*madmin.TierConfig, error) - minioTierStatsMock func(ctx context.Context) ([]madmin.TierInfo, error) - minioAddTiersMock func(ctx context.Context, tier *madmin.TierConfig) error - minioRemoveTierMock func(ctx context.Context, tierName string) error - minioEditTiersMock func(ctx context.Context, tierName string, creds madmin.TierCreds) error - minioVerifyTierStatusMock func(ctx context.Context, tierName string) error - - minioServiceTraceMock func(ctx context.Context, threshold int64, s3, internal, storage, os, errTrace bool) <-chan madmin.ServiceTraceInfo - - minioListUsersMock func() (map[string]madmin.UserInfo, error) - minioAddUserMock func(accessKey, secreyKey string) error - minioRemoveUserMock func(accessKey string) error - minioGetUserInfoMock func(accessKey string) (madmin.UserInfo, error) - minioSetUserStatusMock func(accessKey string, status madmin.AccountStatus) error - - minioAccountInfoMock func(ctx context.Context) (madmin.AccountInfo, error) - minioAddServiceAccountMock func(ctx context.Context, policy string, user string, accessKey string, secretKey string, description string, name string, expiry *time.Time, status string) (madmin.Credentials, error) - minioListServiceAccountsMock func(ctx context.Context, user string) (madmin.ListServiceAccountsResp, error) - minioDeleteServiceAccountMock func(ctx context.Context, serviceAccount string) error - minioInfoServiceAccountMock func(ctx context.Context, serviceAccount string) (madmin.InfoServiceAccountResp, error) - minioUpdateServiceAccountMock func(ctx context.Context, serviceAccount string, opts madmin.UpdateServiceAccountReq) error - minioGetLDAPPolicyEntitiesMock func(ctx context.Context, query madmin.PolicyEntitiesQuery) (madmin.PolicyEntitiesResult, error) - - minioListRemoteBucketsMock func(ctx context.Context, bucket, arnType string) (targets []madmin.BucketTarget, err error) - minioGetRemoteBucketMock func(ctx context.Context, bucket, arnType string) (targets *madmin.BucketTarget, err error) - minioAddRemoteBucketMock func(ctx context.Context, bucket string, target *madmin.BucketTarget) (string, error) -) - -func (ac AdminClientMock) serverInfo(ctx context.Context) (madmin.InfoMessage, error) { - return MinioServerInfoMock(ctx) -} - -func (ac AdminClientMock) listRemoteBuckets(ctx context.Context, bucket, arnType string) (targets []madmin.BucketTarget, err error) { - return minioListRemoteBucketsMock(ctx, bucket, arnType) -} - -func (ac AdminClientMock) getRemoteBucket(ctx context.Context, bucket, arnType string) (targets *madmin.BucketTarget, err error) { - return minioGetRemoteBucketMock(ctx, bucket, arnType) -} - -func (ac AdminClientMock) removeRemoteBucket(_ context.Context, _, _ string) error { - return nil -} - -func (ac AdminClientMock) addRemoteBucket(ctx context.Context, bucket string, target *madmin.BucketTarget) (string, error) { - return minioAddRemoteBucketMock(ctx, bucket, target) -} - -func (ac AdminClientMock) changePassword(ctx context.Context, accessKey, secretKey string) error { - return minioChangePasswordMock(ctx, accessKey, secretKey) -} - -func (ac AdminClientMock) speedtest(_ context.Context, _ madmin.SpeedtestOpts) (chan madmin.SpeedTestResult, error) { - return nil, nil -} - -func (ac AdminClientMock) verifyTierStatus(ctx context.Context, tier string) error { - return minioVerifyTierStatusMock(ctx, tier) -} - -// mock function helpConfigKV() -func (ac AdminClientMock) helpConfigKV(_ context.Context, subSys, key string, envOnly bool) (madmin.Help, error) { - return minioHelpConfigKVMock(subSys, key, envOnly) -} - -// mock function getConfigKV() -func (ac AdminClientMock) getConfigKV(_ context.Context, name string) ([]byte, error) { - return minioGetConfigKVMock(name) -} - -// mock function setConfigKV() -func (ac AdminClientMock) setConfigKV(_ context.Context, kv string) (restart bool, err error) { - return minioSetConfigKVMock(kv) -} - -// mock function helpConfigKV() -func (ac AdminClientMock) helpConfigKVGlobal(_ context.Context, envOnly bool) (madmin.Help, error) { - return minioHelpConfigKVGlobalMock(envOnly) -} - -func (ac AdminClientMock) delConfigKV(_ context.Context, name string) (err error) { - return minioDelConfigKVMock(name) -} - -func (ac AdminClientMock) getLogs(ctx context.Context, node string, lineCnt int, logKind string) <-chan madmin.LogInfo { - return minioGetLogsMock(ctx, node, lineCnt, logKind) -} - -func (ac AdminClientMock) listGroups(_ context.Context) ([]string, error) { - return minioListGroupsMock() -} - -func (ac AdminClientMock) updateGroupMembers(_ context.Context, req madmin.GroupAddRemove) error { - return minioUpdateGroupMembersMock(req) -} - -func (ac AdminClientMock) getGroupDescription(_ context.Context, group string) (*madmin.GroupDesc, error) { - return minioGetGroupDescriptionMock(group) -} - -func (ac AdminClientMock) setGroupStatus(_ context.Context, group string, status madmin.GroupStatus) error { - return minioSetGroupStatusMock(group, status) -} - -func (ac AdminClientMock) heal(ctx context.Context, bucket, prefix string, healOpts madmin.HealOpts, clientToken string, - forceStart, forceStop bool, -) (healStart madmin.HealStartSuccess, healTaskStatus madmin.HealTaskStatus, err error) { - return minioHealMock(ctx, bucket, prefix, healOpts, clientToken, forceStart, forceStop) -} - -func (ac AdminClientMock) serverHealthInfo(ctx context.Context, deadline time.Duration) (interface{}, string, error) { - return minioServerHealthInfoMock(ctx, deadline) -} - -func (ac AdminClientMock) addOrUpdateIDPConfig(_ context.Context, _, _, _ string, _ bool) (restart bool, err error) { - return true, nil -} - -func (ac AdminClientMock) listIDPConfig(_ context.Context, _ string) ([]madmin.IDPListItem, error) { - return []madmin.IDPListItem{{Name: "mock"}}, nil -} - -func (ac AdminClientMock) deleteIDPConfig(_ context.Context, _, _ string) (restart bool, err error) { - return true, nil -} - -func (ac AdminClientMock) getIDPConfig(_ context.Context, _, _ string) (c madmin.IDPConfig, err error) { - return madmin.IDPConfig{Info: []madmin.IDPCfgInfo{{Key: "mock", Value: "mock"}}}, nil +type AdminClientMock struct { + minioAccountInfoMock func(ctx context.Context) (madmin.AccountInfo, error) } func (ac AdminClientMock) kmsStatus(_ context.Context) (madmin.KMSStatus, error) { return madmin.KMSStatus{Name: "name", DefaultKeyID: "key", Endpoints: map[string]madmin.ItemState{"localhost": madmin.ItemState("online")}}, nil } -func (ac AdminClientMock) kmsAPIs(_ context.Context) ([]madmin.KMSAPI, error) { - return []madmin.KMSAPI{{Method: "GET", Path: "/mock"}}, nil -} - -func (ac AdminClientMock) kmsMetrics(_ context.Context) (*madmin.KMSMetrics, error) { - return &madmin.KMSMetrics{}, nil -} - -func (ac AdminClientMock) kmsVersion(_ context.Context) (*madmin.KMSVersion, error) { - return &madmin.KMSVersion{Version: "test-version"}, nil -} - -func (ac AdminClientMock) createKey(_ context.Context, _ string) error { - return nil -} - -func (ac AdminClientMock) listKeys(_ context.Context, _ string) ([]madmin.KMSKeyInfo, error) { - return []madmin.KMSKeyInfo{{ - Name: "name", - CreatedBy: "by", - }}, nil -} - -func (ac AdminClientMock) keyStatus(_ context.Context, _ string) (*madmin.KMSKeyStatus, error) { - return &madmin.KMSKeyStatus{KeyID: "key"}, nil -} - -func (ac AdminClientMock) listPolicies(_ context.Context) (map[string]*iampolicy.Policy, error) { - return minioListPoliciesMock() -} - -func (ac AdminClientMock) getPolicy(_ context.Context, name string) (*iampolicy.Policy, error) { - return minioGetPolicyMock(name) -} - -func (ac AdminClientMock) removePolicy(_ context.Context, name string) error { - return minioRemovePolicyMock(name) -} - -func (ac AdminClientMock) addPolicy(_ context.Context, name string, policy *iampolicy.Policy) error { - return minioAddPolicyMock(name, policy) -} - -func (ac AdminClientMock) setPolicy(_ context.Context, policyName, entityName string, isGroup bool) error { - return minioSetPolicyMock(policyName, entityName, isGroup) -} - -// mock function for startProfiling() -func (ac AdminClientMock) startProfiling(_ context.Context, profiler madmin.ProfilerType, duration time.Duration) (io.ReadCloser, error) { - return minioStartProfiling(profiler, duration) -} - -// mock function of serviceRestart() -func (ac AdminClientMock) serviceRestart(ctx context.Context) error { - return minioServiceRestartMock(ctx) -} - -func (ac AdminClientMock) getSiteReplicationInfo(ctx context.Context) (*madmin.SiteReplicationInfo, error) { - return getSiteReplicationInfo(ctx) -} - -func (ac AdminClientMock) addSiteReplicationInfo(ctx context.Context, sites []madmin.PeerSite, _ madmin.SRAddOptions) (*madmin.ReplicateAddStatus, error) { - return addSiteReplicationInfo(ctx, sites) -} - -func (ac AdminClientMock) editSiteReplicationInfo(ctx context.Context, site madmin.PeerInfo, _ madmin.SREditOptions) (*madmin.ReplicateEditStatus, error) { - return editSiteReplicationInfo(ctx, site) -} - -func (ac AdminClientMock) deleteSiteReplicationInfo(ctx context.Context, removeReq madmin.SRRemoveReq) (*madmin.ReplicateRemoveStatus, error) { - return deleteSiteReplicationInfoMock(ctx, removeReq) -} - -func (ac AdminClientMock) getSiteReplicationStatus(ctx context.Context, params madmin.SRStatusOptions) (*madmin.SRStatusInfo, error) { - return getSiteReplicationStatus(ctx, params) -} - -func (ac AdminClientMock) listTiers(ctx context.Context) ([]*madmin.TierConfig, error) { - return minioListTiersMock(ctx) -} - -func (ac AdminClientMock) tierStats(ctx context.Context) ([]madmin.TierInfo, error) { - return minioTierStatsMock(ctx) -} - -func (ac AdminClientMock) addTier(ctx context.Context, tier *madmin.TierConfig) error { - return minioAddTiersMock(ctx, tier) -} - -func (ac AdminClientMock) removeTier(ctx context.Context, tierName string) error { - return minioRemoveTierMock(ctx, tierName) -} - -func (ac AdminClientMock) editTierCreds(ctx context.Context, tierName string, creds madmin.TierCreds) error { - return minioEditTiersMock(ctx, tierName, creds) -} - -func (ac AdminClientMock) serviceTrace(ctx context.Context, threshold int64, s3, internal, storage, os, errTrace bool) <-chan madmin.ServiceTraceInfo { - return minioServiceTraceMock(ctx, threshold, s3, internal, storage, os, errTrace) -} - -func (ac AdminClientMock) listUsers(_ context.Context) (map[string]madmin.UserInfo, error) { - return minioListUsersMock() -} - -func (ac AdminClientMock) addUser(_ context.Context, accessKey, secretKey string) error { - return minioAddUserMock(accessKey, secretKey) -} - -func (ac AdminClientMock) removeUser(_ context.Context, accessKey string) error { - return minioRemoveUserMock(accessKey) -} - -func (ac AdminClientMock) getUserInfo(_ context.Context, accessKey string) (madmin.UserInfo, error) { - return minioGetUserInfoMock(accessKey) -} - -func (ac AdminClientMock) setUserStatus(_ context.Context, accessKey string, status madmin.AccountStatus) error { - return minioSetUserStatusMock(accessKey, status) -} - func (ac AdminClientMock) AccountInfo(ctx context.Context) (madmin.AccountInfo, error) { - return minioAccountInfoMock(ctx) -} - -func (ac AdminClientMock) addServiceAccount(ctx context.Context, policy string, user string, accessKey string, secretKey string, description string, name string, expiry *time.Time, status string) (madmin.Credentials, error) { - return minioAddServiceAccountMock(ctx, policy, user, accessKey, secretKey, description, name, expiry, status) -} - -func (ac AdminClientMock) listServiceAccounts(ctx context.Context, user string) (madmin.ListServiceAccountsResp, error) { - return minioListServiceAccountsMock(ctx, user) -} - -func (ac AdminClientMock) deleteServiceAccount(ctx context.Context, serviceAccount string) error { - return minioDeleteServiceAccountMock(ctx, serviceAccount) -} - -func (ac AdminClientMock) infoServiceAccount(ctx context.Context, serviceAccount string) (madmin.InfoServiceAccountResp, error) { - return minioInfoServiceAccountMock(ctx, serviceAccount) -} - -func (ac AdminClientMock) updateServiceAccount(ctx context.Context, serviceAccount string, opts madmin.UpdateServiceAccountReq) error { - return minioUpdateServiceAccountMock(ctx, serviceAccount, opts) -} - -func (ac AdminClientMock) getLDAPPolicyEntities(ctx context.Context, query madmin.PolicyEntitiesQuery) (madmin.PolicyEntitiesResult, error) { - return minioGetLDAPPolicyEntitiesMock(ctx, query) + return ac.minioAccountInfoMock(ctx) } diff --git a/api/admin_console.go b/api/admin_console.go deleted file mode 100644 index f7e47c6b99..0000000000 --- a/api/admin_console.go +++ /dev/null @@ -1,104 +0,0 @@ -// This file is part of MinIO Console Server -// Copyright (c) 2021 MinIO, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package api - -import ( - "context" - "encoding/json" - "strings" - "time" - - "github.com/minio/madmin-go/v3" - "github.com/minio/websocket" -) - -const logTimeFormat string = "15:04:05 MST 01/02/2006" - -// startConsoleLog starts log of the servers -func startConsoleLog(ctx context.Context, conn WSConn, client MinioAdmin, logRequest LogRequest) error { - var node string - // name of node, default = "" (all) - if logRequest.node == "all" { - node = "" - } else { - node = logRequest.node - } - - trimNode := strings.Split(node, ":") - // number of log lines - lineCount := 100 - // type of logs "minio"|"application"|"all" default = "all" - var logKind string - if logRequest.logType == "minio" || logRequest.logType == "application" || logRequest.logType == "all" { - logKind = logRequest.logType - } else { - logKind = "all" - } - - // Start listening on all Console Log activity. - logCh := client.getLogs(ctx, trimNode[0], lineCount, logKind) - - for { - select { - case <-ctx.Done(): - return nil - case logInfo, ok := <-logCh: - - // zero value returned because the channel is closed and empty - if !ok { - return nil - } - if logInfo.Err != nil { - LogError("error on console logs: %v", logInfo.Err) - return logInfo.Err - } - - // Serialize message to be sent - bytes, err := json.Marshal(serializeConsoleLogInfo(&logInfo)) - if err != nil { - LogError("error on json.Marshal: %v", err) - return err - } - - // Send Message through websocket connection - err = conn.writeMessage(websocket.TextMessage, bytes) - if err != nil { - LogError("error writeMessage: %v", err) - return err - } - } - } -} - -func serializeConsoleLogInfo(l *madmin.LogInfo) (logInfo madmin.LogInfo) { - logInfo = *l - if logInfo.ConsoleMsg != "" { - logInfo.ConsoleMsg = strings.TrimPrefix(logInfo.ConsoleMsg, "\n") - } - if logInfo.Time != "" { - logInfo.Time = getLogTime(logInfo.Time) - } - return logInfo -} - -func getLogTime(lt string) string { - tm, err := time.Parse(time.RFC3339Nano, lt) - if err != nil { - return lt - } - return tm.Format(logTimeFormat) -} diff --git a/api/admin_console_test.go b/api/admin_console_test.go deleted file mode 100644 index 05e09d6036..0000000000 --- a/api/admin_console_test.go +++ /dev/null @@ -1,117 +0,0 @@ -// This file is part of MinIO Console Server -// Copyright (c) 2021 MinIO, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package api - -import ( - "context" - "encoding/json" - "fmt" - "testing" - - "github.com/minio/madmin-go/v3" - "github.com/stretchr/testify/assert" -) - -func TestAdminConsoleLog(t *testing.T) { - assert := assert.New(t) - adminClient := AdminClientMock{} - mockWSConn := mockConn{} - function := "startConsoleLog(ctx, )" - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - testReceiver := make(chan madmin.LogInfo, 5) - textToReceive := "test message" - testStreamSize := 5 - isClosed := false // testReceiver is closed? - - // Test-1: Serve Console with no errors until Console finishes sending - // define mock function behavior for minio server Console - minioGetLogsMock = func(_ context.Context, _ string, _ int, _ string) <-chan madmin.LogInfo { - ch := make(chan madmin.LogInfo) - // Only success, start a routine to start reading line by line. - go func(ch chan<- madmin.LogInfo) { - defer close(ch) - lines := make([]int, testStreamSize) - // mocking sending 5 lines of info - for range lines { - info := madmin.LogInfo{ - ConsoleMsg: textToReceive, - } - ch <- info - } - }(ch) - return ch - } - writesCount := 1 - // mock connection WriteMessage() no error - connWriteMessageMock = func(_ int, data []byte) error { - // emulate that receiver gets the message written - var t madmin.LogInfo - _ = json.Unmarshal(data, &t) - if writesCount == testStreamSize { - if !isClosed { - close(testReceiver) - isClosed = true - } - return nil - } - testReceiver <- t - writesCount++ - return nil - } - if err := startConsoleLog(ctx, mockWSConn, adminClient, LogRequest{node: "", logType: "all"}); err != nil { - t.Errorf("Failed on %s:, error occurred: %s", function, err.Error()) - } - // check that the TestReceiver got the same number of data from Console. - for i := range testReceiver { - assert.Equal(textToReceive, i.ConsoleMsg) - } - - // Test-2: if error happens while writing, return error - connWriteMessageMock = func(_ int, _ []byte) error { - return fmt.Errorf("error on write") - } - if err := startConsoleLog(ctx, mockWSConn, adminClient, LogRequest{node: "", logType: "all"}); assert.Error(err) { - assert.Equal("error on write", err.Error()) - } - - // Test-3: error happens on GetLogs Minio, Console should stop - // and error shall be returned. - minioGetLogsMock = func(_ context.Context, _ string, _ int, _ string) <-chan madmin.LogInfo { - ch := make(chan madmin.LogInfo) - // Only success, start a routine to start reading line by line. - go func(ch chan<- madmin.LogInfo) { - defer close(ch) - lines := make([]int, 2) - // mocking sending 5 lines of info - for range lines { - info := madmin.LogInfo{ - ConsoleMsg: textToReceive, - } - ch <- info - } - ch <- madmin.LogInfo{Err: fmt.Errorf("error on Console")} - }(ch) - return ch - } - connWriteMessageMock = func(_ int, _ []byte) error { - return nil - } - if err := startConsoleLog(ctx, mockWSConn, adminClient, LogRequest{node: "", logType: "all"}); assert.Error(err) { - assert.Equal("error on Console", err.Error()) - } -} diff --git a/api/admin_profiling.go b/api/admin_profiling.go deleted file mode 100644 index 8e64f08f60..0000000000 --- a/api/admin_profiling.go +++ /dev/null @@ -1,51 +0,0 @@ -// This file is part of MinIO Console Server -// Copyright (c) 2021 MinIO, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package api - -import ( - "context" - "io" - "net/http" - "time" - - "github.com/minio/madmin-go/v3" - "github.com/minio/websocket" -) - -type profileOptions struct { - Types string - Duration time.Duration -} - -func getProfileOptionsFromReq(req *http.Request) (*profileOptions, error) { - pOptions := profileOptions{} - pOptions.Types = req.FormValue("types") - pOptions.Duration = 10 * time.Second // TODO: make this configurable - return &pOptions, nil -} - -func startProfiling(ctx context.Context, conn WSConn, client MinioAdmin, pOpts *profileOptions) error { - data, err := client.startProfiling(ctx, madmin.ProfilerType(pOpts.Types), pOpts.Duration) - if err != nil { - return err - } - message, err := io.ReadAll(data) - if err != nil { - return err - } - return conn.writeMessage(websocket.BinaryMessage, message) -} diff --git a/api/admin_profiling_test.go b/api/admin_profiling_test.go deleted file mode 100644 index 17a62c4150..0000000000 --- a/api/admin_profiling_test.go +++ /dev/null @@ -1,91 +0,0 @@ -// This file is part of MinIO Console Server -// Copyright (c) 2021 MinIO, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package api - -import ( - "bytes" - "context" - "errors" - "io" - "net/http" - "net/url" - "testing" - "time" - - "github.com/minio/madmin-go/v3" - "github.com/stretchr/testify/assert" -) - -// Implementing fake closingBuffer to mock stopProfiling() (io.ReadCloser, error) -type ClosingBuffer struct { - *bytes.Buffer -} - -// Implementing a fake Close function for io.ReadCloser -func (cb *ClosingBuffer) Close() error { - return nil -} - -func TestStartProfiling(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - assert := assert.New(t) - adminClient := AdminClientMock{} - mockWSConn := mockConn{} - function := "startProfiling()" - testOptions := &profileOptions{ - Types: "cpu", - } - - // Test-1 : startProfiling() Get response from MinIO server with one profiling object without errors - // mock function response from startProfiling() - minioStartProfiling = func(_ madmin.ProfilerType, _ time.Duration) (io.ReadCloser, error) { - return &ClosingBuffer{bytes.NewBufferString("In memory string eaeae")}, nil - } - // mock function response from mockConn.writeMessage() - connWriteMessageMock = func(_ int, _ []byte) error { - return nil - } - err := startProfiling(ctx, mockWSConn, adminClient, testOptions) - if err != nil { - t.Errorf("Failed on %s:, error occurred: %s", function, err.Error()) - } - assert.Equal(err, nil) - - // Test-2 : startProfiling() Correctly handles errors returned by MinIO - // mock function response from startProfiling() - minioStartProfiling = func(_ madmin.ProfilerType, _ time.Duration) (io.ReadCloser, error) { - return nil, errors.New("error") - } - err = startProfiling(ctx, mockWSConn, adminClient, testOptions) - if assert.Error(err) { - assert.Equal("error", err.Error()) - } - - // Test-3: getProfileOptionsFromReq() correctly returns profile options from request - u, _ := url.Parse("ws://localhost/ws/profile?types=cpu,mem,block,mutex,trace,threads,goroutines") - req := &http.Request{ - URL: u, - } - opts, err := getProfileOptionsFromReq(req) - if assert.NoError(err) { - expectedOptions := profileOptions{ - Types: "cpu,mem,block,mutex,trace,threads,goroutines", - } - assert.Equal(expectedOptions.Types, opts.Types) - } -} diff --git a/api/admin_trace.go b/api/admin_trace.go deleted file mode 100644 index 9bb64ee11e..0000000000 --- a/api/admin_trace.go +++ /dev/null @@ -1,153 +0,0 @@ -// This file is part of MinIO Console Server -// Copyright (c) 2021 MinIO, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package api - -import ( - "context" - "encoding/json" - "net/http" - "strings" - "time" - - "github.com/minio/madmin-go/v3" - "github.com/minio/websocket" -) - -// shortTraceMsg Short trace record -type shortTraceMsg struct { - Host string `json:"host"` - Time string `json:"time"` - Client string `json:"client"` - CallStats callStats `json:"callStats"` - FuncName string `json:"api"` - Path string `json:"path"` - Query string `json:"query"` - StatusCode int `json:"statusCode"` - StatusMsg string `json:"statusMsg"` -} - -type callStats struct { - Rx int `json:"rx"` - Tx int `json:"tx"` - Duration string `json:"duration"` - Ttfb string `json:"timeToFirstByte"` -} - -// trace filters -func matchTrace(opts TraceRequest, traceInfo madmin.ServiceTraceInfo) bool { - statusCode := int(opts.statusCode) - method := opts.method - funcName := opts.funcName - apiPath := opts.path - - if statusCode == 0 && method == "" && funcName == "" && apiPath == "" { - // no specific filtering found trace all the requests - return true - } - - // Filter request path if passed by the user - if apiPath != "" { - pathToLookup := strings.ToLower(apiPath) - pathFromTrace := strings.ToLower(traceInfo.Trace.Path) - - return strings.Contains(pathFromTrace, pathToLookup) - } - - // Filter response status codes if passed by the user - if statusCode > 0 && traceInfo.Trace.HTTP != nil { - statusCodeFromTrace := traceInfo.Trace.HTTP.RespInfo.StatusCode - - return statusCodeFromTrace == statusCode - } - - // Filter request method if passed by the user - if method != "" && traceInfo.Trace.HTTP != nil { - methodFromTrace := traceInfo.Trace.HTTP.ReqInfo.Method - - return methodFromTrace == method - } - - if funcName != "" { - funcToLookup := strings.ToLower(funcName) - funcFromTrace := strings.ToLower(traceInfo.Trace.FuncName) - - return strings.Contains(funcFromTrace, funcToLookup) - } - - return true -} - -// startTraceInfo starts trace of the servers -func startTraceInfo(ctx context.Context, conn WSConn, client MinioAdmin, opts TraceRequest) error { - // Start listening on all trace activity. - traceCh := client.serviceTrace(ctx, opts.threshold, opts.s3, opts.internal, opts.storage, opts.os, opts.onlyErrors) - for { - select { - case <-ctx.Done(): - return nil - case traceInfo, ok := <-traceCh: - // zero value returned because the channel is closed and empty - if !ok { - return nil - } - if traceInfo.Err != nil { - LogError("error on serviceTrace: %v", traceInfo.Err) - return traceInfo.Err - } - if matchTrace(opts, traceInfo) { - // Serialize message to be sent - traceInfoBytes, err := json.Marshal(shortTrace(&traceInfo)) - if err != nil { - LogError("error on json.Marshal: %v", err) - return err - } - // Send Message through websocket connection - err = conn.writeMessage(websocket.TextMessage, traceInfoBytes) - if err != nil { - LogError("error writeMessage: %v", err) - return err - } - } - } - } -} - -// shortTrace creates a shorter Trace Info message. -// Same implementation as github/minio/mc/cmd/admin-trace.go -func shortTrace(info *madmin.ServiceTraceInfo) shortTraceMsg { - t := info.Trace - s := shortTraceMsg{} - - s.Time = t.Time.Format(time.RFC3339) - s.Path = t.Path - s.FuncName = t.FuncName - s.CallStats.Duration = t.Duration.String() - if info.Trace.HTTP != nil { - s.Query = t.HTTP.ReqInfo.RawQuery - s.StatusCode = t.HTTP.RespInfo.StatusCode - s.StatusMsg = http.StatusText(t.HTTP.RespInfo.StatusCode) - s.CallStats.Rx = t.HTTP.CallStats.InputBytes - s.CallStats.Tx = t.HTTP.CallStats.OutputBytes - s.CallStats.Ttfb = t.HTTP.CallStats.TimeToFirstByte.String() - if host, ok := t.HTTP.ReqInfo.Headers["Host"]; ok { - s.Host = strings.Join(host, "") - } - s.Client = t.HTTP.ReqInfo.Client - } - - return s -} diff --git a/api/admin_trace_test.go b/api/admin_trace_test.go deleted file mode 100644 index 227e900b9f..0000000000 --- a/api/admin_trace_test.go +++ /dev/null @@ -1,119 +0,0 @@ -// This file is part of MinIO Console Server -// Copyright (c) 2021 MinIO, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package api - -import ( - "context" - "encoding/json" - "fmt" - "testing" - - "github.com/minio/madmin-go/v3" - "github.com/stretchr/testify/assert" -) - -func TestAdminTrace(t *testing.T) { - assert := assert.New(t) - adminClient := AdminClientMock{} - mockWSConn := mockConn{} - function := "startTraceInfo(ctx, )" - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - testReceiver := make(chan shortTraceMsg, 5) - textToReceive := "test" - testStreamSize := 5 - isClosed := false // testReceiver is closed? - - // Test-1: Serve Trace with no errors until trace finishes sending - // define mock function behavior for minio server Trace - minioServiceTraceMock = func(_ context.Context, _ int64, _, _, _, _, _ bool) <-chan madmin.ServiceTraceInfo { - ch := make(chan madmin.ServiceTraceInfo) - // Only success, start a routine to start reading line by line. - go func(ch chan<- madmin.ServiceTraceInfo) { - defer close(ch) - lines := make([]int, testStreamSize) - // mocking sending 5 lines of info - for range lines { - info := madmin.TraceInfo{ - FuncName: textToReceive, - } - ch <- madmin.ServiceTraceInfo{Trace: info} - } - }(ch) - return ch - } - writesCount := 1 - // mock connection WriteMessage() no error - connWriteMessageMock = func(_ int, data []byte) error { - // emulate that receiver gets the message written - var t shortTraceMsg - _ = json.Unmarshal(data, &t) - if writesCount == testStreamSize { - // for testing we need to close the receiver channel - if !isClosed { - close(testReceiver) - isClosed = true - } - return nil - } - testReceiver <- t - writesCount++ - return nil - } - if err := startTraceInfo(ctx, mockWSConn, adminClient, TraceRequest{s3: true, internal: true, storage: true, os: true, onlyErrors: false}); err != nil { - t.Errorf("Failed on %s:, error occurred: %s", function, err.Error()) - } - // check that the TestReceiver got the same number of data from trace. - for i := range testReceiver { - assert.Equal(textToReceive, i.FuncName) - } - - // Test-2: if error happens while writing, return error - connWriteMessageMock = func(_ int, _ []byte) error { - return fmt.Errorf("error on write") - } - if err := startTraceInfo(ctx, mockWSConn, adminClient, TraceRequest{}); assert.Error(err) { - assert.Equal("error on write", err.Error()) - } - - // Test-3: error happens on serviceTrace Minio, trace should stop - // and error shall be returned. - minioServiceTraceMock = func(_ context.Context, _ int64, _, _, _, _, _ bool) <-chan madmin.ServiceTraceInfo { - ch := make(chan madmin.ServiceTraceInfo) - // Only success, start a routine to start reading line by line. - go func(ch chan<- madmin.ServiceTraceInfo) { - defer close(ch) - lines := make([]int, 2) - // mocking sending 5 lines of info - for range lines { - info := madmin.TraceInfo{ - NodeName: "test", - } - ch <- madmin.ServiceTraceInfo{Trace: info} - } - ch <- madmin.ServiceTraceInfo{Err: fmt.Errorf("error on trace")} - }(ch) - return ch - } - connWriteMessageMock = func(_ int, _ []byte) error { - return nil - } - if err := startTraceInfo(ctx, mockWSConn, adminClient, TraceRequest{}); assert.Error(err) { - assert.Equal("error on trace", err.Error()) - } -} diff --git a/api/client-admin.go b/api/client-admin.go index def2acc976..bc5b9829d7 100644 --- a/api/client-admin.go +++ b/api/client-admin.go @@ -17,16 +17,12 @@ package api import ( - "bytes" "context" - "encoding/json" - "io" "net" "net/http" "net/url" "regexp" "strings" - "time" "github.com/minio/console/pkg" @@ -35,7 +31,6 @@ import ( "github.com/minio/console/models" "github.com/minio/madmin-go/v3" "github.com/minio/minio-go/v7/pkg/credentials" - iampolicy "github.com/minio/pkg/v3/policy" ) const globalAppName = "MinIO Console" @@ -44,87 +39,9 @@ const globalAppName = "MinIO Console" // by mock when testing, it should include all MinioAdmin respective api calls // that are used within this project. type MinioAdmin interface { - listUsers(ctx context.Context) (map[string]madmin.UserInfo, error) - addUser(ctx context.Context, acessKey, SecretKey string) error - removeUser(ctx context.Context, accessKey string) error - getUserInfo(ctx context.Context, accessKey string) (madmin.UserInfo, error) - setUserStatus(ctx context.Context, accessKey string, status madmin.AccountStatus) error - listGroups(ctx context.Context) ([]string, error) - updateGroupMembers(ctx context.Context, greq madmin.GroupAddRemove) error - getGroupDescription(ctx context.Context, group string) (*madmin.GroupDesc, error) - setGroupStatus(ctx context.Context, group string, status madmin.GroupStatus) error - listPolicies(ctx context.Context) (map[string]*iampolicy.Policy, error) - getPolicy(ctx context.Context, name string) (*iampolicy.Policy, error) - removePolicy(ctx context.Context, name string) error - addPolicy(ctx context.Context, name string, policy *iampolicy.Policy) error - setPolicy(ctx context.Context, policyName, entityName string, isGroup bool) error - getConfigKV(ctx context.Context, key string) ([]byte, error) - helpConfigKV(ctx context.Context, subSys, key string, envOnly bool) (madmin.Help, error) - helpConfigKVGlobal(ctx context.Context, envOnly bool) (madmin.Help, error) - setConfigKV(ctx context.Context, kv string) (restart bool, err error) - delConfigKV(ctx context.Context, kv string) (err error) - serviceRestart(ctx context.Context) error - serverInfo(ctx context.Context) (madmin.InfoMessage, error) - startProfiling(ctx context.Context, profiler madmin.ProfilerType, duration time.Duration) (io.ReadCloser, error) - serviceTrace(ctx context.Context, threshold int64, s3, internal, storage, os, errTrace bool) <-chan madmin.ServiceTraceInfo - getLogs(ctx context.Context, node string, lineCnt int, logKind string) <-chan madmin.LogInfo AccountInfo(ctx context.Context) (madmin.AccountInfo, error) - heal(ctx context.Context, bucket, prefix string, healOpts madmin.HealOpts, clientToken string, - forceStart, forceStop bool) (healStart madmin.HealStartSuccess, healTaskStatus madmin.HealTaskStatus, err error) - // Service Accounts - addServiceAccount(ctx context.Context, policy string, user string, accessKey string, secretKey string, name string, description string, expiry *time.Time, comment string) (madmin.Credentials, error) - listServiceAccounts(ctx context.Context, user string) (madmin.ListServiceAccountsResp, error) - deleteServiceAccount(ctx context.Context, serviceAccount string) error - infoServiceAccount(ctx context.Context, serviceAccount string) (madmin.InfoServiceAccountResp, error) - updateServiceAccount(ctx context.Context, serviceAccount string, opts madmin.UpdateServiceAccountReq) error - // Remote Buckets - listRemoteBuckets(ctx context.Context, bucket, arnType string) (targets []madmin.BucketTarget, err error) - getRemoteBucket(ctx context.Context, bucket, arnType string) (targets *madmin.BucketTarget, err error) - removeRemoteBucket(ctx context.Context, bucket, arn string) error - addRemoteBucket(ctx context.Context, bucket string, target *madmin.BucketTarget) (string, error) - // Account password management - changePassword(ctx context.Context, accessKey, secretKey string) error - serverHealthInfo(ctx context.Context, deadline time.Duration) (interface{}, string, error) - // List Tiers - listTiers(ctx context.Context) ([]*madmin.TierConfig, error) - // Tier Info - tierStats(ctx context.Context) ([]madmin.TierInfo, error) - // Add Tier - addTier(ctx context.Context, tier *madmin.TierConfig) error - // Edit Tier Credentials - editTierCreds(ctx context.Context, tierName string, creds madmin.TierCreds) error - // verify Tier status - verifyTierStatus(ctx context.Context, tierName string) error - // remove empty Tier - removeTier(ctx context.Context, tierName string) error - // Speedtest - speedtest(ctx context.Context, opts madmin.SpeedtestOpts) (chan madmin.SpeedTestResult, error) - // Site Relication - getSiteReplicationInfo(ctx context.Context) (*madmin.SiteReplicationInfo, error) - addSiteReplicationInfo(ctx context.Context, sites []madmin.PeerSite, opts madmin.SRAddOptions) (*madmin.ReplicateAddStatus, error) - editSiteReplicationInfo(ctx context.Context, site madmin.PeerInfo, opts madmin.SREditOptions) (*madmin.ReplicateEditStatus, error) - deleteSiteReplicationInfo(ctx context.Context, removeReq madmin.SRRemoveReq) (*madmin.ReplicateRemoveStatus, error) - - // Replication status - getSiteReplicationStatus(ctx context.Context, params madmin.SRStatusOptions) (*madmin.SRStatusInfo, error) - // KMS kmsStatus(ctx context.Context) (madmin.KMSStatus, error) - kmsMetrics(ctx context.Context) (*madmin.KMSMetrics, error) - kmsAPIs(ctx context.Context) ([]madmin.KMSAPI, error) - kmsVersion(ctx context.Context) (*madmin.KMSVersion, error) - createKey(ctx context.Context, key string) error - listKeys(ctx context.Context, pattern string) ([]madmin.KMSKeyInfo, error) - keyStatus(ctx context.Context, key string) (*madmin.KMSKeyStatus, error) - - // IDP - addOrUpdateIDPConfig(ctx context.Context, idpType, cfgName, cfgData string, update bool) (restart bool, err error) - listIDPConfig(ctx context.Context, idpType string) ([]madmin.IDPListItem, error) - deleteIDPConfig(ctx context.Context, idpType, cfgName string) (restart bool, err error) - getIDPConfig(ctx context.Context, cfgType, cfgName string) (c madmin.IDPConfig, err error) - - // LDAP - getLDAPPolicyEntities(ctx context.Context, query madmin.PolicyEntitiesQuery) (madmin.PolicyEntitiesResult, error) } // Interface implementation @@ -135,292 +52,17 @@ type AdminClient struct { Client *madmin.AdminClient } -func (ac AdminClient) changePassword(ctx context.Context, accessKey, secretKey string) error { - return ac.Client.SetUser(ctx, accessKey, secretKey, madmin.AccountEnabled) -} - -// implements madmin.ListUsers() -func (ac AdminClient) listUsers(ctx context.Context) (map[string]madmin.UserInfo, error) { - return ac.Client.ListUsers(ctx) -} - -// implements madmin.AddUser() -func (ac AdminClient) addUser(ctx context.Context, accessKey, secretKey string) error { - return ac.Client.AddUser(ctx, accessKey, secretKey) -} - -// implements madmin.RemoveUser() -func (ac AdminClient) removeUser(ctx context.Context, accessKey string) error { - return ac.Client.RemoveUser(ctx, accessKey) -} - -// implements madmin.GetUserInfo() -func (ac AdminClient) getUserInfo(ctx context.Context, accessKey string) (madmin.UserInfo, error) { - return ac.Client.GetUserInfo(ctx, accessKey) -} - -// implements madmin.SetUserStatus() -func (ac AdminClient) setUserStatus(ctx context.Context, accessKey string, status madmin.AccountStatus) error { - return ac.Client.SetUserStatus(ctx, accessKey, status) -} - -// implements madmin.ListGroups() -func (ac AdminClient) listGroups(ctx context.Context) ([]string, error) { - return ac.Client.ListGroups(ctx) -} - -// implements madmin.UpdateGroupMembers() -func (ac AdminClient) updateGroupMembers(ctx context.Context, greq madmin.GroupAddRemove) error { - return ac.Client.UpdateGroupMembers(ctx, greq) -} - -// implements madmin.GetGroupDescription(group) -func (ac AdminClient) getGroupDescription(ctx context.Context, group string) (*madmin.GroupDesc, error) { - return ac.Client.GetGroupDescription(ctx, group) -} - -// implements madmin.SetGroupStatus(group, status) -func (ac AdminClient) setGroupStatus(ctx context.Context, group string, status madmin.GroupStatus) error { - return ac.Client.SetGroupStatus(ctx, group, status) -} - -// implements madmin.ListCannedPolicies() -func (ac AdminClient) listPolicies(ctx context.Context) (map[string]*iampolicy.Policy, error) { - policyMap, err := ac.Client.ListCannedPolicies(ctx) - if err != nil { - return nil, err - } - policies := make(map[string]*iampolicy.Policy, len(policyMap)) - for k, v := range policyMap { - p, err := iampolicy.ParseConfig(bytes.NewReader(v)) - if err != nil { - return nil, err - } - policies[k] = p - } - return policies, nil -} - -// implements madmin.ListCannedPolicies() -func (ac AdminClient) getPolicy(ctx context.Context, name string) (*iampolicy.Policy, error) { - info, err := ac.Client.InfoCannedPolicyV2(ctx, name) - if err != nil { - return nil, err - } - return iampolicy.ParseConfig(bytes.NewReader(info.Policy)) -} - -// implements madmin.RemoveCannedPolicy() -func (ac AdminClient) removePolicy(ctx context.Context, name string) error { - return ac.Client.RemoveCannedPolicy(ctx, name) -} - -// implements madmin.AddCannedPolicy() -func (ac AdminClient) addPolicy(ctx context.Context, name string, policy *iampolicy.Policy) error { - buf, err := json.Marshal(policy) - if err != nil { - return err - } - return ac.Client.AddCannedPolicy(ctx, name, buf) -} - -// implements madmin.SetPolicy() -func (ac AdminClient) setPolicy(ctx context.Context, policyName, entityName string, isGroup bool) error { - // nolint:staticcheck // ignore SA1019 - return ac.Client.SetPolicy(ctx, policyName, entityName, isGroup) -} - -// implements madmin.GetConfigKV() -func (ac AdminClient) getConfigKV(ctx context.Context, key string) ([]byte, error) { - return ac.Client.GetConfigKV(ctx, key) -} - -// implements madmin.HelpConfigKV() -func (ac AdminClient) helpConfigKV(ctx context.Context, subSys, key string, envOnly bool) (madmin.Help, error) { - return ac.Client.HelpConfigKV(ctx, subSys, key, envOnly) -} - -// implements madmin.helpConfigKVGlobal() -func (ac AdminClient) helpConfigKVGlobal(ctx context.Context, envOnly bool) (madmin.Help, error) { - return ac.Client.HelpConfigKV(ctx, "", "", envOnly) -} - -// implements madmin.SetConfigKV() -func (ac AdminClient) setConfigKV(ctx context.Context, kv string) (restart bool, err error) { - return ac.Client.SetConfigKV(ctx, kv) -} - -// implements madmin.DelConfigKV() -func (ac AdminClient) delConfigKV(ctx context.Context, kv string) (err error) { - _, err = ac.Client.DelConfigKV(ctx, kv) - return err -} - -// implements madmin.ServiceRestart() -func (ac AdminClient) serviceRestart(ctx context.Context) (err error) { - return ac.Client.ServiceRestartV2(ctx) -} - -// implements madmin.ServerInfo() -func (ac AdminClient) serverInfo(ctx context.Context) (madmin.InfoMessage, error) { - return ac.Client.ServerInfo(ctx) -} - -// implements madmin.StartProfiling() -func (ac AdminClient) startProfiling(ctx context.Context, profiler madmin.ProfilerType, duration time.Duration) (io.ReadCloser, error) { - return ac.Client.Profile(ctx, profiler, duration) -} - -// implements madmin.ServiceTrace() -func (ac AdminClient) serviceTrace(ctx context.Context, threshold int64, _, internal, storage, os, errTrace bool) <-chan madmin.ServiceTraceInfo { - thresholdT := time.Duration(threshold) - - tracingOptions := madmin.ServiceTraceOpts{ - S3: true, - OnlyErrors: errTrace, - Internal: internal, - Storage: storage, - OS: os, - Threshold: thresholdT, - } - - return ac.Client.ServiceTrace(ctx, tracingOptions) -} - -// implements madmin.GetLogs() -func (ac AdminClient) getLogs(ctx context.Context, node string, lineCnt int, logKind string) <-chan madmin.LogInfo { - return ac.Client.GetLogs(ctx, node, lineCnt, logKind) -} - -// implements madmin.AddServiceAccount() -func (ac AdminClient) addServiceAccount(ctx context.Context, policy string, user string, accessKey string, secretKey string, name string, description string, expiry *time.Time, comment string) (madmin.Credentials, error) { - return ac.Client.AddServiceAccount(ctx, madmin.AddServiceAccountReq{ - Policy: []byte(policy), - TargetUser: user, - AccessKey: accessKey, - SecretKey: secretKey, - Name: name, - Description: description, - Expiration: expiry, - Comment: comment, - }) -} - -// implements madmin.ListServiceAccounts() -func (ac AdminClient) listServiceAccounts(ctx context.Context, user string) (madmin.ListServiceAccountsResp, error) { - return ac.Client.ListServiceAccounts(ctx, user) -} - -// implements madmin.DeleteServiceAccount() -func (ac AdminClient) deleteServiceAccount(ctx context.Context, serviceAccount string) error { - return ac.Client.DeleteServiceAccount(ctx, serviceAccount) -} - -// implements madmin.InfoServiceAccount() -func (ac AdminClient) infoServiceAccount(ctx context.Context, serviceAccount string) (madmin.InfoServiceAccountResp, error) { - return ac.Client.InfoServiceAccount(ctx, serviceAccount) -} - -// implements madmin.UpdateServiceAccount() -func (ac AdminClient) updateServiceAccount(ctx context.Context, serviceAccount string, opts madmin.UpdateServiceAccountReq) error { - return ac.Client.UpdateServiceAccount(ctx, serviceAccount, opts) -} - // AccountInfo implements madmin.AccountInfo() func (ac AdminClient) AccountInfo(ctx context.Context) (madmin.AccountInfo, error) { return ac.Client.AccountInfo(ctx, madmin.AccountOpts{}) } -func (ac AdminClient) heal(ctx context.Context, bucket, prefix string, healOpts madmin.HealOpts, clientToken string, - forceStart, forceStop bool, -) (healStart madmin.HealStartSuccess, healTaskStatus madmin.HealTaskStatus, err error) { - return ac.Client.Heal(ctx, bucket, prefix, healOpts, clientToken, forceStart, forceStop) -} - -// listRemoteBuckets - return a list of remote buckets -func (ac AdminClient) listRemoteBuckets(ctx context.Context, bucket, arnType string) (targets []madmin.BucketTarget, err error) { - return ac.Client.ListRemoteTargets(ctx, bucket, arnType) -} - -// getRemoteBucket - gets remote bucked based on a given bucket name -func (ac AdminClient) getRemoteBucket(ctx context.Context, bucket, arnType string) (*madmin.BucketTarget, error) { - targets, err := ac.Client.ListRemoteTargets(ctx, bucket, arnType) - if err != nil { - return nil, err - } - if len(targets) > 0 { - return &targets[0], nil - } - return nil, err -} - -// removeRemoteBucket removes a remote target associated with particular ARN for this bucket -func (ac AdminClient) removeRemoteBucket(ctx context.Context, bucket, arn string) error { - return ac.Client.RemoveRemoteTarget(ctx, bucket, arn) -} - -// addRemoteBucket sets up a remote target for this bucket -func (ac AdminClient) addRemoteBucket(ctx context.Context, bucket string, target *madmin.BucketTarget) (string, error) { - return ac.Client.SetRemoteTarget(ctx, bucket, target) -} - func (ac AdminClient) getBucketQuota(ctx context.Context, bucket string) (madmin.BucketQuota, error) { return ac.Client.GetBucketQuota(ctx, bucket) } -// serverHealthInfo implements mc.ServerHealthInfo - Connect to a minio server and call Health Info Management API -func (ac AdminClient) serverHealthInfo(ctx context.Context, deadline time.Duration) (interface{}, string, error) { - info := madmin.HealthInfo{} - var healthInfo interface{} - var version string - var resp *http.Response - var err error - resp, version, err = ac.Client.ServerHealthInfo(ctx, madmin.HealthDataTypesList, deadline, "") - if err != nil { - return nil, version, err - } - decoder := json.NewDecoder(resp.Body) - for { - if err = decoder.Decode(&info); err != nil { - break - } - } - if info.Version == "" { - return nil, "", ErrHealthReportFail - } - healthInfo = info - - return healthInfo, version, nil -} - -// implements madmin.listTiers() -func (ac AdminClient) listTiers(ctx context.Context) ([]*madmin.TierConfig, error) { - return ac.Client.ListTiers(ctx) -} - -// implements madmin.tierStats() -func (ac AdminClient) tierStats(ctx context.Context) ([]madmin.TierInfo, error) { - return ac.Client.TierStats(ctx) -} - -// implements madmin.AddTier() -func (ac AdminClient) addTier(ctx context.Context, cfg *madmin.TierConfig) error { - return ac.Client.AddTier(ctx, cfg) -} - -// implements madmin.EditTier() -func (ac AdminClient) editTierCreds(ctx context.Context, tierName string, creds madmin.TierCreds) error { - return ac.Client.EditTier(ctx, tierName, creds) -} - -// implements madmin.VerifyTier() -func (ac AdminClient) verifyTierStatus(ctx context.Context, tierName string) error { - return ac.Client.VerifyTier(ctx, tierName) -} - -// implements madmin.RemoveTier() -func (ac AdminClient) removeTier(ctx context.Context, tierName string) error { - return ac.Client.RemoveTier(ctx, tierName) +func (ac AdminClient) kmsStatus(ctx context.Context) (madmin.KMSStatus, error) { + return ac.Client.KMSStatus(ctx) } func NewMinioAdminClient(ctx context.Context, sessionClaims *models.Principal) (*madmin.AdminClient, error) { @@ -546,114 +188,3 @@ func getClientIP(r *http.Request) string { } return raddr } - -func (ac AdminClient) speedtest(ctx context.Context, opts madmin.SpeedtestOpts) (chan madmin.SpeedTestResult, error) { - return ac.Client.Speedtest(ctx, opts) -} - -// Site Replication -func (ac AdminClient) getSiteReplicationInfo(ctx context.Context) (*madmin.SiteReplicationInfo, error) { - res, err := ac.Client.SiteReplicationInfo(ctx) - if err != nil { - return nil, err - } - return &madmin.SiteReplicationInfo{ - Enabled: res.Enabled, - Name: res.Name, - Sites: res.Sites, - ServiceAccountAccessKey: res.ServiceAccountAccessKey, - }, nil -} - -func (ac AdminClient) addSiteReplicationInfo(ctx context.Context, sites []madmin.PeerSite, opts madmin.SRAddOptions) (*madmin.ReplicateAddStatus, error) { - res, err := ac.Client.SiteReplicationAdd(ctx, sites, opts) - if err != nil { - return nil, err - } - - return &madmin.ReplicateAddStatus{ - Success: res.Success, - Status: res.Status, - ErrDetail: res.ErrDetail, - InitialSyncErrorMessage: res.InitialSyncErrorMessage, - }, nil -} - -func (ac AdminClient) editSiteReplicationInfo(ctx context.Context, site madmin.PeerInfo, opts madmin.SREditOptions) (*madmin.ReplicateEditStatus, error) { - res, err := ac.Client.SiteReplicationEdit(ctx, site, opts) - if err != nil { - return nil, err - } - return &madmin.ReplicateEditStatus{ - Success: res.Success, - Status: res.Status, - ErrDetail: res.ErrDetail, - }, nil -} - -func (ac AdminClient) deleteSiteReplicationInfo(ctx context.Context, removeReq madmin.SRRemoveReq) (*madmin.ReplicateRemoveStatus, error) { - res, err := ac.Client.SiteReplicationRemove(ctx, removeReq) - if err != nil { - return nil, err - } - return &madmin.ReplicateRemoveStatus{ - Status: res.Status, - ErrDetail: res.ErrDetail, - }, nil -} - -func (ac AdminClient) getSiteReplicationStatus(ctx context.Context, params madmin.SRStatusOptions) (*madmin.SRStatusInfo, error) { - res, err := ac.Client.SRStatusInfo(ctx, params) - if err != nil { - return nil, err - } - return &res, nil -} - -func (ac AdminClient) kmsStatus(ctx context.Context) (madmin.KMSStatus, error) { - return ac.Client.KMSStatus(ctx) -} - -func (ac AdminClient) kmsMetrics(ctx context.Context) (*madmin.KMSMetrics, error) { - return ac.Client.KMSMetrics(ctx) -} - -func (ac AdminClient) kmsAPIs(ctx context.Context) ([]madmin.KMSAPI, error) { - return ac.Client.KMSAPIs(ctx) -} - -func (ac AdminClient) kmsVersion(ctx context.Context) (*madmin.KMSVersion, error) { - return ac.Client.KMSVersion(ctx) -} - -func (ac AdminClient) createKey(ctx context.Context, key string) error { - return ac.Client.CreateKey(ctx, key) -} - -func (ac AdminClient) listKeys(ctx context.Context, pattern string) ([]madmin.KMSKeyInfo, error) { - return ac.Client.ListKeys(ctx, pattern) -} - -func (ac AdminClient) keyStatus(ctx context.Context, key string) (*madmin.KMSKeyStatus, error) { - return ac.Client.GetKeyStatus(ctx, key) -} - -func (ac AdminClient) addOrUpdateIDPConfig(ctx context.Context, idpType, cfgName, cfgData string, update bool) (restart bool, err error) { - return ac.Client.AddOrUpdateIDPConfig(ctx, idpType, cfgName, cfgData, update) -} - -func (ac AdminClient) listIDPConfig(ctx context.Context, idpType string) ([]madmin.IDPListItem, error) { - return ac.Client.ListIDPConfig(ctx, idpType) -} - -func (ac AdminClient) deleteIDPConfig(ctx context.Context, idpType, cfgName string) (restart bool, err error) { - return ac.Client.DeleteIDPConfig(ctx, idpType, cfgName) -} - -func (ac AdminClient) getIDPConfig(ctx context.Context, idpType, cfgName string) (c madmin.IDPConfig, err error) { - return ac.Client.GetIDPConfig(ctx, idpType, cfgName) -} - -func (ac AdminClient) getLDAPPolicyEntities(ctx context.Context, query madmin.PolicyEntitiesQuery) (madmin.PolicyEntitiesResult, error) { - return ac.Client.GetLDAPPolicyEntities(ctx, query) -} diff --git a/api/user_buckets_test.go b/api/user_buckets_test.go index 9a3684c324..29fe35edd6 100644 --- a/api/user_buckets_test.go +++ b/api/user_buckets_test.go @@ -40,109 +40,102 @@ import ( "github.com/stretchr/testify/assert" ) -// // Mock mc S3Client functions //// -var ( - mcAddNotificationConfigMock func(ctx context.Context, arn string, events []string, prefix, suffix string, ignoreExisting bool) *probe.Error - mcRemoveNotificationConfigMock func(ctx context.Context, arn string, event string, prefix string, suffix string) *probe.Error - minioGetBucketNotificationMock func(ctx context.Context, bucketName string) (bucketNotification notification.Configuration, err error) -) - // Define a mock struct of mc S3Client interface implementation -type s3ClientMock struct{} +type s3ClientMock struct { + addNotificationConfigMock func(ctx context.Context, arn string, events []string, prefix, suffix string, ignoreExisting bool) *probe.Error + removeNotificationConfigMock func(ctx context.Context, arn string, event string, prefix string, suffix string) *probe.Error + setVersioningMock func(ctx context.Context, state string, excludePrefix []string, excludeFolders bool) *probe.Error +} // implements mc.S3Client.AddNotificationConfigMock() func (c s3ClientMock) addNotificationConfig(ctx context.Context, arn string, events []string, prefix, suffix string, ignoreExisting bool) *probe.Error { - return mcAddNotificationConfigMock(ctx, arn, events, prefix, suffix, ignoreExisting) + return c.addNotificationConfigMock(ctx, arn, events, prefix, suffix, ignoreExisting) } // implements mc.S3Client.DeleteBucketEventNotification() func (c s3ClientMock) removeNotificationConfig(ctx context.Context, arn string, event string, prefix string, suffix string) *probe.Error { - return mcRemoveNotificationConfigMock(ctx, arn, event, prefix, suffix) + return c.removeNotificationConfigMock(ctx, arn, event, prefix, suffix) } -// mock function of getBucketNotification() -func (mc minioClientMock) getBucketNotification(ctx context.Context, bucketName string) (bucketNotification notification.Configuration, err error) { - return minioGetBucketNotificationMock(ctx, bucketName) +func (c s3ClientMock) setVersioning(ctx context.Context, state string, excludePrefix []string, excludeFolders bool) *probe.Error { + return c.setVersioningMock(ctx, state, excludePrefix, excludeFolders) } -// assigning mock at runtime instead of compile time -var minioListBucketsWithContextMock func(ctx context.Context) ([]minio.BucketInfo, error) - -var ( - minioMakeBucketWithContextMock func(ctx context.Context, bucketName, location string, objectLock bool) error - minioSetBucketPolicyWithContextMock func(ctx context.Context, bucketName, policy string) error - minioRemoveBucketMock func(bucketName string) error - minioGetBucketPolicyMock func(bucketName string) (string, error) - minioSetBucketEncryptionMock func(ctx context.Context, bucketName string, config *sse.Configuration) error - minioRemoveBucketEncryptionMock func(ctx context.Context, bucketName string) error - minioGetBucketEncryptionMock func(ctx context.Context, bucketName string) (*sse.Configuration, error) - minioSetObjectLockConfigMock func(ctx context.Context, bucketName string, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit) error - minioGetBucketObjectLockConfigMock func(ctx context.Context, bucketName string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) - minioGetObjectLockConfigMock func(ctx context.Context, bucketName string) (lock string, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) - minioSetVersioningMock func(ctx context.Context, state string, excludePrefix []string, excludeFolders bool) *probe.Error - minioCopyObjectMock func(ctx context.Context, dst minio.CopyDestOptions, src minio.CopySrcOptions) (minio.UploadInfo, error) - minioSetBucketTaggingMock func(ctx context.Context, bucketName string, tags *tags.Tags) error - minioRemoveBucketTaggingMock func(ctx context.Context, bucketName string) error -) - // Define a mock struct of minio Client interface implementation -type minioClientMock struct{} +type minioClientMock struct { + getBucketNotificationMock func(ctx context.Context, bucketName string) (bucketNotification notification.Configuration, err error) + listBucketsWithContextMock func(ctx context.Context) ([]minio.BucketInfo, error) + makeBucketWithContextMock func(ctx context.Context, bucketName, location string, objectLock bool) error + setBucketPolicyWithContextMock func(ctx context.Context, bucketName, policy string) error + removeBucketMock func(bucketName string) error + getBucketPolicyMock func(bucketName string) (string, error) + setBucketEncryptionMock func(ctx context.Context, bucketName string, config *sse.Configuration) error + removeBucketEncryptionMock func(ctx context.Context, bucketName string) error + getBucketEncryptionMock func(ctx context.Context, bucketName string) (*sse.Configuration, error) + setObjectLockConfigMock func(ctx context.Context, bucketName string, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit) error + getBucketObjectLockConfigMock func(ctx context.Context, bucketName string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) + getObjectLockConfigMock func(ctx context.Context, bucketName string) (lock string, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) + copyObjectMock func(ctx context.Context, dst minio.CopyDestOptions, src minio.CopySrcOptions) (minio.UploadInfo, error) + setBucketTaggingMock func(ctx context.Context, bucketName string, tags *tags.Tags) error + removeBucketTaggingMock func(ctx context.Context, bucketName string) error +} + +// mock function of getBucketNotification() +func (mc minioClientMock) getBucketNotification(ctx context.Context, bucketName string) (bucketNotification notification.Configuration, err error) { + return mc.getBucketNotificationMock(ctx, bucketName) +} // mock function of listBucketsWithContext() func (mc minioClientMock) listBucketsWithContext(ctx context.Context) ([]minio.BucketInfo, error) { - return minioListBucketsWithContextMock(ctx) + return mc.listBucketsWithContextMock(ctx) } // mock function of makeBucketsWithContext() func (mc minioClientMock) makeBucketWithContext(ctx context.Context, bucketName, location string, objectLock bool) error { - return minioMakeBucketWithContextMock(ctx, bucketName, location, objectLock) + return mc.makeBucketWithContextMock(ctx, bucketName, location, objectLock) } // mock function of setBucketPolicyWithContext() func (mc minioClientMock) setBucketPolicyWithContext(ctx context.Context, bucketName, policy string) error { - return minioSetBucketPolicyWithContextMock(ctx, bucketName, policy) + return mc.setBucketPolicyWithContextMock(ctx, bucketName, policy) } // mock function of removeBucket() func (mc minioClientMock) removeBucket(_ context.Context, bucketName string) error { - return minioRemoveBucketMock(bucketName) + return mc.removeBucketMock(bucketName) } // mock function of getBucketPolicy() func (mc minioClientMock) getBucketPolicy(_ context.Context, bucketName string) (string, error) { - return minioGetBucketPolicyMock(bucketName) + return mc.getBucketPolicyMock(bucketName) } func (mc minioClientMock) setBucketEncryption(ctx context.Context, bucketName string, config *sse.Configuration) error { - return minioSetBucketEncryptionMock(ctx, bucketName, config) + return mc.setBucketEncryptionMock(ctx, bucketName, config) } func (mc minioClientMock) removeBucketEncryption(ctx context.Context, bucketName string) error { - return minioRemoveBucketEncryptionMock(ctx, bucketName) + return mc.removeBucketEncryptionMock(ctx, bucketName) } func (mc minioClientMock) getBucketEncryption(ctx context.Context, bucketName string) (*sse.Configuration, error) { - return minioGetBucketEncryptionMock(ctx, bucketName) + return mc.getBucketEncryptionMock(ctx, bucketName) } func (mc minioClientMock) setObjectLockConfig(ctx context.Context, bucketName string, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit) error { - return minioSetObjectLockConfigMock(ctx, bucketName, mode, validity, unit) + return mc.setObjectLockConfigMock(ctx, bucketName, mode, validity, unit) } func (mc minioClientMock) getBucketObjectLockConfig(ctx context.Context, bucketName string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) { - return minioGetBucketObjectLockConfigMock(ctx, bucketName) + return mc.getBucketObjectLockConfigMock(ctx, bucketName) } func (mc minioClientMock) getObjectLockConfig(ctx context.Context, bucketName string) (lock string, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) { - return minioGetObjectLockConfigMock(ctx, bucketName) + return mc.getObjectLockConfigMock(ctx, bucketName) } func (mc minioClientMock) copyObject(ctx context.Context, dst minio.CopyDestOptions, src minio.CopySrcOptions) (minio.UploadInfo, error) { - return minioCopyObjectMock(ctx, dst, src) -} - -func (c s3ClientMock) setVersioning(ctx context.Context, state string, excludePrefix []string, excludeFolders bool) *probe.Error { - return minioSetVersioningMock(ctx, state, excludePrefix, excludeFolders) + return mc.copyObjectMock(ctx, dst, src) } func (mc minioClientMock) GetBucketTagging(ctx context.Context, bucketName string) (*tags.Tags, error) { @@ -150,11 +143,11 @@ func (mc minioClientMock) GetBucketTagging(ctx context.Context, bucketName strin } func (mc minioClientMock) SetBucketTagging(ctx context.Context, bucketName string, tags *tags.Tags) error { - return minioSetBucketTaggingMock(ctx, bucketName, tags) + return mc.setBucketTaggingMock(ctx, bucketName, tags) } func (mc minioClientMock) RemoveBucketTagging(ctx context.Context, bucketName string) error { - return minioRemoveBucketTaggingMock(ctx, bucketName) + return mc.removeBucketTaggingMock(ctx, bucketName) } func minioGetBucketTaggingMock(ctx context.Context, bucketName string) (*tags.Tags, error) { @@ -172,7 +165,7 @@ func TestMakeBucket(t *testing.T) { ctx := context.Background() // Test-1: makeBucket() create a bucket // mock function response from makeBucketWithContext(ctx) - minioMakeBucketWithContextMock = func(_ context.Context, _, _ string, _ bool) error { + minClient.makeBucketWithContextMock = func(_ context.Context, _, _ string, _ bool) error { return nil } if err := makeBucket(ctx, minClient, "bucktest1", true); err != nil { @@ -180,7 +173,7 @@ func TestMakeBucket(t *testing.T) { } // Test-2 makeBucket() make sure errors are handled correctly when errors on MakeBucketWithContext - minioMakeBucketWithContextMock = func(_ context.Context, _, _ string, _ bool) error { + minClient.makeBucketWithContextMock = func(_ context.Context, _, _ string, _ bool) error { return errors.New("error") } if err := makeBucket(ctx, minClient, "bucktest1", true); assert.Error(err) { @@ -199,7 +192,7 @@ func TestBucketInfo(t *testing.T) { // Test-1: getBucketInfo() get a bucket with PRIVATE access // if not policy set on bucket, access should be PRIVATE mockPolicy := "" - minioGetBucketPolicyMock = func(_ string) (string, error) { + minClient.getBucketPolicyMock = func(_ string) (string, error) { return mockPolicy, nil } bucketToSet := "csbucket" @@ -241,7 +234,7 @@ func TestBucketInfo(t *testing.T) { Policy: []byte(infoPolicy), } // mock function response from listBucketsWithContext(ctx) - minioAccountInfoMock = func(_ context.Context) (madmin.AccountInfo, error) { + adminClient.minioAccountInfoMock = func(_ context.Context) (madmin.AccountInfo, error) { return mockBucketList, nil } @@ -258,7 +251,7 @@ func TestBucketInfo(t *testing.T) { // Test-2: getBucketInfo() get a bucket with PUBLIC access // mock policy for bucket csbucket with readWrite access (should return PUBLIC) mockPolicy = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\",\"s3:ListBucketMultipartUploads\"],\"Resource\":[\"arn:aws:s3:::csbucket\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\",\"s3:AbortMultipartUpload\",\"s3:DeleteObject\"],\"Resource\":[\"arn:aws:s3:::csbucket/*\"]}]}" - minioGetBucketPolicyMock = func(_ string) (string, error) { + minClient.getBucketPolicyMock = func(_ string) (string, error) { return mockPolicy, nil } bucketToSet = "csbucket" @@ -282,7 +275,7 @@ func TestBucketInfo(t *testing.T) { // Test-3: getBucketInfo() get a bucket with PRIVATE access // if bucket has a null statement, the bucket is PRIVATE mockPolicy = "{\"Version\":\"2012-10-17\",\"Statement\":[]}" - minioGetBucketPolicyMock = func(_ string) (string, error) { + minClient.getBucketPolicyMock = func(_ string) (string, error) { return mockPolicy, nil } bucketToSet = "csbucket" @@ -305,7 +298,7 @@ func TestBucketInfo(t *testing.T) { // Test-4: getBucketInfo() returns an errors while parsing invalid policy mockPolicy = "policyinvalid" - minioGetBucketPolicyMock = func(_ string) (string, error) { + minClient.getBucketPolicyMock = func(_ string) (string, error) { return mockPolicy, nil } bucketToSet = "csbucket" @@ -333,7 +326,7 @@ func TestSetBucketAccess(t *testing.T) { function := "setBucketAccessPolicy()" // Test-1: setBucketAccessPolicy() set a bucket's access policy // mock function response from setBucketPolicyWithContext(ctx) - minioSetBucketPolicyWithContextMock = func(_ context.Context, _, _ string) error { + minClient.setBucketPolicyWithContextMock = func(_ context.Context, _, _ string) error { return nil } if err := setBucketAccessPolicy(ctx, minClient, "bucktest1", models.BucketAccessPUBLIC, ""); err != nil { @@ -361,7 +354,7 @@ func TestSetBucketAccess(t *testing.T) { } // Test-5: setBucketAccessPolicy() handle errors on SetPolicy call - minioSetBucketPolicyWithContextMock = func(_ context.Context, _, _ string) error { + minClient.setBucketPolicyWithContextMock = func(_ context.Context, _, _ string) error { return errors.New("error") } if err := setBucketAccessPolicy(ctx, minClient, "bucktest1", models.BucketAccessPUBLIC, ""); assert.Error(err) { @@ -371,10 +364,8 @@ func TestSetBucketAccess(t *testing.T) { func Test_enableBucketEncryption(t *testing.T) { ctx := context.Background() - minClient := minioClientMock{} type args struct { ctx context.Context - client MinioClient bucketName string encryptionType models.BucketEncryptionType kmsKeyID string @@ -389,7 +380,6 @@ func Test_enableBucketEncryption(t *testing.T) { name: "Bucket encryption enabled correctly", args: args{ ctx: ctx, - client: minClient, bucketName: "test", encryptionType: "sse-s3", mockEnableBucketEncryptionFunc: func(_ context.Context, _ string, _ *sse.Configuration) error { @@ -402,7 +392,6 @@ func Test_enableBucketEncryption(t *testing.T) { name: "Error when enabling bucket encryption", args: args{ ctx: ctx, - client: minClient, bucketName: "test", encryptionType: "sse-s3", mockEnableBucketEncryptionFunc: func(_ context.Context, _ string, _ *sse.Configuration) error { @@ -414,8 +403,9 @@ func Test_enableBucketEncryption(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(_ *testing.T) { - minioSetBucketEncryptionMock = tt.args.mockEnableBucketEncryptionFunc - if err := enableBucketEncryption(tt.args.ctx, tt.args.client, tt.args.bucketName, tt.args.encryptionType, tt.args.kmsKeyID); (err != nil) != tt.wantErr { + minClient := minioClientMock{} + minClient.setBucketEncryptionMock = tt.args.mockEnableBucketEncryptionFunc + if err := enableBucketEncryption(tt.args.ctx, minClient, tt.args.bucketName, tt.args.encryptionType, tt.args.kmsKeyID); (err != nil) != tt.wantErr { t.Errorf("enableBucketEncryption() errors = %v, wantErr %v", err, tt.wantErr) } }) @@ -424,10 +414,8 @@ func Test_enableBucketEncryption(t *testing.T) { func Test_disableBucketEncryption(t *testing.T) { ctx := context.Background() - minClient := minioClientMock{} type args struct { ctx context.Context - client MinioClient bucketName string mockBucketDisableFunc func(ctx context.Context, bucketName string) error } @@ -440,7 +428,6 @@ func Test_disableBucketEncryption(t *testing.T) { name: "Bucket encryption disabled correctly", args: args{ ctx: ctx, - client: minClient, bucketName: "test", mockBucketDisableFunc: func(_ context.Context, _ string) error { return nil @@ -452,7 +439,6 @@ func Test_disableBucketEncryption(t *testing.T) { name: "Error when disabling bucket encryption", args: args{ ctx: ctx, - client: minClient, bucketName: "test", mockBucketDisableFunc: func(_ context.Context, _ string) error { return ErrDefault @@ -463,8 +449,9 @@ func Test_disableBucketEncryption(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(_ *testing.T) { - minioRemoveBucketEncryptionMock = tt.args.mockBucketDisableFunc - if err := disableBucketEncryption(tt.args.ctx, tt.args.client, tt.args.bucketName); (err != nil) != tt.wantErr { + minClient := minioClientMock{} + minClient.removeBucketEncryptionMock = tt.args.mockBucketDisableFunc + if err := disableBucketEncryption(tt.args.ctx, minClient, tt.args.bucketName); (err != nil) != tt.wantErr { t.Errorf("disableBucketEncryption() errors = %v, wantErr %v", err, tt.wantErr) } }) @@ -473,10 +460,8 @@ func Test_disableBucketEncryption(t *testing.T) { func Test_getBucketEncryptionInfo(t *testing.T) { ctx := context.Background() - minClient := minioClientMock{} type args struct { ctx context.Context - client MinioClient bucketName string mockBucketEncryptionGet func(ctx context.Context, bucketName string) (*sse.Configuration, error) } @@ -490,7 +475,6 @@ func Test_getBucketEncryptionInfo(t *testing.T) { name: "Bucket encryption info returned correctly", args: args{ ctx: ctx, - client: minClient, bucketName: "test", mockBucketEncryptionGet: func(_ context.Context, _ string) (*sse.Configuration, error) { return &sse.Configuration{ @@ -512,7 +496,6 @@ func Test_getBucketEncryptionInfo(t *testing.T) { name: "Bucket encryption info with no rules", args: args{ ctx: ctx, - client: minClient, bucketName: "test", mockBucketEncryptionGet: func(_ context.Context, _ string) (*sse.Configuration, error) { return &sse.Configuration{ @@ -526,7 +509,6 @@ func Test_getBucketEncryptionInfo(t *testing.T) { name: "Error when obtaining bucket encryption info", args: args{ ctx: ctx, - client: minClient, bucketName: "test", mockBucketEncryptionGet: func(_ context.Context, _ string) (*sse.Configuration, error) { return nil, ErrSSENotConfigured @@ -537,8 +519,9 @@ func Test_getBucketEncryptionInfo(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(_ *testing.T) { - minioGetBucketEncryptionMock = tt.args.mockBucketEncryptionGet - got, err := getBucketEncryptionInfo(tt.args.ctx, tt.args.client, tt.args.bucketName) + minClient := minioClientMock{} + minClient.getBucketEncryptionMock = tt.args.mockBucketEncryptionGet + got, err := getBucketEncryptionInfo(tt.args.ctx, minClient, tt.args.bucketName) if (err != nil) != tt.wantErr { t.Errorf("getBucketEncryptionInfo() errors = %v, wantErr %v", err, tt.wantErr) return @@ -553,10 +536,8 @@ func Test_getBucketEncryptionInfo(t *testing.T) { func Test_SetBucketRetentionConfig(t *testing.T) { assert := assert.New(t) ctx := context.Background() - minClient := minioClientMock{} type args struct { ctx context.Context - client MinioClient bucketName string mode models.ObjectRetentionMode unit models.ObjectRetentionUnit @@ -572,7 +553,6 @@ func Test_SetBucketRetentionConfig(t *testing.T) { name: "Set Bucket Retention Config", args: args{ ctx: ctx, - client: minClient, bucketName: "test", mode: models.ObjectRetentionModeCompliance, unit: models.ObjectRetentionUnitDays, @@ -587,7 +567,6 @@ func Test_SetBucketRetentionConfig(t *testing.T) { name: "Set Bucket Retention Config 2", args: args{ ctx: ctx, - client: minClient, bucketName: "test", mode: models.ObjectRetentionModeGovernance, unit: models.ObjectRetentionUnitYears, @@ -602,7 +581,6 @@ func Test_SetBucketRetentionConfig(t *testing.T) { name: "Invalid validity", args: args{ ctx: ctx, - client: minClient, bucketName: "test", mode: models.ObjectRetentionModeCompliance, unit: models.ObjectRetentionUnitDays, @@ -617,7 +595,6 @@ func Test_SetBucketRetentionConfig(t *testing.T) { name: "Invalid retention mode", args: args{ ctx: ctx, - client: minClient, bucketName: "test", mode: models.ObjectRetentionMode("othermode"), unit: models.ObjectRetentionUnitDays, @@ -632,7 +609,6 @@ func Test_SetBucketRetentionConfig(t *testing.T) { name: "Invalid retention unit", args: args{ ctx: ctx, - client: minClient, bucketName: "test", mode: models.ObjectRetentionModeCompliance, unit: models.ObjectRetentionUnit("otherunit"), @@ -647,7 +623,6 @@ func Test_SetBucketRetentionConfig(t *testing.T) { name: "Handle errors on objec lock function", args: args{ ctx: ctx, - client: minClient, bucketName: "test", mode: models.ObjectRetentionModeCompliance, unit: models.ObjectRetentionUnitDays, @@ -661,8 +636,9 @@ func Test_SetBucketRetentionConfig(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(_ *testing.T) { - minioSetObjectLockConfigMock = tt.args.mockBucketRetentionFunc - err := setBucketRetentionConfig(tt.args.ctx, tt.args.client, tt.args.bucketName, tt.args.mode, tt.args.unit, tt.args.validity) + minClient := minioClientMock{} + minClient.setObjectLockConfigMock = tt.args.mockBucketRetentionFunc + err := setBucketRetentionConfig(tt.args.ctx, minClient, tt.args.bucketName, tt.args.mode, tt.args.unit, tt.args.validity) if tt.expectedError != nil { fmt.Println(t.Name()) assert.Equal(tt.expectedError.Error(), err.Error(), fmt.Sprintf("setObjectRetention() errors: `%s`, wantErr: `%s`", err, tt.expectedError)) @@ -676,10 +652,8 @@ func Test_SetBucketRetentionConfig(t *testing.T) { func Test_GetBucketRetentionConfig(t *testing.T) { assert := assert.New(t) ctx := context.Background() - minClient := minioClientMock{} type args struct { ctx context.Context - client MinioClient bucketName string getRetentionFunc func(ctx context.Context, bucketName string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) } @@ -693,7 +667,6 @@ func Test_GetBucketRetentionConfig(t *testing.T) { name: "Get Bucket Retention Config", args: args{ ctx: ctx, - client: minClient, bucketName: "test", getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) { m := minio.Governance @@ -712,7 +685,6 @@ func Test_GetBucketRetentionConfig(t *testing.T) { name: "Get Bucket Retention Config Compliance", args: args{ ctx: ctx, - client: minClient, bucketName: "test", getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) { m := minio.Compliance @@ -731,7 +703,6 @@ func Test_GetBucketRetentionConfig(t *testing.T) { name: "Handle Error on minio func", args: args{ ctx: ctx, - client: minClient, bucketName: "test", getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) { return nil, nil, nil, errors.New("error func") @@ -746,7 +717,6 @@ func Test_GetBucketRetentionConfig(t *testing.T) { name: "Handle NoLock Config errors", args: args{ ctx: ctx, - client: minClient, bucketName: "test", getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) { return nil, nil, nil, minio.ErrorResponse{ @@ -762,7 +732,6 @@ func Test_GetBucketRetentionConfig(t *testing.T) { name: "Return errors on invalid mode", args: args{ ctx: ctx, - client: minClient, bucketName: "test", getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) { m := minio.RetentionMode("other") @@ -777,7 +746,6 @@ func Test_GetBucketRetentionConfig(t *testing.T) { name: "Return errors on invalid unit", args: args{ ctx: ctx, - client: minClient, bucketName: "test", getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) { m := minio.Governance @@ -792,8 +760,9 @@ func Test_GetBucketRetentionConfig(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(_ *testing.T) { - minioGetBucketObjectLockConfigMock = tt.args.getRetentionFunc - resp, err := getBucketRetentionConfig(tt.args.ctx, tt.args.client, tt.args.bucketName) + minClient := minioClientMock{} + minClient.getBucketObjectLockConfigMock = tt.args.getRetentionFunc + resp, err := getBucketRetentionConfig(tt.args.ctx, minClient, tt.args.bucketName) if tt.expectedError != nil { fmt.Println(t.Name()) @@ -813,14 +782,12 @@ func Test_SetBucketVersioning(t *testing.T) { assert := assert.New(t) ctx := context.WithValue(context.Background(), utils.ContextClientIP, "127.0.0.1") errorMsg := "Error Message" - minClient := s3ClientMock{} type args struct { ctx context.Context state VersionState excludePrefix []string excludeFolders bool bucketName string - client s3ClientMock setVersioningFunc func(ctx context.Context, state string, excludePrefix []string, excludeFolders bool) *probe.Error } tests := []struct { @@ -834,7 +801,6 @@ func Test_SetBucketVersioning(t *testing.T) { ctx: ctx, state: VersionEnable, bucketName: "test", - client: minClient, setVersioningFunc: func(_ context.Context, _ string, _ []string, _ bool) *probe.Error { return nil }, @@ -848,7 +814,6 @@ func Test_SetBucketVersioning(t *testing.T) { state: VersionEnable, excludePrefix: []string{"prefix1", "prefix2"}, bucketName: "test", - client: minClient, setVersioningFunc: func(_ context.Context, _ string, _ []string, _ bool) *probe.Error { return nil }, @@ -863,7 +828,6 @@ func Test_SetBucketVersioning(t *testing.T) { excludePrefix: []string{"prefix1", "prefix2"}, excludeFolders: true, bucketName: "test", - client: minClient, setVersioningFunc: func(_ context.Context, _ string, _ []string, _ bool) *probe.Error { return nil }, @@ -876,7 +840,6 @@ func Test_SetBucketVersioning(t *testing.T) { ctx: ctx, state: VersionEnable, bucketName: "test", - client: minClient, setVersioningFunc: func(_ context.Context, _ string, _ []string, _ bool) *probe.Error { return probe.NewError(errors.New(errorMsg)) }, @@ -887,9 +850,10 @@ func Test_SetBucketVersioning(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(_ *testing.T) { - minioSetVersioningMock = tt.args.setVersioningFunc + s3Client := s3ClientMock{} + s3Client.setVersioningMock = tt.args.setVersioningFunc - err := doSetVersioning(tt.args.ctx, tt.args.client, tt.args.state, tt.args.excludePrefix, tt.args.excludeFolders) + err := doSetVersioning(tt.args.ctx, s3Client, tt.args.state, tt.args.excludePrefix, tt.args.excludeFolders) fmt.Println(t.Name()) fmt.Println("Expected:", tt.expectedError, "Error:", err) @@ -1202,11 +1166,11 @@ func Test_getAccountBuckets(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(_ *testing.T) { + client := AdminClientMock{} // mock function response from listBucketsWithContext(ctx) - minioAccountInfoMock = func(_ context.Context) (madmin.AccountInfo, error) { + client.minioAccountInfoMock = func(_ context.Context) (madmin.AccountInfo, error) { return tt.args.mockBucketList, tt.args.mockError } - client := AdminClientMock{} got, err := getAccountBuckets(tt.args.ctx, client) if !tt.wantErr(t, err, fmt.Sprintf("getAccountBuckets(%v, %v)", tt.args.ctx, client)) { diff --git a/api/user_login_test.go b/api/user_login_test.go index be8268e376..bfdc041b41 100644 --- a/api/user_login_test.go +++ b/api/user_login_test.go @@ -149,28 +149,25 @@ func Test_validateUserAgainstIDP(t *testing.T) { } func Test_getAccountInfo(t *testing.T) { - client := AdminClientMock{} type args struct { - ctx context.Context - client MinioAdmin + ctx context.Context } tests := []struct { name string args args want *iampolicy.Policy wantErr bool - mockFunc func() + mockFunc func(client *AdminClientMock) }{ { name: "error getting account info", args: args{ - ctx: context.Background(), - client: client, + ctx: context.Background(), }, want: nil, wantErr: true, - mockFunc: func() { - minioAccountInfoMock = func(_ context.Context) (madmin.AccountInfo, error) { + mockFunc: func(client *AdminClientMock) { + client.minioAccountInfoMock = func(_ context.Context) (madmin.AccountInfo, error) { return madmin.AccountInfo{}, errors.New("something went wrong") } }, @@ -178,10 +175,11 @@ func Test_getAccountInfo(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(_ *testing.T) { + client := AdminClientMock{} if tt.mockFunc != nil { - tt.mockFunc() + tt.mockFunc(&client) } - got, err := getAccountInfo(tt.args.ctx, tt.args.client) + got, err := getAccountInfo(tt.args.ctx, client) if (err != nil) != tt.wantErr { t.Errorf("getAccountInfo() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/api/ws_handle.go b/api/ws_handle.go index a6dedc9ebc..572e9d669c 100644 --- a/api/ws_handle.go +++ b/api/ws_handle.go @@ -42,29 +42,6 @@ const ( wsBasePath = "/ws" ) -// ConsoleWebsocketAdmin interface of a Websocket Client -type ConsoleWebsocketAdmin interface { - trace() - console() -} - -type wsAdminClient struct { - // websocket connection. - conn wsConn - // MinIO admin Client - client MinioAdmin -} - -// ConsoleWebsocket interface of a Websocket Client -type ConsoleWebsocket interface { - watch(options watchOptions) -} - -// ConsoleWebSocketMClient interface of a Websocket Client -type ConsoleWebsocketMClient interface { - objectManager(options objectsListOpts) -} - type wsMinioClient struct { // websocket connection. conn wsConn @@ -89,26 +66,6 @@ type wsConn struct { conn *websocket.Conn } -// Types for trace request. this adds support for calls, threshold, status and extra filters -type TraceRequest struct { - s3 bool - internal bool - storage bool - os bool - threshold int64 - onlyErrors bool - statusCode int64 - method string - funcName string - path string -} - -// Type for log requests. This allows for filtering by node and kind -type LogRequest struct { - node string - logType string -} - func (c wsConn) writeMessage(messageType int, data []byte) error { return c.conn.WriteMessage(messageType, data) } @@ -176,22 +133,6 @@ func serveWS(w http.ResponseWriter, req *http.Request) { } switch { - case strings.HasPrefix(wsPath, `/console`): - - wsAdminClient, err := newWebSocketAdminClient(conn, session, clientIP) - if err != nil { - ErrorWithContext(ctx, err) - closeWsConn(conn) - return - } - node := req.URL.Query().Get("node") - logType := req.URL.Query().Get("logType") - - logRequestItem := LogRequest{ - node: node, - logType: logType, - } - go wsAdminClient.console(ctx, logRequestItem) case strings.HasPrefix(wsPath, `/objectManager`): wsMinioClient, err := newWebSocketMinioClient(conn, session, clientIP) if err != nil { @@ -207,28 +148,6 @@ func serveWS(w http.ResponseWriter, req *http.Request) { } } -// newWebSocketAdminClient returns a wsAdminClient authenticated as an admin user -func newWebSocketAdminClient(conn *websocket.Conn, autClaims *models.Principal, clientIP string) (*wsAdminClient, error) { - // create a websocket connection interface implementation - // defining the connection to be used - wsConnection := wsConn{conn: conn} - - // Only start Websocket Interaction after user has been - // authenticated with MinIO - mAdmin, err := newAdminFromClaims(autClaims, clientIP) - if err != nil { - LogError("error creating madmin client: %v", err) - return nil, err - } - - // create a minioClient interface implementation - // defining the client to be used - adminClient := AdminClient{Client: mAdmin} - // create websocket client and handle request - wsAdminClient := &wsAdminClient{conn: wsConnection, client: adminClient} - return wsAdminClient, nil -} - func newWebSocketMinioClient(conn *websocket.Conn, claims *models.Principal, clientIP string) (*wsMinioClient, error) { mClient, err := newMinioClient(claims, clientIP) if err != nil { @@ -312,42 +231,3 @@ func closeWsConn(conn *websocket.Conn) { conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) conn.Close() } - -// console serves madmin.GetLogs -// on a Websocket connection. -func (wsc *wsAdminClient) console(ctx context.Context, logRequestItem LogRequest) { - defer func() { - LogInfo("console logs stopped") - // close connection after return - wsc.conn.close() - }() - LogInfo("console logs started") - - ctx = wsReadClientCtx(ctx, wsc.conn) - - err := startConsoleLog(ctx, wsc.conn, wsc.client, logRequestItem) - - sendWsCloseMessage(wsc.conn, err) -} - -// sendWsCloseMessage sends Websocket Connection Close Message indicating the Status Code -// see https://tools.ietf.org/html/rfc6455#page-45 -func sendWsCloseMessage(conn WSConn, err error) { - if err != nil { - LogError("original ws error: %v", err) - // If connection exceeded read deadline send Close - // Message Policy Violation code since we don't want - // to let the receiver figure out the read deadline. - // This is a generic code designed if there is a - // need to hide specific details about the policy. - if nErr, ok := err.(net.Error); ok && nErr.Timeout() { - conn.writeMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.ClosePolicyViolation, "")) - return - } - // else, internal server error - conn.writeMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseInternalServerErr, err.Error())) - return - } - // normal closure - conn.writeMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) -} diff --git a/go.mod b/go.mod index d4e5343da9..b022f2b0d0 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,12 @@ module github.com/minio/console -go 1.23 +go 1.23.0 -toolchain go1.23.6 +toolchain go1.23.7 require ( github.com/blang/semver/v4 v4.0.0 - github.com/cheggaaa/pb/v3 v3.1.6 + github.com/cheggaaa/pb/v3 v3.1.7 github.com/dustin/go-humanize v1.0.1 // indirect github.com/fatih/color v1.18.0 github.com/go-openapi/errors v0.22.0 @@ -14,18 +14,18 @@ require ( github.com/go-openapi/runtime v0.28.0 github.com/go-openapi/spec v0.21.0 github.com/go-openapi/strfmt v0.23.0 - github.com/go-openapi/swag v0.23.0 + github.com/go-openapi/swag v0.23.1 github.com/go-openapi/validate v0.24.0 github.com/golang-jwt/jwt/v4 v4.5.1 github.com/google/uuid v1.6.0 github.com/jessevdk/go-flags v1.6.1 - github.com/klauspost/compress v1.17.11 + github.com/klauspost/compress v1.18.0 github.com/minio/cli v1.24.2 github.com/minio/highwayhash v1.0.3 github.com/minio/kes v0.24.0 - github.com/minio/madmin-go/v3 v3.0.91 - github.com/minio/mc v0.0.0-20250208210632-10c50368c526 - github.com/minio/minio-go/v7 v7.0.85 + github.com/minio/madmin-go/v3 v3.0.98 + github.com/minio/mc v0.0.0-20250313080218-cf909e1063a9 + github.com/minio/minio-go/v7 v7.0.88 github.com/minio/selfupdate v0.6.0 github.com/minio/websocket v1.6.0 github.com/mitchellh/go-homedir v1.1.0 @@ -34,16 +34,16 @@ require ( github.com/stretchr/testify v1.10.0 github.com/tidwall/gjson v1.18.0 // indirect github.com/unrolled/secure v1.17.0 - golang.org/x/crypto v0.33.0 - golang.org/x/net v0.35.0 - golang.org/x/oauth2 v0.26.0 + golang.org/x/crypto v0.36.0 + golang.org/x/net v0.37.0 + golang.org/x/oauth2 v0.28.0 // Added to include security fix for // https://github.com/golang/go/issues/56152 - golang.org/x/text v0.22.0 // indirect + golang.org/x/text v0.23.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) -require github.com/minio/pkg/v3 v3.0.29 +require github.com/minio/pkg/v3 v3.1.2 require ( aead.dev/mem v0.2.0 // indirect @@ -55,7 +55,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/charmbracelet/bubbles v0.20.0 // indirect - github.com/charmbracelet/bubbletea v1.3.0 // indirect + github.com/charmbracelet/bubbletea v1.3.4 // indirect github.com/charmbracelet/lipgloss v1.0.0 // indirect github.com/charmbracelet/x/ansi v0.8.0 // indirect github.com/charmbracelet/x/term v0.2.1 // indirect @@ -63,14 +63,14 @@ require ( github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/fatih/structs v1.1.0 // indirect github.com/go-ini/ini v1.67.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-openapi/analysis v0.23.0 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonpointer v0.21.1 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/goccy/go-json v0.10.5 // indirect github.com/gogo/protobuf v1.3.2 // indirect @@ -79,18 +79,18 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jedib0t/go-pretty/v6 v6.6.5 // indirect + github.com/jedib0t/go-pretty/v6 v6.6.7 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/juju/ratelimit v1.0.2 // indirect - github.com/klauspost/cpuid/v2 v2.2.9 // indirect + github.com/klauspost/cpuid/v2 v2.2.10 // indirect github.com/lestrrat-go/blackmagic v1.0.2 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect github.com/lestrrat-go/httprc v1.0.6 // indirect github.com/lestrrat-go/iter v1.0.2 // indirect - github.com/lestrrat-go/jwx/v2 v2.1.3 // indirect + github.com/lestrrat-go/jwx/v2 v2.1.4 // indirect github.com/lestrrat-go/option v1.0.1 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect - github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 // indirect + github.com/lufia/plan9stats v0.0.0-20250303091104-876f3ea5145d // indirect github.com/mailru/easyjson v0.9.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-ieproxy v0.0.12 // indirect @@ -99,15 +99,15 @@ require ( github.com/mattn/go-runewidth v0.0.16 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/minio/colorjson v1.0.8 // indirect + github.com/minio/crc64nvme v1.0.1 // indirect github.com/minio/filepath v1.0.0 // indirect github.com/minio/kms-go/kes v0.3.1 // indirect github.com/minio/md5-simd v1.1.2 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/montanaflynn/stats v0.7.1 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/reflow v0.3.0 // indirect - github.com/muesli/termenv v0.15.2 // indirect + github.com/muesli/termenv v0.16.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect @@ -116,12 +116,12 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/posener/complete v1.2.3 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect - github.com/prometheus/client_golang v1.20.5 // indirect + github.com/prometheus/client_golang v1.21.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/prometheus/prom2json v1.4.1 // indirect - github.com/prometheus/prometheus v0.301.0 // indirect + github.com/prometheus/prometheus v0.302.1 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rjeczalik/notify v0.9.3 // indirect github.com/safchain/ethtool v0.5.10 // indirect @@ -131,22 +131,22 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/tinylib/msgp v1.2.5 // indirect - github.com/tklauser/go-sysconf v0.3.14 // indirect - github.com/tklauser/numcpus v0.9.0 // indirect - github.com/vbauerster/mpb/v8 v8.9.2 // indirect + github.com/tklauser/go-sysconf v0.3.15 // indirect + github.com/tklauser/numcpus v0.10.0 // indirect + github.com/vbauerster/mpb/v8 v8.9.3 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - go.etcd.io/etcd/api/v3 v3.5.18 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.18 // indirect - go.etcd.io/etcd/client/v3 v3.5.18 // indirect - go.mongodb.org/mongo-driver v1.17.2 // indirect + go.etcd.io/etcd/api/v3 v3.5.19 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.19 // indirect + go.etcd.io/etcd/client/v3 v3.5.19 // indirect + go.mongodb.org/mongo-driver v1.17.3 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/term v0.29.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250207221924-e9438ea467c6 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 // indirect - google.golang.org/grpc v1.70.0 // indirect + golang.org/x/sync v0.12.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/term v0.30.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250311190419-81fb87f6b8bf // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250311190419-81fb87f6b8bf // indirect + google.golang.org/grpc v1.71.0 // indirect google.golang.org/protobuf v1.36.5 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 49171456ae..b365841125 100644 --- a/go.sum +++ b/go.sum @@ -22,8 +22,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE= github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU= -github.com/charmbracelet/bubbletea v1.3.0 h1:fPMyirm0u3Fou+flch7hlJN9krlnVURrkUVDwqXjoAc= -github.com/charmbracelet/bubbletea v1.3.0/go.mod h1:eTaHfqbIwvBhFQM/nlT1NsGc4kp8jhF8LfUK67XiTDM= +github.com/charmbracelet/bubbletea v1.3.4 h1:kCg7B+jSCFPLYRA52SDZjr51kG/fMUEoPoZrkaDHyoI= +github.com/charmbracelet/bubbletea v1.3.4/go.mod h1:dtcUCyCGEX3g9tosuYiut3MXgY/Jsv9nKVdibKKRRXo= github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg= github.com/charmbracelet/lipgloss v1.0.0/go.mod h1:U5fy9Z+C38obMs+T+tJqst9VGzlOYGj4ri9reL3qUlo= github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE= @@ -34,8 +34,8 @@ github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQ github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= github.com/cheggaaa/pb v1.0.29 h1:FckUN5ngEk2LpvuG0fw1GEFx6LtyY2pWI/Z2QgCnEYo= github.com/cheggaaa/pb v1.0.29/go.mod h1:W40334L7FMC5JKWldsTWbdGjLo0RxUKK73K+TuPxX30= -github.com/cheggaaa/pb/v3 v3.1.6 h1:h0x+vd7EiUohAJ29DJtJy+SNAc55t/elW3jCD086EXk= -github.com/cheggaaa/pb/v3 v3.1.6/go.mod h1:urxmfVtaxT+9aWk92DbsvXFZtNSWQSO5TRAp+MJ3l1s= +github.com/cheggaaa/pb/v3 v3.1.7 h1:2FsIW307kt7A/rz/ZI2lvPO+v3wKazzE4K/0LtTWsOI= +github.com/cheggaaa/pb/v3 v3.1.7/go.mod h1:/Ji89zfVPeC/u5j8ukD0MBPHt2bzTYp74lQ7KlgFWTQ= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= @@ -43,8 +43,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= @@ -69,8 +69,8 @@ github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC0 github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo= github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w= github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic= +github.com/go-openapi/jsonpointer v0.21.1/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk= github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= github.com/go-openapi/loads v0.22.0 h1:ECPGd4jX1U6NApCGG1We+uEozOAvXvJSF4nnwHZ8Aco= @@ -81,8 +81,8 @@ github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9Z github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c= github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= +github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58= github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ= github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= @@ -95,8 +95,8 @@ github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -109,8 +109,8 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jedib0t/go-pretty/v6 v6.6.5 h1:9PgMJOVBedpgYLI56jQRJYqngxYAAzfEUua+3NgSqAo= -github.com/jedib0t/go-pretty/v6 v6.6.5/go.mod h1:Uq/HrbhuFty5WSVNfjpQQe47x16RwVGXIveNGEyGtHs= +github.com/jedib0t/go-pretty/v6 v6.6.7 h1:m+LbHpm0aIAPLzLbMfn8dc3Ht8MW7lsSO4MPItz/Uuo= +github.com/jedib0t/go-pretty/v6 v6.6.7/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= github.com/jessevdk/go-flags v1.6.1 h1:Cvu5U8UGrLay1rZfv/zP7iLpSHGUZ/Ou68T0iX1bBK4= github.com/jessevdk/go-flags v1.6.1/go.mod h1:Mk8T1hIAWpOiJiHa9rJASDK2UGWji0EuPGBnNLMooyc= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -119,11 +119,11 @@ github.com/juju/ratelimit v1.0.2 h1:sRxmtRiajbvrcLQT7S+JbqU0ntsb9W2yhSdNN8tWfaI= github.com/juju/ratelimit v1.0.2/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= -github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= -github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= +github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= +github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -138,14 +138,14 @@ github.com/lestrrat-go/httprc v1.0.6 h1:qgmgIRhpvBqexMJjA/PmwSvhNk679oqD1RbovdCG github.com/lestrrat-go/httprc v1.0.6/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo= github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx/v2 v2.1.3 h1:Ud4lb2QuxRClYAmRleF50KrbKIoM1TddXgBrneT5/Jo= -github.com/lestrrat-go/jwx/v2 v2.1.3/go.mod h1:q6uFgbgZfEmQrfJfrCo90QcQOcXFMfbI/fO0NqRtvZo= +github.com/lestrrat-go/jwx/v2 v2.1.4 h1:uBCMmJX8oRZStmKuMMOFb0Yh9xmEMgNJLgjuKKt4/qc= +github.com/lestrrat-go/jwx/v2 v2.1.4/go.mod h1:nWRbDFR1ALG2Z6GJbBXzfQaYyvn751KuuyySN2yR6is= github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 h1:7UMa6KCCMjZEMDtTVdcGu0B1GmmC7QJKiCCjyTAWQy0= -github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= +github.com/lufia/plan9stats v0.0.0-20250303091104-876f3ea5145d h1:fjMbDVUGsMQiVZnSQsmouYJvMdwsGiDipOZoN66v844= +github.com/lufia/plan9stats v0.0.0-20250303091104-876f3ea5145d/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -170,6 +170,8 @@ github.com/minio/cli v1.24.2 h1:J+fCUh9mhPLjN3Lj/YhklXvxj8mnyE/D6FpFduXJ2jg= github.com/minio/cli v1.24.2/go.mod h1:bYxnK0uS629N3Bq+AOZZ+6lwF77Sodk4+UL9vNuXhOY= github.com/minio/colorjson v1.0.8 h1:AS6gEQ1dTRYHmC4xuoodPDRILHP/9Wz5wYUGDQfPLpg= github.com/minio/colorjson v1.0.8/go.mod h1:wrs39G/4kqNlGjwqHvPlAnXuc2tlPszo6JKdSBCLN8w= +github.com/minio/crc64nvme v1.0.1 h1:DHQPrYPdqK7jQG/Ls5CTBZWeex/2FMS3G5XGkycuFrY= +github.com/minio/crc64nvme v1.0.1/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg= github.com/minio/filepath v1.0.0 h1:fvkJu1+6X+ECRA6G3+JJETj4QeAYO9sV43I79H8ubDY= github.com/minio/filepath v1.0.0/go.mod h1:/nRZA2ldl5z6jT9/KQuvZcQlxZIMQoFFQPvEXx9T/Bw= github.com/minio/highwayhash v1.0.3 h1:kbnuUMoHYyVl7szWjSxJnxw11k2U709jqFPPmIUyD6Q= @@ -178,18 +180,18 @@ github.com/minio/kes v0.24.0 h1:iRAmVjgZ4vQV+V7wc88kADahGl1tA/USlfQzAAr+qh8= github.com/minio/kes v0.24.0/go.mod h1:rpgBd+s918q6zCclNLkYs//SDccXLCDv/xeM2/POzKk= github.com/minio/kms-go/kes v0.3.1 h1:K3sPFAvFbJx33XlCTUBnQo8JRmSZyDvT6T2/MQ2iC3A= github.com/minio/kms-go/kes v0.3.1/go.mod h1:Q9Ct0KUAuN9dH0hSVa0eva45Jg99cahbZpPxeqR9rOQ= -github.com/minio/madmin-go/v3 v3.0.91 h1:ixa64WnPNeysO77Bk0OoYP8dl1jz4FVOfJ56+3CjoOc= -github.com/minio/madmin-go/v3 v3.0.91/go.mod h1:pMLdj9OtN0CANNs5tdm6opvOlDFfj0WhbztboZAjRWE= -github.com/minio/mc v0.0.0-20250208210632-10c50368c526 h1:FzxZFUgTf21n+spBVhGAed8HCSUpAN+zfOChg49zZ64= -github.com/minio/mc v0.0.0-20250208210632-10c50368c526/go.mod h1:AgzD1Axs0TauPrFSd7M3yC75TRg9zT919d9bbxhubJ4= +github.com/minio/madmin-go/v3 v3.0.98 h1:K9gyo6Men83FgMX9ZOd/x5+cghRK9rBhf8v7s+mN2nA= +github.com/minio/madmin-go/v3 v3.0.98/go.mod h1:pMLdj9OtN0CANNs5tdm6opvOlDFfj0WhbztboZAjRWE= +github.com/minio/mc v0.0.0-20250313080218-cf909e1063a9 h1:6RyInOHKL6jz8zxcAar/h6rg/aJCxDP/uFuSNvYSuMI= +github.com/minio/mc v0.0.0-20250313080218-cf909e1063a9/go.mod h1:h5UQZ+5Qfq6XV81E4iZSgStPZ6Hy+gMuHMkLkjq4Gys= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= -github.com/minio/minio-go/v7 v7.0.85 h1:9psTLS/NTvC3MWoyjhjXpwcKoNbkongaCSF3PNpSuXo= -github.com/minio/minio-go/v7 v7.0.85/go.mod h1:57YXpvc5l3rjPdhqNrDsvVlY0qPI6UTk1bflAe+9doY= +github.com/minio/minio-go/v7 v7.0.88 h1:v8MoIJjwYxOkehp+eiLIuvXk87P2raUtoU5klrAAshs= +github.com/minio/minio-go/v7 v7.0.88/go.mod h1:33+O8h0tO7pCeCWwBVa07RhVVfB/3vS4kEX7rwYKmIg= github.com/minio/mux v1.9.0 h1:dWafQFyEfGhJvK6AwLOt83bIG5bxKxKJnKMCi0XAaoA= github.com/minio/mux v1.9.0/go.mod h1:1pAare17ZRL5GpmNL+9YmqHoWnLmMZF9C/ioUCfy0BQ= -github.com/minio/pkg/v3 v3.0.29 h1:Gcj4MndnSzPFtI8yQ5utE2/zDgtNynCHTM0EN54/2RE= -github.com/minio/pkg/v3 v3.0.29/go.mod h1:mIaN552nu0D2jiSk5BQC8LB25f44ytbOBJCuLtksX7Q= +github.com/minio/pkg/v3 v3.1.2 h1:DCIzGiUM2uJelWKP1wzwyP8KqdNXHrxMkG52S337oN8= +github.com/minio/pkg/v3 v3.1.2/go.mod h1:XIUU35+I9lWuTuMf94pwnQjvli6nZfRND6TjZGgqSEE= github.com/minio/selfupdate v0.6.0 h1:i76PgT0K5xO9+hjzKcacQtO7+MjJ4JKA8Ak8XQ9DDwU= github.com/minio/selfupdate v0.6.0/go.mod h1:bO02GTIPCMQFTEvE5h4DjYB58bCoZ35XLeBf0buTDdM= github.com/minio/websocket v1.6.0 h1:CPvnQvNvlVaQmvw5gtJNyYQhg4+xRmrPNhBbv8BdpAE= @@ -198,16 +200,14 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= -github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= -github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= -github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= +github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= +github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= @@ -225,8 +225,8 @@ github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXq github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= -github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk= +github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= @@ -235,8 +235,8 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/prometheus/prom2json v1.4.1 h1:7McxdrHgPEOtMwWjkKtd0v5AhpR2Q6QAnlHKVxq0+tQ= github.com/prometheus/prom2json v1.4.1/go.mod h1:CzOQykSKFxXuC7ELUZHOHQvwKesQ3eN0p2PWLhFitQM= -github.com/prometheus/prometheus v0.301.0 h1:0z8dgegmILivNomCd79RKvVkIols8vBGPKmcIBc7OyY= -github.com/prometheus/prometheus v0.301.0/go.mod h1:BJLjWCKNfRfjp7Q48DrAjARnCi7GhfUVvUFEAWTssZM= +github.com/prometheus/prometheus v0.302.1 h1:xqVdrwrB4WNpdgJqxsz5loqFWNUZitsK8myqLuSZ6Ag= +github.com/prometheus/prometheus v0.302.1/go.mod h1:YcyCoTbUR/TM8rY3Aoeqr0AWTu/pu1Ehh+trpX3eRzg= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= @@ -274,38 +274,38 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tinylib/msgp v1.2.5 h1:WeQg1whrXRFiZusidTQqzETkRpGjFjcIhW6uqWH09po= github.com/tinylib/msgp v1.2.5/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0= -github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU= -github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= -github.com/tklauser/numcpus v0.9.0 h1:lmyCHtANi8aRUgkckBgoDk1nHCux3n2cgkJLXdQGPDo= -github.com/tklauser/numcpus v0.9.0/go.mod h1:SN6Nq1O3VychhC1npsWostA+oW+VOQTxZrS604NSRyI= +github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= +github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= +github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= +github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ= github.com/unrolled/secure v1.17.0 h1:Io7ifFgo99Bnh0J7+Q+qcMzWM6kaDPCA5FroFZEdbWU= github.com/unrolled/secure v1.17.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= -github.com/vbauerster/mpb/v8 v8.9.2 h1:kb91+D643Qg040bbICYtzpjgZ9ypVO/+sjv4Jcm6si4= -github.com/vbauerster/mpb/v8 v8.9.2/go.mod h1:hxS8Hz4C6ijnppDSIX6LjG8FYJSoPo9iIOcE53Zik0c= +github.com/vbauerster/mpb/v8 v8.9.3 h1:PnMeF+sMvYv9u23l6DO6Q3+Mdj408mjLRXIzmUmU2Z8= +github.com/vbauerster/mpb/v8 v8.9.3/go.mod h1:hxS8Hz4C6ijnppDSIX6LjG8FYJSoPo9iIOcE53Zik0c= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -go.etcd.io/etcd/api/v3 v3.5.18 h1:Q4oDAKnmwqTo5lafvB+afbgCDF7E35E4EYV2g+FNGhs= -go.etcd.io/etcd/api/v3 v3.5.18/go.mod h1:uY03Ob2H50077J7Qq0DeehjM/A9S8PhVfbQ1mSaMopU= -go.etcd.io/etcd/client/pkg/v3 v3.5.18 h1:mZPOYw4h8rTk7TeJ5+3udUkfVGBqc+GCjOJYd68QgNM= -go.etcd.io/etcd/client/pkg/v3 v3.5.18/go.mod h1:BxVf2o5wXG9ZJV+/Cu7QNUiJYk4A29sAhoI5tIRsCu4= -go.etcd.io/etcd/client/v3 v3.5.18 h1:nvvYmNHGumkDjZhTHgVU36A9pykGa2K4lAJ0yY7hcXA= -go.etcd.io/etcd/client/v3 v3.5.18/go.mod h1:kmemwOsPU9broExyhYsBxX4spCTDX3yLgPMWtpBXG6E= -go.mongodb.org/mongo-driver v1.17.2 h1:gvZyk8352qSfzyZ2UMWcpDpMSGEr1eqE4T793SqyhzM= -go.mongodb.org/mongo-driver v1.17.2/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= +go.etcd.io/etcd/api/v3 v3.5.19 h1:w3L6sQZGsWPuBxRQ4m6pPP3bVUtV8rjW033EGwlr0jw= +go.etcd.io/etcd/api/v3 v3.5.19/go.mod h1:QqKGViq4KTgOG43dr/uH0vmGWIaoJY3ggFi6ZH0TH/U= +go.etcd.io/etcd/client/pkg/v3 v3.5.19 h1:9VsyGhg0WQGjDWWlDI4VuaS9PZJGNbPkaHEIuLwtixk= +go.etcd.io/etcd/client/pkg/v3 v3.5.19/go.mod h1:qaOi1k4ZA9lVLejXNvyPABrVEe7VymMF2433yyRQ7O0= +go.etcd.io/etcd/client/v3 v3.5.19 h1:+4byIz6ti3QC28W0zB0cEZWwhpVHXdrKovyycJh1KNo= +go.etcd.io/etcd/client/v3 v3.5.19/go.mod h1:FNzyinmMIl0oVsty1zA3hFeUrxXI/JpEnz4sG+POzjU= +go.mongodb.org/mongo-driver v1.17.3 h1:TQyXhnsWfWtgAhMtOgtYHMTkZIfBTpMTsMnd9ZBeHxQ= +go.mongodb.org/mongo-driver v1.17.3/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw= -go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= -go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ= -go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M= -go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM= -go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM= -go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU= -go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= -go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= -go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= +go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= +go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= +go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= +go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -318,8 +318,8 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= -golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -327,16 +327,16 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE= -golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= +golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc= +golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -356,17 +356,17 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= -golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= +golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= +golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -375,12 +375,12 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20250207221924-e9438ea467c6 h1:L9JNMl/plZH9wmzQUHleO/ZZDSN+9Gh41wPczNy+5Fk= -google.golang.org/genproto/googleapis/api v0.0.0-20250207221924-e9438ea467c6/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 h1:2duwAxN2+k0xLNpjnHTXoMUgnv6VPSp5fiqTuwSxjmI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= -google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= -google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= +google.golang.org/genproto/googleapis/api v0.0.0-20250311190419-81fb87f6b8bf h1:BdIVRm+fyDUn8lrZLPSlBCfM/YKDwUBYgDoLv9+DYo0= +google.golang.org/genproto/googleapis/api v0.0.0-20250311190419-81fb87f6b8bf/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250311190419-81fb87f6b8bf h1:dHDlF3CWxQkefK9IJx+O8ldY0gLygvrlYRBNbPqDWuY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250311190419-81fb87f6b8bf/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= +google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= +google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/web-app/package.json b/web-app/package.json index 7617b8257e..8de7a22757 100644 --- a/web-app/package.json +++ b/web-app/package.json @@ -59,6 +59,7 @@ "proxy": "http://localhost:9090/", "devDependencies": { "@babel/plugin-proposal-private-property-in-object": "^7.21.11", + "@babel/runtime": "^7.26.10", "@playwright/test": "^1.50.1", "@types/jest": "^29.5.14", "@types/lodash": "^4.17.15", @@ -95,7 +96,8 @@ "ws": "^8.17.1", "rollup": "^4.24.0", "cookie": "^0.7.2", - "jspdf": "^3.0.0" + "jspdf": "^3.0.0", + "@babel/runtime": "^7.26.10" }, "main": "index.js", "packageManager": "yarn@4.4.0" diff --git a/web-app/yarn.lock b/web-app/yarn.lock index e873e80095..d6c531c281 100644 --- a/web-app/yarn.lock +++ b/web-app/yarn.lock @@ -1652,12 +1652,12 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": - version: 7.26.0 - resolution: "@babel/runtime@npm:7.26.0" +"@babel/runtime@npm:^7.26.10": + version: 7.26.10 + resolution: "@babel/runtime@npm:7.26.10" dependencies: regenerator-runtime: "npm:^0.14.0" - checksum: 10c0/12c01357e0345f89f4f7e8c0e81921f2a3e3e101f06e8eaa18a382b517376520cd2fa8c237726eb094dab25532855df28a7baaf1c26342b52782f6936b07c287 + checksum: 10c0/6dc6d88c7908f505c4f7770fb4677dfa61f68f659b943c2be1f2a99cb6680343462867abf2d49822adc435932919b36c77ac60125793e719ea8745f2073d3745 languageName: node linkType: hard @@ -17914,6 +17914,7 @@ __metadata: resolution: "web-app@workspace:." dependencies: "@babel/plugin-proposal-private-property-in-object": "npm:^7.21.11" + "@babel/runtime": "npm:^7.26.10" "@playwright/test": "npm:^1.50.1" "@reduxjs/toolkit": "npm:^1.9.7" "@types/jest": "npm:^29.5.14"