Clean-up after PR 3509 (#3517)

This commit is contained in:
Ramon de Klein
2025-03-21 20:43:10 +01:00
committed by GitHub
parent 63c6d8952b
commit 71b1b708b7
15 changed files with 214 additions and 1787 deletions

View File

@@ -18,332 +18,18 @@ package api
import ( import (
"context" "context"
"io"
"time"
"github.com/minio/madmin-go/v3" "github.com/minio/madmin-go/v3"
iampolicy "github.com/minio/pkg/v3/policy"
) )
type AdminClientMock struct{} 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) 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
} }
func (ac AdminClientMock) kmsStatus(_ context.Context) (madmin.KMSStatus, 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 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) { func (ac AdminClientMock) AccountInfo(ctx context.Context) (madmin.AccountInfo, error) {
return minioAccountInfoMock(ctx) return ac.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)
} }

View File

@@ -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 <http://www.gnu.org/licenses/>.
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)
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
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())
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
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)
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
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)
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
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
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
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())
}
}

View File

@@ -17,16 +17,12 @@
package api package api
import ( import (
"bytes"
"context" "context"
"encoding/json"
"io"
"net" "net"
"net/http" "net/http"
"net/url" "net/url"
"regexp" "regexp"
"strings" "strings"
"time"
"github.com/minio/console/pkg" "github.com/minio/console/pkg"
@@ -35,7 +31,6 @@ import (
"github.com/minio/console/models" "github.com/minio/console/models"
"github.com/minio/madmin-go/v3" "github.com/minio/madmin-go/v3"
"github.com/minio/minio-go/v7/pkg/credentials" "github.com/minio/minio-go/v7/pkg/credentials"
iampolicy "github.com/minio/pkg/v3/policy"
) )
const globalAppName = "MinIO Console" const globalAppName = "MinIO Console"
@@ -44,87 +39,9 @@ const globalAppName = "MinIO Console"
// by mock when testing, it should include all MinioAdmin respective api calls // by mock when testing, it should include all MinioAdmin respective api calls
// that are used within this project. // that are used within this project.
type MinioAdmin interface { 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) 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 // KMS
kmsStatus(ctx context.Context) (madmin.KMSStatus, error) 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 // Interface implementation
@@ -135,292 +52,17 @@ type AdminClient struct {
Client *madmin.AdminClient 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() // AccountInfo implements madmin.AccountInfo()
func (ac AdminClient) AccountInfo(ctx context.Context) (madmin.AccountInfo, error) { func (ac AdminClient) AccountInfo(ctx context.Context) (madmin.AccountInfo, error) {
return ac.Client.AccountInfo(ctx, madmin.AccountOpts{}) 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) { func (ac AdminClient) getBucketQuota(ctx context.Context, bucket string) (madmin.BucketQuota, error) {
return ac.Client.GetBucketQuota(ctx, bucket) return ac.Client.GetBucketQuota(ctx, bucket)
} }
// serverHealthInfo implements mc.ServerHealthInfo - Connect to a minio server and call Health Info Management API func (ac AdminClient) kmsStatus(ctx context.Context) (madmin.KMSStatus, error) {
func (ac AdminClient) serverHealthInfo(ctx context.Context, deadline time.Duration) (interface{}, string, error) { return ac.Client.KMSStatus(ctx)
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 NewMinioAdminClient(ctx context.Context, sessionClaims *models.Principal) (*madmin.AdminClient, error) { func NewMinioAdminClient(ctx context.Context, sessionClaims *models.Principal) (*madmin.AdminClient, error) {
@@ -546,114 +188,3 @@ func getClientIP(r *http.Request) string {
} }
return raddr 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)
}

View File

@@ -40,109 +40,102 @@ import (
"github.com/stretchr/testify/assert" "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 // 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() // implements mc.S3Client.AddNotificationConfigMock()
func (c s3ClientMock) addNotificationConfig(ctx context.Context, arn string, events []string, prefix, suffix string, ignoreExisting bool) *probe.Error { 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() // implements mc.S3Client.DeleteBucketEventNotification()
func (c s3ClientMock) removeNotificationConfig(ctx context.Context, arn string, event string, prefix string, suffix string) *probe.Error { 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)
}
func (c s3ClientMock) setVersioning(ctx context.Context, state string, excludePrefix []string, excludeFolders bool) *probe.Error {
return c.setVersioningMock(ctx, state, excludePrefix, excludeFolders)
}
// Define a mock struct of minio Client interface implementation
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() // mock function of getBucketNotification()
func (mc minioClientMock) getBucketNotification(ctx context.Context, bucketName string) (bucketNotification notification.Configuration, err error) { func (mc minioClientMock) getBucketNotification(ctx context.Context, bucketName string) (bucketNotification notification.Configuration, err error) {
return minioGetBucketNotificationMock(ctx, bucketName) return mc.getBucketNotificationMock(ctx, bucketName)
} }
// 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{}
// mock function of listBucketsWithContext() // mock function of listBucketsWithContext()
func (mc minioClientMock) listBucketsWithContext(ctx context.Context) ([]minio.BucketInfo, error) { func (mc minioClientMock) listBucketsWithContext(ctx context.Context) ([]minio.BucketInfo, error) {
return minioListBucketsWithContextMock(ctx) return mc.listBucketsWithContextMock(ctx)
} }
// mock function of makeBucketsWithContext() // mock function of makeBucketsWithContext()
func (mc minioClientMock) makeBucketWithContext(ctx context.Context, bucketName, location string, objectLock bool) error { 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() // mock function of setBucketPolicyWithContext()
func (mc minioClientMock) setBucketPolicyWithContext(ctx context.Context, bucketName, policy string) error { 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() // mock function of removeBucket()
func (mc minioClientMock) removeBucket(_ context.Context, bucketName string) error { func (mc minioClientMock) removeBucket(_ context.Context, bucketName string) error {
return minioRemoveBucketMock(bucketName) return mc.removeBucketMock(bucketName)
} }
// mock function of getBucketPolicy() // mock function of getBucketPolicy()
func (mc minioClientMock) getBucketPolicy(_ context.Context, bucketName string) (string, error) { 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 { 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 { 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) { 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 { 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) { 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) { 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) { func (mc minioClientMock) copyObject(ctx context.Context, dst minio.CopyDestOptions, src minio.CopySrcOptions) (minio.UploadInfo, error) {
return minioCopyObjectMock(ctx, dst, src) return mc.copyObjectMock(ctx, dst, src)
}
func (c s3ClientMock) setVersioning(ctx context.Context, state string, excludePrefix []string, excludeFolders bool) *probe.Error {
return minioSetVersioningMock(ctx, state, excludePrefix, excludeFolders)
} }
func (mc minioClientMock) GetBucketTagging(ctx context.Context, bucketName string) (*tags.Tags, error) { 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 { 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 { 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) { func minioGetBucketTaggingMock(ctx context.Context, bucketName string) (*tags.Tags, error) {
@@ -172,7 +165,7 @@ func TestMakeBucket(t *testing.T) {
ctx := context.Background() ctx := context.Background()
// Test-1: makeBucket() create a bucket // Test-1: makeBucket() create a bucket
// mock function response from makeBucketWithContext(ctx) // mock function response from makeBucketWithContext(ctx)
minioMakeBucketWithContextMock = func(_ context.Context, _, _ string, _ bool) error { minClient.makeBucketWithContextMock = func(_ context.Context, _, _ string, _ bool) error {
return nil return nil
} }
if err := makeBucket(ctx, minClient, "bucktest1", true); err != 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 // 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") return errors.New("error")
} }
if err := makeBucket(ctx, minClient, "bucktest1", true); assert.Error(err) { 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 // Test-1: getBucketInfo() get a bucket with PRIVATE access
// if not policy set on bucket, access should be PRIVATE // if not policy set on bucket, access should be PRIVATE
mockPolicy := "" mockPolicy := ""
minioGetBucketPolicyMock = func(_ string) (string, error) { minClient.getBucketPolicyMock = func(_ string) (string, error) {
return mockPolicy, nil return mockPolicy, nil
} }
bucketToSet := "csbucket" bucketToSet := "csbucket"
@@ -241,7 +234,7 @@ func TestBucketInfo(t *testing.T) {
Policy: []byte(infoPolicy), Policy: []byte(infoPolicy),
} }
// mock function response from listBucketsWithContext(ctx) // mock function response from listBucketsWithContext(ctx)
minioAccountInfoMock = func(_ context.Context) (madmin.AccountInfo, error) { adminClient.minioAccountInfoMock = func(_ context.Context) (madmin.AccountInfo, error) {
return mockBucketList, nil return mockBucketList, nil
} }
@@ -258,7 +251,7 @@ func TestBucketInfo(t *testing.T) {
// Test-2: getBucketInfo() get a bucket with PUBLIC access // Test-2: getBucketInfo() get a bucket with PUBLIC access
// mock policy for bucket csbucket with readWrite access (should return PUBLIC) // 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/*\"]}]}" 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 return mockPolicy, nil
} }
bucketToSet = "csbucket" bucketToSet = "csbucket"
@@ -282,7 +275,7 @@ func TestBucketInfo(t *testing.T) {
// Test-3: getBucketInfo() get a bucket with PRIVATE access // Test-3: getBucketInfo() get a bucket with PRIVATE access
// if bucket has a null statement, the bucket is PRIVATE // if bucket has a null statement, the bucket is PRIVATE
mockPolicy = "{\"Version\":\"2012-10-17\",\"Statement\":[]}" mockPolicy = "{\"Version\":\"2012-10-17\",\"Statement\":[]}"
minioGetBucketPolicyMock = func(_ string) (string, error) { minClient.getBucketPolicyMock = func(_ string) (string, error) {
return mockPolicy, nil return mockPolicy, nil
} }
bucketToSet = "csbucket" bucketToSet = "csbucket"
@@ -305,7 +298,7 @@ func TestBucketInfo(t *testing.T) {
// Test-4: getBucketInfo() returns an errors while parsing invalid policy // Test-4: getBucketInfo() returns an errors while parsing invalid policy
mockPolicy = "policyinvalid" mockPolicy = "policyinvalid"
minioGetBucketPolicyMock = func(_ string) (string, error) { minClient.getBucketPolicyMock = func(_ string) (string, error) {
return mockPolicy, nil return mockPolicy, nil
} }
bucketToSet = "csbucket" bucketToSet = "csbucket"
@@ -333,7 +326,7 @@ func TestSetBucketAccess(t *testing.T) {
function := "setBucketAccessPolicy()" function := "setBucketAccessPolicy()"
// Test-1: setBucketAccessPolicy() set a bucket's access policy // Test-1: setBucketAccessPolicy() set a bucket's access policy
// mock function response from setBucketPolicyWithContext(ctx) // mock function response from setBucketPolicyWithContext(ctx)
minioSetBucketPolicyWithContextMock = func(_ context.Context, _, _ string) error { minClient.setBucketPolicyWithContextMock = func(_ context.Context, _, _ string) error {
return nil return nil
} }
if err := setBucketAccessPolicy(ctx, minClient, "bucktest1", models.BucketAccessPUBLIC, ""); err != 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 // 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") return errors.New("error")
} }
if err := setBucketAccessPolicy(ctx, minClient, "bucktest1", models.BucketAccessPUBLIC, ""); assert.Error(err) { 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) { func Test_enableBucketEncryption(t *testing.T) {
ctx := context.Background() ctx := context.Background()
minClient := minioClientMock{}
type args struct { type args struct {
ctx context.Context ctx context.Context
client MinioClient
bucketName string bucketName string
encryptionType models.BucketEncryptionType encryptionType models.BucketEncryptionType
kmsKeyID string kmsKeyID string
@@ -389,7 +380,6 @@ func Test_enableBucketEncryption(t *testing.T) {
name: "Bucket encryption enabled correctly", name: "Bucket encryption enabled correctly",
args: args{ args: args{
ctx: ctx, ctx: ctx,
client: minClient,
bucketName: "test", bucketName: "test",
encryptionType: "sse-s3", encryptionType: "sse-s3",
mockEnableBucketEncryptionFunc: func(_ context.Context, _ string, _ *sse.Configuration) error { mockEnableBucketEncryptionFunc: func(_ context.Context, _ string, _ *sse.Configuration) error {
@@ -402,7 +392,6 @@ func Test_enableBucketEncryption(t *testing.T) {
name: "Error when enabling bucket encryption", name: "Error when enabling bucket encryption",
args: args{ args: args{
ctx: ctx, ctx: ctx,
client: minClient,
bucketName: "test", bucketName: "test",
encryptionType: "sse-s3", encryptionType: "sse-s3",
mockEnableBucketEncryptionFunc: func(_ context.Context, _ string, _ *sse.Configuration) error { mockEnableBucketEncryptionFunc: func(_ context.Context, _ string, _ *sse.Configuration) error {
@@ -414,8 +403,9 @@ func Test_enableBucketEncryption(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(_ *testing.T) { t.Run(tt.name, func(_ *testing.T) {
minioSetBucketEncryptionMock = tt.args.mockEnableBucketEncryptionFunc minClient := minioClientMock{}
if err := enableBucketEncryption(tt.args.ctx, tt.args.client, tt.args.bucketName, tt.args.encryptionType, tt.args.kmsKeyID); (err != nil) != tt.wantErr { 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) 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) { func Test_disableBucketEncryption(t *testing.T) {
ctx := context.Background() ctx := context.Background()
minClient := minioClientMock{}
type args struct { type args struct {
ctx context.Context ctx context.Context
client MinioClient
bucketName string bucketName string
mockBucketDisableFunc func(ctx context.Context, bucketName string) error mockBucketDisableFunc func(ctx context.Context, bucketName string) error
} }
@@ -440,7 +428,6 @@ func Test_disableBucketEncryption(t *testing.T) {
name: "Bucket encryption disabled correctly", name: "Bucket encryption disabled correctly",
args: args{ args: args{
ctx: ctx, ctx: ctx,
client: minClient,
bucketName: "test", bucketName: "test",
mockBucketDisableFunc: func(_ context.Context, _ string) error { mockBucketDisableFunc: func(_ context.Context, _ string) error {
return nil return nil
@@ -452,7 +439,6 @@ func Test_disableBucketEncryption(t *testing.T) {
name: "Error when disabling bucket encryption", name: "Error when disabling bucket encryption",
args: args{ args: args{
ctx: ctx, ctx: ctx,
client: minClient,
bucketName: "test", bucketName: "test",
mockBucketDisableFunc: func(_ context.Context, _ string) error { mockBucketDisableFunc: func(_ context.Context, _ string) error {
return ErrDefault return ErrDefault
@@ -463,8 +449,9 @@ func Test_disableBucketEncryption(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(_ *testing.T) { t.Run(tt.name, func(_ *testing.T) {
minioRemoveBucketEncryptionMock = tt.args.mockBucketDisableFunc minClient := minioClientMock{}
if err := disableBucketEncryption(tt.args.ctx, tt.args.client, tt.args.bucketName); (err != nil) != tt.wantErr { 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) 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) { func Test_getBucketEncryptionInfo(t *testing.T) {
ctx := context.Background() ctx := context.Background()
minClient := minioClientMock{}
type args struct { type args struct {
ctx context.Context ctx context.Context
client MinioClient
bucketName string bucketName string
mockBucketEncryptionGet func(ctx context.Context, bucketName string) (*sse.Configuration, error) 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", name: "Bucket encryption info returned correctly",
args: args{ args: args{
ctx: ctx, ctx: ctx,
client: minClient,
bucketName: "test", bucketName: "test",
mockBucketEncryptionGet: func(_ context.Context, _ string) (*sse.Configuration, error) { mockBucketEncryptionGet: func(_ context.Context, _ string) (*sse.Configuration, error) {
return &sse.Configuration{ return &sse.Configuration{
@@ -512,7 +496,6 @@ func Test_getBucketEncryptionInfo(t *testing.T) {
name: "Bucket encryption info with no rules", name: "Bucket encryption info with no rules",
args: args{ args: args{
ctx: ctx, ctx: ctx,
client: minClient,
bucketName: "test", bucketName: "test",
mockBucketEncryptionGet: func(_ context.Context, _ string) (*sse.Configuration, error) { mockBucketEncryptionGet: func(_ context.Context, _ string) (*sse.Configuration, error) {
return &sse.Configuration{ return &sse.Configuration{
@@ -526,7 +509,6 @@ func Test_getBucketEncryptionInfo(t *testing.T) {
name: "Error when obtaining bucket encryption info", name: "Error when obtaining bucket encryption info",
args: args{ args: args{
ctx: ctx, ctx: ctx,
client: minClient,
bucketName: "test", bucketName: "test",
mockBucketEncryptionGet: func(_ context.Context, _ string) (*sse.Configuration, error) { mockBucketEncryptionGet: func(_ context.Context, _ string) (*sse.Configuration, error) {
return nil, ErrSSENotConfigured return nil, ErrSSENotConfigured
@@ -537,8 +519,9 @@ func Test_getBucketEncryptionInfo(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(_ *testing.T) { t.Run(tt.name, func(_ *testing.T) {
minioGetBucketEncryptionMock = tt.args.mockBucketEncryptionGet minClient := minioClientMock{}
got, err := getBucketEncryptionInfo(tt.args.ctx, tt.args.client, tt.args.bucketName) minClient.getBucketEncryptionMock = tt.args.mockBucketEncryptionGet
got, err := getBucketEncryptionInfo(tt.args.ctx, minClient, tt.args.bucketName)
if (err != nil) != tt.wantErr { if (err != nil) != tt.wantErr {
t.Errorf("getBucketEncryptionInfo() errors = %v, wantErr %v", err, tt.wantErr) t.Errorf("getBucketEncryptionInfo() errors = %v, wantErr %v", err, tt.wantErr)
return return
@@ -553,10 +536,8 @@ func Test_getBucketEncryptionInfo(t *testing.T) {
func Test_SetBucketRetentionConfig(t *testing.T) { func Test_SetBucketRetentionConfig(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
ctx := context.Background() ctx := context.Background()
minClient := minioClientMock{}
type args struct { type args struct {
ctx context.Context ctx context.Context
client MinioClient
bucketName string bucketName string
mode models.ObjectRetentionMode mode models.ObjectRetentionMode
unit models.ObjectRetentionUnit unit models.ObjectRetentionUnit
@@ -572,7 +553,6 @@ func Test_SetBucketRetentionConfig(t *testing.T) {
name: "Set Bucket Retention Config", name: "Set Bucket Retention Config",
args: args{ args: args{
ctx: ctx, ctx: ctx,
client: minClient,
bucketName: "test", bucketName: "test",
mode: models.ObjectRetentionModeCompliance, mode: models.ObjectRetentionModeCompliance,
unit: models.ObjectRetentionUnitDays, unit: models.ObjectRetentionUnitDays,
@@ -587,7 +567,6 @@ func Test_SetBucketRetentionConfig(t *testing.T) {
name: "Set Bucket Retention Config 2", name: "Set Bucket Retention Config 2",
args: args{ args: args{
ctx: ctx, ctx: ctx,
client: minClient,
bucketName: "test", bucketName: "test",
mode: models.ObjectRetentionModeGovernance, mode: models.ObjectRetentionModeGovernance,
unit: models.ObjectRetentionUnitYears, unit: models.ObjectRetentionUnitYears,
@@ -602,7 +581,6 @@ func Test_SetBucketRetentionConfig(t *testing.T) {
name: "Invalid validity", name: "Invalid validity",
args: args{ args: args{
ctx: ctx, ctx: ctx,
client: minClient,
bucketName: "test", bucketName: "test",
mode: models.ObjectRetentionModeCompliance, mode: models.ObjectRetentionModeCompliance,
unit: models.ObjectRetentionUnitDays, unit: models.ObjectRetentionUnitDays,
@@ -617,7 +595,6 @@ func Test_SetBucketRetentionConfig(t *testing.T) {
name: "Invalid retention mode", name: "Invalid retention mode",
args: args{ args: args{
ctx: ctx, ctx: ctx,
client: minClient,
bucketName: "test", bucketName: "test",
mode: models.ObjectRetentionMode("othermode"), mode: models.ObjectRetentionMode("othermode"),
unit: models.ObjectRetentionUnitDays, unit: models.ObjectRetentionUnitDays,
@@ -632,7 +609,6 @@ func Test_SetBucketRetentionConfig(t *testing.T) {
name: "Invalid retention unit", name: "Invalid retention unit",
args: args{ args: args{
ctx: ctx, ctx: ctx,
client: minClient,
bucketName: "test", bucketName: "test",
mode: models.ObjectRetentionModeCompliance, mode: models.ObjectRetentionModeCompliance,
unit: models.ObjectRetentionUnit("otherunit"), unit: models.ObjectRetentionUnit("otherunit"),
@@ -647,7 +623,6 @@ func Test_SetBucketRetentionConfig(t *testing.T) {
name: "Handle errors on objec lock function", name: "Handle errors on objec lock function",
args: args{ args: args{
ctx: ctx, ctx: ctx,
client: minClient,
bucketName: "test", bucketName: "test",
mode: models.ObjectRetentionModeCompliance, mode: models.ObjectRetentionModeCompliance,
unit: models.ObjectRetentionUnitDays, unit: models.ObjectRetentionUnitDays,
@@ -661,8 +636,9 @@ func Test_SetBucketRetentionConfig(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(_ *testing.T) { t.Run(tt.name, func(_ *testing.T) {
minioSetObjectLockConfigMock = tt.args.mockBucketRetentionFunc minClient := minioClientMock{}
err := setBucketRetentionConfig(tt.args.ctx, tt.args.client, tt.args.bucketName, tt.args.mode, tt.args.unit, tt.args.validity) 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 { if tt.expectedError != nil {
fmt.Println(t.Name()) fmt.Println(t.Name())
assert.Equal(tt.expectedError.Error(), err.Error(), fmt.Sprintf("setObjectRetention() errors: `%s`, wantErr: `%s`", err, tt.expectedError)) 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) { func Test_GetBucketRetentionConfig(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
ctx := context.Background() ctx := context.Background()
minClient := minioClientMock{}
type args struct { type args struct {
ctx context.Context ctx context.Context
client MinioClient
bucketName string bucketName string
getRetentionFunc func(ctx context.Context, bucketName string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) 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", name: "Get Bucket Retention Config",
args: args{ args: args{
ctx: ctx, ctx: ctx,
client: minClient,
bucketName: "test", bucketName: "test",
getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) { getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) {
m := minio.Governance m := minio.Governance
@@ -712,7 +685,6 @@ func Test_GetBucketRetentionConfig(t *testing.T) {
name: "Get Bucket Retention Config Compliance", name: "Get Bucket Retention Config Compliance",
args: args{ args: args{
ctx: ctx, ctx: ctx,
client: minClient,
bucketName: "test", bucketName: "test",
getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) { getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) {
m := minio.Compliance m := minio.Compliance
@@ -731,7 +703,6 @@ func Test_GetBucketRetentionConfig(t *testing.T) {
name: "Handle Error on minio func", name: "Handle Error on minio func",
args: args{ args: args{
ctx: ctx, ctx: ctx,
client: minClient,
bucketName: "test", bucketName: "test",
getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) { getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) {
return nil, nil, nil, errors.New("error func") return nil, nil, nil, errors.New("error func")
@@ -746,7 +717,6 @@ func Test_GetBucketRetentionConfig(t *testing.T) {
name: "Handle NoLock Config errors", name: "Handle NoLock Config errors",
args: args{ args: args{
ctx: ctx, ctx: ctx,
client: minClient,
bucketName: "test", bucketName: "test",
getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) { getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) {
return nil, nil, nil, minio.ErrorResponse{ return nil, nil, nil, minio.ErrorResponse{
@@ -762,7 +732,6 @@ func Test_GetBucketRetentionConfig(t *testing.T) {
name: "Return errors on invalid mode", name: "Return errors on invalid mode",
args: args{ args: args{
ctx: ctx, ctx: ctx,
client: minClient,
bucketName: "test", bucketName: "test",
getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) { getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) {
m := minio.RetentionMode("other") m := minio.RetentionMode("other")
@@ -777,7 +746,6 @@ func Test_GetBucketRetentionConfig(t *testing.T) {
name: "Return errors on invalid unit", name: "Return errors on invalid unit",
args: args{ args: args{
ctx: ctx, ctx: ctx,
client: minClient,
bucketName: "test", bucketName: "test",
getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) { getRetentionFunc: func(_ context.Context, _ string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) {
m := minio.Governance m := minio.Governance
@@ -792,8 +760,9 @@ func Test_GetBucketRetentionConfig(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(_ *testing.T) { t.Run(tt.name, func(_ *testing.T) {
minioGetBucketObjectLockConfigMock = tt.args.getRetentionFunc minClient := minioClientMock{}
resp, err := getBucketRetentionConfig(tt.args.ctx, tt.args.client, tt.args.bucketName) minClient.getBucketObjectLockConfigMock = tt.args.getRetentionFunc
resp, err := getBucketRetentionConfig(tt.args.ctx, minClient, tt.args.bucketName)
if tt.expectedError != nil { if tt.expectedError != nil {
fmt.Println(t.Name()) fmt.Println(t.Name())
@@ -813,14 +782,12 @@ func Test_SetBucketVersioning(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
ctx := context.WithValue(context.Background(), utils.ContextClientIP, "127.0.0.1") ctx := context.WithValue(context.Background(), utils.ContextClientIP, "127.0.0.1")
errorMsg := "Error Message" errorMsg := "Error Message"
minClient := s3ClientMock{}
type args struct { type args struct {
ctx context.Context ctx context.Context
state VersionState state VersionState
excludePrefix []string excludePrefix []string
excludeFolders bool excludeFolders bool
bucketName string bucketName string
client s3ClientMock
setVersioningFunc func(ctx context.Context, state string, excludePrefix []string, excludeFolders bool) *probe.Error setVersioningFunc func(ctx context.Context, state string, excludePrefix []string, excludeFolders bool) *probe.Error
} }
tests := []struct { tests := []struct {
@@ -834,7 +801,6 @@ func Test_SetBucketVersioning(t *testing.T) {
ctx: ctx, ctx: ctx,
state: VersionEnable, state: VersionEnable,
bucketName: "test", bucketName: "test",
client: minClient,
setVersioningFunc: func(_ context.Context, _ string, _ []string, _ bool) *probe.Error { setVersioningFunc: func(_ context.Context, _ string, _ []string, _ bool) *probe.Error {
return nil return nil
}, },
@@ -848,7 +814,6 @@ func Test_SetBucketVersioning(t *testing.T) {
state: VersionEnable, state: VersionEnable,
excludePrefix: []string{"prefix1", "prefix2"}, excludePrefix: []string{"prefix1", "prefix2"},
bucketName: "test", bucketName: "test",
client: minClient,
setVersioningFunc: func(_ context.Context, _ string, _ []string, _ bool) *probe.Error { setVersioningFunc: func(_ context.Context, _ string, _ []string, _ bool) *probe.Error {
return nil return nil
}, },
@@ -863,7 +828,6 @@ func Test_SetBucketVersioning(t *testing.T) {
excludePrefix: []string{"prefix1", "prefix2"}, excludePrefix: []string{"prefix1", "prefix2"},
excludeFolders: true, excludeFolders: true,
bucketName: "test", bucketName: "test",
client: minClient,
setVersioningFunc: func(_ context.Context, _ string, _ []string, _ bool) *probe.Error { setVersioningFunc: func(_ context.Context, _ string, _ []string, _ bool) *probe.Error {
return nil return nil
}, },
@@ -876,7 +840,6 @@ func Test_SetBucketVersioning(t *testing.T) {
ctx: ctx, ctx: ctx,
state: VersionEnable, state: VersionEnable,
bucketName: "test", bucketName: "test",
client: minClient,
setVersioningFunc: func(_ context.Context, _ string, _ []string, _ bool) *probe.Error { setVersioningFunc: func(_ context.Context, _ string, _ []string, _ bool) *probe.Error {
return probe.NewError(errors.New(errorMsg)) return probe.NewError(errors.New(errorMsg))
}, },
@@ -887,9 +850,10 @@ func Test_SetBucketVersioning(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(_ *testing.T) { 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(t.Name())
fmt.Println("Expected:", tt.expectedError, "Error:", err) fmt.Println("Expected:", tt.expectedError, "Error:", err)
@@ -1202,11 +1166,11 @@ func Test_getAccountBuckets(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(_ *testing.T) { t.Run(tt.name, func(_ *testing.T) {
client := AdminClientMock{}
// mock function response from listBucketsWithContext(ctx) // 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 return tt.args.mockBucketList, tt.args.mockError
} }
client := AdminClientMock{}
got, err := getAccountBuckets(tt.args.ctx, client) got, err := getAccountBuckets(tt.args.ctx, client)
if !tt.wantErr(t, err, fmt.Sprintf("getAccountBuckets(%v, %v)", tt.args.ctx, client)) { if !tt.wantErr(t, err, fmt.Sprintf("getAccountBuckets(%v, %v)", tt.args.ctx, client)) {

View File

@@ -149,28 +149,25 @@ func Test_validateUserAgainstIDP(t *testing.T) {
} }
func Test_getAccountInfo(t *testing.T) { func Test_getAccountInfo(t *testing.T) {
client := AdminClientMock{}
type args struct { type args struct {
ctx context.Context ctx context.Context
client MinioAdmin
} }
tests := []struct { tests := []struct {
name string name string
args args args args
want *iampolicy.Policy want *iampolicy.Policy
wantErr bool wantErr bool
mockFunc func() mockFunc func(client *AdminClientMock)
}{ }{
{ {
name: "error getting account info", name: "error getting account info",
args: args{ args: args{
ctx: context.Background(), ctx: context.Background(),
client: client,
}, },
want: nil, want: nil,
wantErr: true, wantErr: true,
mockFunc: func() { mockFunc: func(client *AdminClientMock) {
minioAccountInfoMock = func(_ context.Context) (madmin.AccountInfo, error) { client.minioAccountInfoMock = func(_ context.Context) (madmin.AccountInfo, error) {
return madmin.AccountInfo{}, errors.New("something went wrong") return madmin.AccountInfo{}, errors.New("something went wrong")
} }
}, },
@@ -178,10 +175,11 @@ func Test_getAccountInfo(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(_ *testing.T) { t.Run(tt.name, func(_ *testing.T) {
client := AdminClientMock{}
if tt.mockFunc != nil { 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 { if (err != nil) != tt.wantErr {
t.Errorf("getAccountInfo() error = %v, wantErr %v", err, tt.wantErr) t.Errorf("getAccountInfo() error = %v, wantErr %v", err, tt.wantErr)
return return

View File

@@ -42,29 +42,6 @@ const (
wsBasePath = "/ws" 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 { type wsMinioClient struct {
// websocket connection. // websocket connection.
conn wsConn conn wsConn
@@ -89,26 +66,6 @@ type wsConn struct {
conn *websocket.Conn 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 { func (c wsConn) writeMessage(messageType int, data []byte) error {
return c.conn.WriteMessage(messageType, data) return c.conn.WriteMessage(messageType, data)
} }
@@ -176,22 +133,6 @@ func serveWS(w http.ResponseWriter, req *http.Request) {
} }
switch { 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`): case strings.HasPrefix(wsPath, `/objectManager`):
wsMinioClient, err := newWebSocketMinioClient(conn, session, clientIP) wsMinioClient, err := newWebSocketMinioClient(conn, session, clientIP)
if err != nil { 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) { func newWebSocketMinioClient(conn *websocket.Conn, claims *models.Principal, clientIP string) (*wsMinioClient, error) {
mClient, err := newMinioClient(claims, clientIP) mClient, err := newMinioClient(claims, clientIP)
if err != nil { if err != nil {
@@ -312,42 +231,3 @@ func closeWsConn(conn *websocket.Conn) {
conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
conn.Close() 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, ""))
}

74
go.mod
View File

@@ -1,12 +1,12 @@
module github.com/minio/console module github.com/minio/console
go 1.23 go 1.23.0
toolchain go1.23.6 toolchain go1.23.7
require ( require (
github.com/blang/semver/v4 v4.0.0 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/dustin/go-humanize v1.0.1 // indirect
github.com/fatih/color v1.18.0 github.com/fatih/color v1.18.0
github.com/go-openapi/errors v0.22.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/runtime v0.28.0
github.com/go-openapi/spec v0.21.0 github.com/go-openapi/spec v0.21.0
github.com/go-openapi/strfmt v0.23.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/go-openapi/validate v0.24.0
github.com/golang-jwt/jwt/v4 v4.5.1 github.com/golang-jwt/jwt/v4 v4.5.1
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
github.com/jessevdk/go-flags v1.6.1 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/cli v1.24.2
github.com/minio/highwayhash v1.0.3 github.com/minio/highwayhash v1.0.3
github.com/minio/kes v0.24.0 github.com/minio/kes v0.24.0
github.com/minio/madmin-go/v3 v3.0.91 github.com/minio/madmin-go/v3 v3.0.98
github.com/minio/mc v0.0.0-20250208210632-10c50368c526 github.com/minio/mc v0.0.0-20250313080218-cf909e1063a9
github.com/minio/minio-go/v7 v7.0.85 github.com/minio/minio-go/v7 v7.0.88
github.com/minio/selfupdate v0.6.0 github.com/minio/selfupdate v0.6.0
github.com/minio/websocket v1.6.0 github.com/minio/websocket v1.6.0
github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/go-homedir v1.1.0
@@ -34,16 +34,16 @@ require (
github.com/stretchr/testify v1.10.0 github.com/stretchr/testify v1.10.0
github.com/tidwall/gjson v1.18.0 // indirect github.com/tidwall/gjson v1.18.0 // indirect
github.com/unrolled/secure v1.17.0 github.com/unrolled/secure v1.17.0
golang.org/x/crypto v0.33.0 golang.org/x/crypto v0.36.0
golang.org/x/net v0.35.0 golang.org/x/net v0.37.0
golang.org/x/oauth2 v0.26.0 golang.org/x/oauth2 v0.28.0
// Added to include security fix for // Added to include security fix for
// https://github.com/golang/go/issues/56152 // 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 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 ( require (
aead.dev/mem v0.2.0 // indirect aead.dev/mem v0.2.0 // indirect
@@ -55,7 +55,7 @@ require (
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/charmbracelet/bubbles v0.20.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/lipgloss v1.0.0 // indirect
github.com/charmbracelet/x/ansi v0.8.0 // indirect github.com/charmbracelet/x/ansi v0.8.0 // indirect
github.com/charmbracelet/x/term v0.2.1 // 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-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // 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/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/docker/go-units v0.5.0 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/fatih/structs v1.1.0 // indirect github.com/fatih/structs v1.1.0 // indirect
github.com/go-ini/ini v1.67.0 // indirect github.com/go-ini/ini v1.67.0 // indirect
github.com/go-ole/go-ole v1.3.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/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/go-openapi/jsonreference v0.21.0 // indirect
github.com/goccy/go-json v0.10.5 // indirect github.com/goccy/go-json v0.10.5 // indirect
github.com/gogo/protobuf v1.3.2 // 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/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // 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/josharian/intern v1.0.0 // indirect
github.com/juju/ratelimit v1.0.2 // 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/blackmagic v1.0.2 // indirect
github.com/lestrrat-go/httpcc v1.0.1 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect
github.com/lestrrat-go/httprc v1.0.6 // indirect github.com/lestrrat-go/httprc v1.0.6 // indirect
github.com/lestrrat-go/iter v1.0.2 // 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/lestrrat-go/option v1.0.1 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // 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/mailru/easyjson v0.9.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-ieproxy v0.0.12 // 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/mattn/go-runewidth v0.0.16 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/minio/colorjson v1.0.8 // 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/filepath v1.0.0 // indirect
github.com/minio/kms-go/kes v0.3.1 // indirect github.com/minio/kms-go/kes v0.3.1 // indirect
github.com/minio/md5-simd v1.1.2 // indirect github.com/minio/md5-simd v1.1.2 // indirect
github.com/mitchellh/mapstructure v1.5.0 // 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/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/reflow v0.3.0 // 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/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/oklog/ulid v1.3.1 // indirect github.com/oklog/ulid v1.3.1 // indirect
github.com/olekukonko/tablewriter v0.0.5 // 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/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/posener/complete v1.2.3 // indirect github.com/posener/complete v1.2.3 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // 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/client_model v0.6.1 // indirect
github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/common v0.62.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect github.com/prometheus/procfs v0.15.1 // indirect
github.com/prometheus/prom2json v1.4.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/rivo/uniseg v0.4.7 // indirect
github.com/rjeczalik/notify v0.9.3 // indirect github.com/rjeczalik/notify v0.9.3 // indirect
github.com/safchain/ethtool v0.5.10 // 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/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect
github.com/tinylib/msgp v1.2.5 // indirect github.com/tinylib/msgp v1.2.5 // indirect
github.com/tklauser/go-sysconf v0.3.14 // indirect github.com/tklauser/go-sysconf v0.3.15 // indirect
github.com/tklauser/numcpus v0.9.0 // indirect github.com/tklauser/numcpus v0.10.0 // indirect
github.com/vbauerster/mpb/v8 v8.9.2 // indirect github.com/vbauerster/mpb/v8 v8.9.3 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.etcd.io/etcd/api/v3 v3.5.18 // indirect go.etcd.io/etcd/api/v3 v3.5.19 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.18 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.19 // indirect
go.etcd.io/etcd/client/v3 v3.5.18 // indirect go.etcd.io/etcd/client/v3 v3.5.19 // indirect
go.mongodb.org/mongo-driver v1.17.2 // indirect go.mongodb.org/mongo-driver v1.17.3 // indirect
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect go.uber.org/zap v1.27.0 // indirect
golang.org/x/sync v0.11.0 // indirect golang.org/x/sync v0.12.0 // indirect
golang.org/x/sys v0.30.0 // indirect golang.org/x/sys v0.31.0 // indirect
golang.org/x/term v0.29.0 // indirect golang.org/x/term v0.30.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250207221924-e9438ea467c6 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250311190419-81fb87f6b8bf // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250311190419-81fb87f6b8bf // indirect
google.golang.org/grpc v1.70.0 // indirect google.golang.org/grpc v1.71.0 // indirect
google.golang.org/protobuf v1.36.5 // indirect google.golang.org/protobuf v1.36.5 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
) )

164
go.sum
View File

@@ -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/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 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE=
github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU= 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.4 h1:kCg7B+jSCFPLYRA52SDZjr51kG/fMUEoPoZrkaDHyoI=
github.com/charmbracelet/bubbletea v1.3.0/go.mod h1:eTaHfqbIwvBhFQM/nlT1NsGc4kp8jhF8LfUK67XiTDM= 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 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg=
github.com/charmbracelet/lipgloss v1.0.0/go.mod h1:U5fy9Z+C38obMs+T+tJqst9VGzlOYGj4ri9reL3qUlo= 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= 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/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 h1:FckUN5ngEk2LpvuG0fw1GEFx6LtyY2pWI/Z2QgCnEYo=
github.com/cheggaaa/pb v1.0.29/go.mod h1:W40334L7FMC5JKWldsTWbdGjLo0RxUKK73K+TuPxX30= 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.7 h1:2FsIW307kt7A/rz/ZI2lvPO+v3wKazzE4K/0LtTWsOI=
github.com/cheggaaa/pb/v3 v3.1.6/go.mod h1:urxmfVtaxT+9aWk92DbsvXFZtNSWQSO5TRAp+MJ3l1s= 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 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= 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.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 h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
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/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 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= 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= 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/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 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w=
github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE= 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.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= 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 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
github.com/go-openapi/loads v0.22.0 h1:ECPGd4jX1U6NApCGG1We+uEozOAvXvJSF4nnwHZ8Aco= 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/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 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c=
github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4= 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.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU=
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= 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 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58=
github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ= 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= 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.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 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 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.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 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 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 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/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 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= 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.7 h1:m+LbHpm0aIAPLzLbMfn8dc3Ht8MW7lsSO4MPItz/Uuo=
github.com/jedib0t/go-pretty/v6 v6.6.5/go.mod h1:Uq/HrbhuFty5WSVNfjpQQe47x16RwVGXIveNGEyGtHs= 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 h1:Cvu5U8UGrLay1rZfv/zP7iLpSHGUZ/Ou68T0iX1bBK4=
github.com/jessevdk/go-flags v1.6.1/go.mod h1:Mk8T1hIAWpOiJiHa9rJASDK2UGWji0EuPGBnNLMooyc= github.com/jessevdk/go-flags v1.6.1/go.mod h1:Mk8T1hIAWpOiJiHa9rJASDK2UGWji0EuPGBnNLMooyc=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= 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/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/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 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.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= 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.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.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= 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 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 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/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 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=
github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= 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.4 h1:uBCMmJX8oRZStmKuMMOFb0Yh9xmEMgNJLgjuKKt4/qc=
github.com/lestrrat-go/jwx/v2 v2.1.3/go.mod h1:q6uFgbgZfEmQrfJfrCo90QcQOcXFMfbI/fO0NqRtvZo= 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 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU=
github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= 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 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= 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-20250303091104-876f3ea5145d h1:fjMbDVUGsMQiVZnSQsmouYJvMdwsGiDipOZoN66v844=
github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= 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 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= 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= 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/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 h1:AS6gEQ1dTRYHmC4xuoodPDRILHP/9Wz5wYUGDQfPLpg=
github.com/minio/colorjson v1.0.8/go.mod h1:wrs39G/4kqNlGjwqHvPlAnXuc2tlPszo6JKdSBCLN8w= 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 h1:fvkJu1+6X+ECRA6G3+JJETj4QeAYO9sV43I79H8ubDY=
github.com/minio/filepath v1.0.0/go.mod h1:/nRZA2ldl5z6jT9/KQuvZcQlxZIMQoFFQPvEXx9T/Bw= github.com/minio/filepath v1.0.0/go.mod h1:/nRZA2ldl5z6jT9/KQuvZcQlxZIMQoFFQPvEXx9T/Bw=
github.com/minio/highwayhash v1.0.3 h1:kbnuUMoHYyVl7szWjSxJnxw11k2U709jqFPPmIUyD6Q= 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/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 h1:K3sPFAvFbJx33XlCTUBnQo8JRmSZyDvT6T2/MQ2iC3A=
github.com/minio/kms-go/kes v0.3.1/go.mod h1:Q9Ct0KUAuN9dH0hSVa0eva45Jg99cahbZpPxeqR9rOQ= 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.98 h1:K9gyo6Men83FgMX9ZOd/x5+cghRK9rBhf8v7s+mN2nA=
github.com/minio/madmin-go/v3 v3.0.91/go.mod h1:pMLdj9OtN0CANNs5tdm6opvOlDFfj0WhbztboZAjRWE= github.com/minio/madmin-go/v3 v3.0.98/go.mod h1:pMLdj9OtN0CANNs5tdm6opvOlDFfj0WhbztboZAjRWE=
github.com/minio/mc v0.0.0-20250208210632-10c50368c526 h1:FzxZFUgTf21n+spBVhGAed8HCSUpAN+zfOChg49zZ64= github.com/minio/mc v0.0.0-20250313080218-cf909e1063a9 h1:6RyInOHKL6jz8zxcAar/h6rg/aJCxDP/uFuSNvYSuMI=
github.com/minio/mc v0.0.0-20250208210632-10c50368c526/go.mod h1:AgzD1Axs0TauPrFSd7M3yC75TRg9zT919d9bbxhubJ4= 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 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= 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.88 h1:v8MoIJjwYxOkehp+eiLIuvXk87P2raUtoU5klrAAshs=
github.com/minio/minio-go/v7 v7.0.85/go.mod h1:57YXpvc5l3rjPdhqNrDsvVlY0qPI6UTk1bflAe+9doY= 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 h1:dWafQFyEfGhJvK6AwLOt83bIG5bxKxKJnKMCi0XAaoA=
github.com/minio/mux v1.9.0/go.mod h1:1pAare17ZRL5GpmNL+9YmqHoWnLmMZF9C/ioUCfy0BQ= 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.1.2 h1:DCIzGiUM2uJelWKP1wzwyP8KqdNXHrxMkG52S337oN8=
github.com/minio/pkg/v3 v3.0.29/go.mod h1:mIaN552nu0D2jiSk5BQC8LB25f44ytbOBJCuLtksX7Q= 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 h1:i76PgT0K5xO9+hjzKcacQtO7+MjJ4JKA8Ak8XQ9DDwU=
github.com/minio/selfupdate v0.6.0/go.mod h1:bO02GTIPCMQFTEvE5h4DjYB58bCoZ35XLeBf0buTDdM= github.com/minio/selfupdate v0.6.0/go.mod h1:bO02GTIPCMQFTEvE5h4DjYB58bCoZ35XLeBf0buTDdM=
github.com/minio/websocket v1.6.0 h1:CPvnQvNvlVaQmvw5gtJNyYQhg4+xRmrPNhBbv8BdpAE= 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/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 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= 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 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= 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 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= 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 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= 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.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= 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 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= 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/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 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= 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.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= 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 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= 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/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 h1:7McxdrHgPEOtMwWjkKtd0v5AhpR2Q6QAnlHKVxq0+tQ=
github.com/prometheus/prom2json v1.4.1/go.mod h1:CzOQykSKFxXuC7ELUZHOHQvwKesQ3eN0p2PWLhFitQM= 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.302.1 h1:xqVdrwrB4WNpdgJqxsz5loqFWNUZitsK8myqLuSZ6Ag=
github.com/prometheus/prometheus v0.301.0/go.mod h1:BJLjWCKNfRfjp7Q48DrAjARnCi7GhfUVvUFEAWTssZM= 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.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.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= 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/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 h1:WeQg1whrXRFiZusidTQqzETkRpGjFjcIhW6uqWH09po=
github.com/tinylib/msgp v1.2.5/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0= 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.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4=
github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4=
github.com/tklauser/numcpus v0.9.0 h1:lmyCHtANi8aRUgkckBgoDk1nHCux3n2cgkJLXdQGPDo= github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso=
github.com/tklauser/numcpus v0.9.0/go.mod h1:SN6Nq1O3VychhC1npsWostA+oW+VOQTxZrS604NSRyI= 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 h1:Io7ifFgo99Bnh0J7+Q+qcMzWM6kaDPCA5FroFZEdbWU=
github.com/unrolled/secure v1.17.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= 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.3 h1:PnMeF+sMvYv9u23l6DO6Q3+Mdj408mjLRXIzmUmU2Z8=
github.com/vbauerster/mpb/v8 v8.9.2/go.mod h1:hxS8Hz4C6ijnppDSIX6LjG8FYJSoPo9iIOcE53Zik0c= 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.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/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 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= 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.19 h1:w3L6sQZGsWPuBxRQ4m6pPP3bVUtV8rjW033EGwlr0jw=
go.etcd.io/etcd/api/v3 v3.5.18/go.mod h1:uY03Ob2H50077J7Qq0DeehjM/A9S8PhVfbQ1mSaMopU= go.etcd.io/etcd/api/v3 v3.5.19/go.mod h1:QqKGViq4KTgOG43dr/uH0vmGWIaoJY3ggFi6ZH0TH/U=
go.etcd.io/etcd/client/pkg/v3 v3.5.18 h1:mZPOYw4h8rTk7TeJ5+3udUkfVGBqc+GCjOJYd68QgNM= go.etcd.io/etcd/client/pkg/v3 v3.5.19 h1:9VsyGhg0WQGjDWWlDI4VuaS9PZJGNbPkaHEIuLwtixk=
go.etcd.io/etcd/client/pkg/v3 v3.5.18/go.mod h1:BxVf2o5wXG9ZJV+/Cu7QNUiJYk4A29sAhoI5tIRsCu4= go.etcd.io/etcd/client/pkg/v3 v3.5.19/go.mod h1:qaOi1k4ZA9lVLejXNvyPABrVEe7VymMF2433yyRQ7O0=
go.etcd.io/etcd/client/v3 v3.5.18 h1:nvvYmNHGumkDjZhTHgVU36A9pykGa2K4lAJ0yY7hcXA= go.etcd.io/etcd/client/v3 v3.5.19 h1:+4byIz6ti3QC28W0zB0cEZWwhpVHXdrKovyycJh1KNo=
go.etcd.io/etcd/client/v3 v3.5.18/go.mod h1:kmemwOsPU9broExyhYsBxX4spCTDX3yLgPMWtpBXG6E= go.etcd.io/etcd/client/v3 v3.5.19/go.mod h1:FNzyinmMIl0oVsty1zA3hFeUrxXI/JpEnz4sG+POzjU=
go.mongodb.org/mongo-driver v1.17.2 h1:gvZyk8352qSfzyZ2UMWcpDpMSGEr1eqE4T793SqyhzM= go.mongodb.org/mongo-driver v1.17.3 h1:TQyXhnsWfWtgAhMtOgtYHMTkZIfBTpMTsMnd9ZBeHxQ=
go.mongodb.org/mongo-driver v1.17.2/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= 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 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= 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.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ= go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M= go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM= go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM= go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU= go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= 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 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= 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-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-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.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.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= 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.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.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= 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-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-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.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE= golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= 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-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-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-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.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.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 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-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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/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.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.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.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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-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.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= 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.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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/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.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= 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-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-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 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-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-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/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-20250311190419-81fb87f6b8bf h1:BdIVRm+fyDUn8lrZLPSlBCfM/YKDwUBYgDoLv9+DYo0=
google.golang.org/genproto/googleapis/api v0.0.0-20250207221924-e9438ea467c6/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4= 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-20250207221924-e9438ea467c6 h1:2duwAxN2+k0xLNpjnHTXoMUgnv6VPSp5fiqTuwSxjmI= google.golang.org/genproto/googleapis/rpc v0.0.0-20250311190419-81fb87f6b8bf h1:dHDlF3CWxQkefK9IJx+O8ldY0gLygvrlYRBNbPqDWuY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= google.golang.org/genproto/googleapis/rpc v0.0.0-20250311190419-81fb87f6b8bf/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= 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 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= 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= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@@ -59,6 +59,7 @@
"proxy": "http://localhost:9090/", "proxy": "http://localhost:9090/",
"devDependencies": { "devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@babel/runtime": "^7.26.10",
"@playwright/test": "^1.50.1", "@playwright/test": "^1.50.1",
"@types/jest": "^29.5.14", "@types/jest": "^29.5.14",
"@types/lodash": "^4.17.15", "@types/lodash": "^4.17.15",
@@ -95,7 +96,8 @@
"ws": "^8.17.1", "ws": "^8.17.1",
"rollup": "^4.24.0", "rollup": "^4.24.0",
"cookie": "^0.7.2", "cookie": "^0.7.2",
"jspdf": "^3.0.0" "jspdf": "^3.0.0",
"@babel/runtime": "^7.26.10"
}, },
"main": "index.js", "main": "index.js",
"packageManager": "yarn@4.4.0" "packageManager": "yarn@4.4.0"

View File

@@ -1652,12 +1652,12 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "@babel/runtime@npm:^7.26.10":
version: 7.26.0 version: 7.26.10
resolution: "@babel/runtime@npm:7.26.0" resolution: "@babel/runtime@npm:7.26.10"
dependencies: dependencies:
regenerator-runtime: "npm:^0.14.0" regenerator-runtime: "npm:^0.14.0"
checksum: 10c0/12c01357e0345f89f4f7e8c0e81921f2a3e3e101f06e8eaa18a382b517376520cd2fa8c237726eb094dab25532855df28a7baaf1c26342b52782f6936b07c287 checksum: 10c0/6dc6d88c7908f505c4f7770fb4677dfa61f68f659b943c2be1f2a99cb6680343462867abf2d49822adc435932919b36c77ac60125793e719ea8745f2073d3745
languageName: node languageName: node
linkType: hard linkType: hard
@@ -17914,6 +17914,7 @@ __metadata:
resolution: "web-app@workspace:." resolution: "web-app@workspace:."
dependencies: dependencies:
"@babel/plugin-proposal-private-property-in-object": "npm:^7.21.11" "@babel/plugin-proposal-private-property-in-object": "npm:^7.21.11"
"@babel/runtime": "npm:^7.26.10"
"@playwright/test": "npm:^1.50.1" "@playwright/test": "npm:^1.50.1"
"@reduxjs/toolkit": "npm:^1.9.7" "@reduxjs/toolkit": "npm:^1.9.7"
"@types/jest": "npm:^29.5.14" "@types/jest": "npm:^29.5.14"