Compare commits

...

18 Commits

Author SHA1 Message Date
Alex
bd89cfde79 Release v1.4.0 (#3333) 2024-05-06 17:58:31 -06:00
Anis Eleuch
0bd563b2e5 Fix a leak in WS object browser (#3325)
```
goroutine 7399330769 [chan send, 70126 minutes]:
github.com/minio/console/api.(*wsMinioClient).objectManager.func2.1()
        github.com/minio/console@v0.46.0/api/ws_objects.go:135 +0x6f0
created by github.com/minio/console/api.(*wsMinioClient).objectManager.func2 in goroutine 7354918912
        github.com/minio/console@v0.46.0/api/ws_objects.go:95 +0x45e
```
2024-05-06 15:12:31 -07:00
Alex
22fe915629 Changed default Replicate Existing Objects behavior in MinIO UI (#3271)
Changed default Replicate Existing Objects behavior in UI

- Fixed replicate existing objects configuration saving
- Displayed full error message if error case ocurrs.
- Changed wording for this feature & enabled by default this setting

Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
2024-05-06 16:02:27 -06:00
Alex
aa161a5365 Added VersionID support to Metadata Details (#3332)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
2024-05-06 14:38:53 -07:00
kcao
0557514cb4 fix: correct metric endpoint from minio_cluster_drive_free_inodes (#3296)
Fixes minio/console#3295
2024-05-06 03:56:08 -07:00
Alex
298203253c Updated UI dependencies (#3329)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
2024-05-03 17:32:11 -06:00
Cesar N
cbeef2b248 Fix URL safe string decoding for DownloadPublicObject API (#3328)
Co-authored-by: cesnietor <cesar.nieto@min.io>
2024-05-03 15:33:46 -07:00
Harshavardhana
e68a74ba48 fix: passing correct httpClient, do not use DefaultClients (#3319)
most of our deployments use custom certificates, using DefaultClient
makes it virtually impossible to make share URL feature work.

this PR fixes this behavior in the implementation.

Bonus: re-use transports inside console, will add more changes to
take custom transport inputs in subsequent PR.
2024-05-01 09:46:35 -07:00
Ramon de Klein
02a0db1408 Use React hook to better deal with websockets (#3299) 2024-05-01 03:42:49 -07:00
dependabot[bot]
348376c672 Bump ejs from 3.1.9 to 3.1.10 in /web-app (#3324)
Bumps [ejs](https://github.com/mde/ejs) from 3.1.9 to 3.1.10.
- [Release notes](https://github.com/mde/ejs/releases)
- [Commits](https://github.com/mde/ejs/compare/v3.1.9...v3.1.10)

---
updated-dependencies:
- dependency-name: ejs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-01 02:53:56 -07:00
Kaan Kabalak
037b02e268 Make permission tests compatible with minio-js v8 (#3323)
Fixes #3322
2024-05-01 02:45:09 -07:00
Kaan Kabalak
fe534ab4e6 Temporarily fix permission tests failing due to minio-js version bump (#3321)
Fix permission tests failing due to minio-js version bump

Permission tests were failing due to function signature changes
introduced with the latest minio-js release. This is a temporary
measure until a Console PR to update test files is sent.
2024-04-30 14:32:02 -06:00
Cesar N
6625d54d67 Release v1.3.0 (#3313) 2024-04-24 18:15:13 -07:00
Cesar N
ee6d1ed586 Upgrade superagent package to fix vulnerability (#3314) 2024-04-24 17:27:42 -07:00
Cesar N
6de1d88e11 Use url-safe base64 encoding for download-shared-object api (#3305) 2024-04-23 08:36:30 -07:00
jinapurapu
de19b6f17b Make prefix field optional for adding tier (#3301) 2024-04-18 23:51:13 -06:00
jinapurapu
226a90be1d Adds ExpireDeleteMarker status to bucketLifecycleRule UI display (#3302) 2024-04-18 18:36:00 -06:00
Prakash Senthil Vel
6cfb6ff06a add user agent in admin client to display console in audit logs (#3297) 2024-04-17 10:49:15 -06:00
70 changed files with 1879 additions and 3080 deletions

View File

@@ -1,166 +0,0 @@
# @format
name: Cross Compile
on:
pull_request:
branches:
- master
paths:
- go.sum
# This ensures that previous jobs for the PR are canceled when the PR is
# updated.
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref }}
cancel-in-progress: true
jobs:
cross-compile-1:
name: Cross compile
needs:
- lint-job
- ui-assets
- reuse-golang-dependencies
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
go-version: [ 1.21.x ]
os: [ ubuntu-latest ]
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
cache: true
id: go
- name: Build on ${{ matrix.os }}
env:
GO111MODULE: on
GOOS: linux
run: |
make crosscompile arg1="'linux/ppc64le linux/mips64'"
cross-compile-2:
name: Cross compile 2
needs:
- lint-job
- ui-assets
- reuse-golang-dependencies
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
go-version: [ 1.21.x ]
os: [ ubuntu-latest ]
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
cache: true
id: go
- name: Build on ${{ matrix.os }}
env:
GO111MODULE: on
GOOS: linux
run: |
make crosscompile arg1="'linux/arm64 linux/s390x'"
cross-compile-3:
name: Cross compile 3
needs:
- lint-job
- ui-assets
- reuse-golang-dependencies
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
go-version: [ 1.21.x ]
os: [ ubuntu-latest ]
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
cache: true
id: go
- name: Build on ${{ matrix.os }}
env:
GO111MODULE: on
GOOS: linux
run: |
make crosscompile arg1="'darwin/amd64 freebsd/amd64'"
cross-compile-4:
name: Cross compile 4
needs:
- lint-job
- ui-assets
- reuse-golang-dependencies
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
go-version: [ 1.21.x ]
os: [ ubuntu-latest ]
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
cache: true
id: go
- name: Build on ${{ matrix.os }}
env:
GO111MODULE: on
GOOS: linux
run: |
make crosscompile arg1="'windows/amd64 linux/arm'"
cross-compile-5:
name: Cross compile 5
needs:
- lint-job
- ui-assets
- reuse-golang-dependencies
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
go-version: [ 1.21.x ]
os: [ ubuntu-latest ]
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
cache: true
id: go
- name: Build on ${{ matrix.os }}
env:
GO111MODULE: on
GOOS: linux
run: |
make crosscompile arg1="'linux/386 netbsd/amd64'"

View File

@@ -105,28 +105,6 @@ jobs:
continue-on-error: false
run: |
./check-deadcode.sh
reuse-golang-dependencies:
name: reuse golang dependencies
runs-on: ubuntu-latest
strategy:
matrix:
go-version: [ 1.21.x ]
os: [ ubuntu-latest ]
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
cache: true
id: go
- name: Build on ${{ matrix.os }}
env:
GO111MODULE: on
GOOS: linux
run: |
go mod download
latest-minio:
name: Build latest MinIO
@@ -140,18 +118,10 @@ jobs:
uses: actions/checkout@v3
with:
repository: minio/minio
- uses: actions/cache@v3
id: minio-latest-cache
name: MinIO Latest Cache
with:
path: |
./minio
key: ${{ runner.os }}-minio-latest-${{ hashFiles('./go.sum') }}
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
cache: true
id: go-minio
- name: Build on ${{ matrix.os }}
if: steps.minio-latest-cache.outputs.cache-hit != 'true'
@@ -163,7 +133,6 @@ jobs:
needs:
- lint-job
- ui-assets
- reuse-golang-dependencies
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
@@ -239,7 +208,7 @@ jobs:
(CONSOLE_SUBPATH=/console/subpath ./console server ) & (make test-initialize-minio-nginx)
- name: Install TestCafe
run: npm install testcafe@3.0.0
run: npm install testcafe@3.5.0
- name: Run TestCafe Tests
run: npx testcafe "chrome:headless" web-app/tests/subpath-nginx/ -q --skip-js-errors -c 3
@@ -288,7 +257,7 @@ jobs:
(./console server) & (make initialize-permissions)
- name: Install TestCafe
run: npm install testcafe@3.0.0
run: npm install testcafe@3.5.0
- name: Run TestCafe Tests
run: npx testcafe "chrome:headless" web-app/tests/permissions-1/ -q --skip-js-errors -c 3
@@ -335,7 +304,7 @@ jobs:
(./console server) & (make initialize-permissions)
- name: Install TestCafe
run: npm install testcafe@3.0.0
run: npm install testcafe@3.5.0
- name: Run TestCafe Tests
run: npx testcafe "chrome:headless" web-app/tests/permissions-2/ -q --skip-js-errors -c 3
@@ -382,7 +351,7 @@ jobs:
(./console server) & (make initialize-permissions)
- name: Install TestCafe
run: npm install testcafe@3.0.0
run: npm install testcafe@3.5.0
- name: Run TestCafe Tests
run: npx testcafe "chrome:headless" web-app/tests/permissions-3/ -q --skip-js-errors -c 3
@@ -429,7 +398,7 @@ jobs:
(./console server) & (make initialize-permissions)
- name: Install TestCafe
run: npm install testcafe@3.0.0
run: npm install testcafe@3.5.0
- name: Run TestCafe Tests
timeout-minutes: 10
@@ -472,7 +441,7 @@ jobs:
(./console server) & (make initialize-permissions)
- name: Install TestCafe
run: npm install testcafe@3.0.0
run: npm install testcafe@3.5.0
- name: Run TestCafe Tests
timeout-minutes: 5
@@ -515,7 +484,7 @@ jobs:
(./console server) & (make initialize-permissions)
- name: Install TestCafe
run: npm install testcafe@3.0.0
run: npm install testcafe@3.5.0
- name: Run TestCafe Tests
timeout-minutes: 5
@@ -557,7 +526,7 @@ jobs:
run: |
(./console server) & (make initialize-permissions)
- name: Install TestCafe
run: npm install testcafe@3.0.0
run: npm install testcafe@3.5.0
- name: Run TestCafe Tests
timeout-minutes: 5
@@ -600,7 +569,7 @@ jobs:
(./console server) & (make initialize-permissions)
- name: Install TestCafe
run: npm install testcafe@3.0.0
run: npm install testcafe@3.5.0
- name: Run TestCafe Tests
timeout-minutes: 5
@@ -643,7 +612,7 @@ jobs:
(./console server) & (make initialize-permissions)
- name: Install TestCafe
run: npm install testcafe@3.0.0
run: npm install testcafe@3.5.0
- name: Run TestCafe Tests
run: npx testcafe "chrome:headless" web-app/tests/permissions-A/ --skip-js-errors -c 3
@@ -689,7 +658,7 @@ jobs:
(./console server) & (make initialize-permissions)
- name: Install TestCafe
run: npm install testcafe@3.0.0
run: npm install testcafe@3.5.0
- name: Run TestCafe Tests
run: npx testcafe "chrome:headless" web-app/tests/permissions-B/ --skip-js-errors -c 3
@@ -703,7 +672,6 @@ jobs:
needs:
- lint-job
- ui-assets
- reuse-golang-dependencies
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
@@ -740,7 +708,6 @@ jobs:
needs:
- lint-job
- ui-assets
- reuse-golang-dependencies
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
@@ -777,7 +744,6 @@ jobs:
needs:
- lint-job
- ui-assets
- reuse-golang-dependencies
- semgrep-static-code-analysis
- latest-minio
runs-on: ubuntu-latest
@@ -816,27 +782,23 @@ jobs:
VERSION=`git rev-parse HEAD`;
echo $VERSION;
echo "Create MinIO image";
if [ ! -f ../minio ]; then
echo "minio binary not found!, so compiling..."
make docker VERSION=$VERSION;
else
echo "Using binary from cache"
cp ../minio .
fi
make docker VERSION=$VERSION;
docker build -q --no-cache -t minio/minio:$VERSION . -f Dockerfile
echo "Jumping back to console repository to run the integration test"
cd $GITHUB_WORKSPACE;
echo "We are going to use the built image on test-integration";
VERSION="minio/minio:$VERSION";
echo $VERSION;
MINIO_VERSION="minio/minio:$VERSION";
echo $MINIO_VERSION;
echo "Create bucket for replication with versioning"
echo "Download mc for Ubuntu"
wget -q https://dl.min.io/client/mc/release/linux-amd64/mc
echo "Change the permissions to execute mc command"
chmod +x mc
echo "Create the folder to put the all.out file"
make test-integration MINIO_VERSION=$VERSION;
make test-integration MINIO_VERSION=$MINIO_VERSION;
- uses: actions/cache@v3
id: coverage-cache
@@ -850,7 +812,6 @@ jobs:
needs:
- lint-job
- ui-assets
- reuse-golang-dependencies
- semgrep-static-code-analysis
runs-on: ubuntu-latest
steps:
@@ -866,7 +827,6 @@ jobs:
needs:
- lint-job
- ui-assets
- reuse-golang-dependencies
- semgrep-static-code-analysis
- latest-minio
runs-on: [ ubuntu-latest ]
@@ -907,20 +867,17 @@ jobs:
VERSION=`git rev-parse HEAD`;
echo $VERSION;
echo "Create MinIO image";
if [ ! -f ../minio ]; then
echo "minio binary not found!, so compiling..."
make docker VERSION=$VERSION;
else
echo "Using binary from cache"
cp ../minio .
fi
make docker VERSION=$VERSION;
docker build -q --no-cache -t minio/minio:$VERSION . -f Dockerfile
echo "Jumping back to console repository to run the integration test"
cd $GITHUB_WORKSPACE;
echo "We are going to use the built image on test-integration";
VERSION="minio/minio:$VERSION";
echo $VERSION;
make test-replication MINIO_VERSION=$VERSION;
MINIO_VERSION="minio/minio:$VERSION";
echo $MINIO_VERSION;
make test-replication MINIO_VERSION=$MINIO_VERSION;
- uses: actions/cache@v3
id: coverage-cache-replication
name: Coverage Cache Replication
@@ -941,7 +898,6 @@ jobs:
needs:
- lint-job
- ui-assets
- reuse-golang-dependencies
- semgrep-static-code-analysis
- latest-minio
runs-on: ubuntu-latest
@@ -981,26 +937,23 @@ jobs:
echo "replace github.com/minio/console => ../" >> go.mod
echo "updates to go.mod needed; to update it: go mod tidy"
go mod tidy -compat=1.19
go mod tidy -compat=1.21
echo "Get git version to build MinIO Image";
VERSION=`git rev-parse HEAD`;
echo $VERSION;
echo "Create MinIO image";
if [ ! -f ../minio ]; then
echo "minio binary not found!, so compiling..."
make docker VERSION=$VERSION;
else
echo "Using binary from cache"
cp ../minio .
fi
make docker VERSION=$VERSION;
docker build -q --no-cache -t minio/minio:$VERSION . -f Dockerfile
echo "Jumping back to console repository to run the integration test"
cd $GITHUB_WORKSPACE;
echo "We are going to use the built image on test-integration";
VERSION="minio/minio:$VERSION";
echo $VERSION;
make test-sso-integration MINIO_VERSION=$VERSION;
MINIO_VERSION="minio/minio:$VERSION";
echo $MINIO_VERSION;
make test-sso-integration MINIO_VERSION=$MINIO_VERSION;
- uses: actions/cache@v3
id: coverage-cache-sso
name: Coverage Cache SSO
@@ -1089,7 +1042,7 @@ jobs:
echo "download golang x tools"
go mod download golang.org/x/tools
echo "go mod tidy compat mode"
go mod tidy -compat=1.19
go mod tidy -compat=1.21
echo "go build gocoverage.go"
go build gocovmerge.go
echo "put together the outs for final coverage resolution"
@@ -1201,7 +1154,6 @@ jobs:
needs:
- lint-job
- ui-assets-istanbul-coverage
- reuse-golang-dependencies
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
@@ -1238,6 +1190,150 @@ jobs:
run: |
make console
cross-compile-1:
name: Cross compile
needs:
- lint-job
- ui-assets
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
go-version: [ 1.21.x ]
os: [ ubuntu-latest ]
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
cache: true
id: go
- name: Build on ${{ matrix.os }}
env:
GO111MODULE: on
GOOS: linux
run: |
make crosscompile arg1="'linux/ppc64le linux/mips64'"
cross-compile-2:
name: Cross compile 2
needs:
- lint-job
- ui-assets
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
go-version: [ 1.21.x ]
os: [ ubuntu-latest ]
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
cache: true
id: go
- name: Build on ${{ matrix.os }}
env:
GO111MODULE: on
GOOS: linux
run: |
make crosscompile arg1="'linux/arm64 linux/s390x'"
cross-compile-3:
name: Cross compile 3
needs:
- lint-job
- ui-assets
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
go-version: [ 1.21.x ]
os: [ ubuntu-latest ]
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
cache: true
id: go
- name: Build on ${{ matrix.os }}
env:
GO111MODULE: on
GOOS: linux
run: |
make crosscompile arg1="'darwin/amd64 freebsd/amd64'"
cross-compile-4:
name: Cross compile 4
needs:
- lint-job
- ui-assets
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
go-version: [ 1.21.x ]
os: [ ubuntu-latest ]
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
cache: true
id: go
- name: Build on ${{ matrix.os }}
env:
GO111MODULE: on
GOOS: linux
run: |
make crosscompile arg1="'windows/amd64 linux/arm'"
cross-compile-5:
name: Cross compile 5
needs:
- lint-job
- ui-assets
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
go-version: [ 1.21.x ]
os: [ ubuntu-latest ]
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
cache: true
id: go
- name: Build on ${{ matrix.os }}
env:
GO111MODULE: on
GOOS: linux
run: |
make crosscompile arg1="'linux/386 netbsd/amd64'"
playwright:
needs:
- compile-binary-istanbul-coverage

View File

@@ -2,6 +2,33 @@
# Changelog
## Release v1.4.0
Features:
- Added VersionID support to metadata details
- Improved Websockets handlers
Bug Fix:
- Fixed vulnerabilities and updated dependencies
- Fixed an issue with Download URL decoding
- Fixed leak in Object Browser Websocket
- Minor UX fixes
## Release v1.3.0
Features:
- Adds ExpireDeleteMarker status to BucketLifecycleRule UI
Bug Fix:
- Fixed vulnerability
- Used URL-safe base64 enconding for Share API
- Made Prefix field optional when Adding Tier
- Added Console user agent in MinIO Admin Client
## Release v1.2.0
Features:
@@ -64,7 +91,7 @@ Deprecated:
Features:
- Updated tines on menus & pages
- Updated tines on menus & pages
Bug Fix:

1646
CREDITS

File diff suppressed because it is too large Load Diff

View File

@@ -775,7 +775,7 @@ var widgets = []Metric{
},
Targets: []Target{
{
Expr: `minio_cluster_drive_free_inodes{$__query}`,
Expr: `minio_node_drive_free_inodes{$__query}`,
LegendFormat: "Free Inodes [{{server}}:{{drive}}]",
},
},
@@ -994,8 +994,6 @@ func unmarshalPrometheus(ctx context.Context, httpClnt *http.Client, endpoint st
}
func testPrometheusURL(ctx context.Context, url string) bool {
clientIP := utils.ClientIPFromContext(ctx)
httpClnt := GetConsoleHTTPClient(url, clientIP)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url+"/-/healthy", nil)
if err != nil {
ErrorWithContext(ctx, fmt.Errorf("error Building Request: (%v)", err))
@@ -1003,11 +1001,13 @@ func testPrometheusURL(ctx context.Context, url string) bool {
}
prometheusBearer := getPrometheusAuthToken()
if prometheusBearer != "" {
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", prometheusBearer))
}
clientIP := utils.ClientIPFromContext(ctx)
httpClnt := GetConsoleHTTPClient(clientIP)
response, err := httpClnt.Do(req)
if err != nil {
ErrorWithContext(ctx, fmt.Errorf("default Prometheus URL not reachable, trying root testing: (%v)", err))
@@ -1050,7 +1050,7 @@ func getWidgetDetails(ctx context.Context, prometheusURL string, selector string
return nil, ErrorWithContext(ctx, errors.New("prometheus URL is unreachable"))
}
clientIP := utils.ClientIPFromContext(ctx)
httpClnt := GetConsoleHTTPClient(prometheusURL, clientIP)
httpClnt := GetConsoleHTTPClient(clientIP)
labelResultsCh := make(chan LabelResults)

View File

@@ -97,7 +97,7 @@ func getReleases(endpoint, repo, currentRelease, search, filter, clientIP string
req.URL.RawQuery = q.Encode()
req.Header.Set("Content-Type", "application/json")
client := GetConsoleHTTPClient("", clientIP)
client := GetConsoleHTTPClient(clientIP)
client.Timeout = time.Second * 5
resp, err := client.Do(req)

View File

@@ -292,7 +292,7 @@ func addRemoteBucket(ctx context.Context, client MinioAdmin, params models.Creat
return bucketARN, err
}
func addBucketReplicationItem(ctx context.Context, session *models.Principal, minClient minioClient, bucketName, prefix, destinationARN string, repDelMark, repDels, repMeta bool, tags string, priority int32, storageClass string) error {
func addBucketReplicationItem(ctx context.Context, session *models.Principal, minClient minioClient, bucketName, prefix, destinationARN string, repExistingObj, repDelMark, repDels, repMeta bool, tags string, priority int32, storageClass string) error {
// we will tolerate this call failing
cfg, err := minClient.getBucketReplication(ctx, bucketName)
if err != nil {
@@ -337,13 +337,18 @@ func addBucketReplicationItem(ctx context.Context, session *models.Principal, mi
repMetaStatus = "enable"
}
existingRepStatus := "disable"
if repExistingObj {
existingRepStatus = "enable"
}
opts := replication.Options{
Priority: fmt.Sprintf("%d", maxPrio),
RuleStatus: "enable",
DestBucket: destinationARN,
Op: replication.AddOption,
TagString: tags,
ExistingObjectReplicate: "enable", // enabled by default
ExistingObjectReplicate: existingRepStatus,
ReplicateDeleteMarkers: repDelMarkStatus,
ReplicateDeletes: repDelsStatus,
ReplicaSync: repMetaStatus,
@@ -459,6 +464,7 @@ func setMultiBucketReplication(ctx context.Context, session *models.Principal, c
sourceBucket,
params.Body.Prefix,
arn,
params.Body.ReplicateExistingObjects,
params.Body.ReplicateDeleteMarkers,
params.Body.ReplicateDeletes,
params.Body.ReplicateMetadata,

View File

@@ -96,7 +96,7 @@ func SubnetRegisterWithAPIKey(ctx context.Context, minioClient MinioAdmin, apiKe
return false, err
}
clientIP := utils.ClientIPFromContext(ctx)
registerResult, err := subnet.Register(GetConsoleHTTPClient("", clientIP), serverInfo, apiKey, "", "")
registerResult, err := subnet.Register(GetConsoleHTTPClient(clientIP), serverInfo, apiKey, "", "")
if err != nil {
return false, err
}
@@ -199,7 +199,6 @@ func SubnetLoginWithMFA(client xhttp.ClientI, username, mfaToken, otp string) (*
// GetSubnetHTTPClient will return a client with proxy if configured, otherwise will return the default console http client
func GetSubnetHTTPClient(ctx context.Context, minioClient MinioAdmin) (*xhttp.Client, error) {
clientIP := utils.ClientIPFromContext(ctx)
subnetHTTPClient := GetConsoleHTTPClient("", clientIP)
subnetKey, err := GetSubnetKeyFromMinIOConfig(ctx, minioClient)
if err != nil {
return nil, err
@@ -209,18 +208,24 @@ func GetSubnetHTTPClient(ctx context.Context, minioClient MinioAdmin) (*xhttp.Cl
if subnetKey.Proxy != "" {
proxy = subnetKey.Proxy
}
tr := GlobalTransport.Clone()
if proxy != "" {
subnetProxyURL, err := url.Parse(proxy)
u, err := url.Parse(proxy)
if err != nil {
return nil, err
}
subnetHTTPClient.Transport.(*ConsoleTransport).Transport.Proxy = http.ProxyURL(subnetProxyURL)
tr.Proxy = http.ProxyURL(u)
}
clientI := &xhttp.Client{
Client: subnetHTTPClient,
}
return clientI, nil
return &xhttp.Client{
Client: &http.Client{
Transport: &ConsoleTransport{
Transport: tr,
ClientIP: clientIP,
},
},
}, nil
}
func GetSubnetLoginWithMFAResponse(session *models.Principal, params subnetApi.SubnetLoginMFAParams) (*models.SubnetLoginResponse, *CodedAPIError) {
@@ -322,7 +327,7 @@ func GetSubnetInfoResponse(session *models.Principal, params subnetApi.SubnetInf
defer cancel()
clientIP := utils.ClientIPFromContext(ctx)
client := &xhttp.Client{
Client: GetConsoleHTTPClient("", clientIP),
Client: GetConsoleHTTPClient(clientIP),
}
// license gets seeded to us by MinIO
seededLicense := os.Getenv(EnvSubnetLicense)

View File

@@ -24,9 +24,12 @@ import (
"net"
"net/http"
"net/url"
"regexp"
"strings"
"time"
"github.com/minio/console/pkg"
"github.com/minio/console/pkg/utils"
"github.com/minio/console/models"
@@ -211,11 +214,11 @@ func (ac AdminClient) listPolicies(ctx context.Context) (map[string]*iampolicy.P
// implements madmin.ListCannedPolicies()
func (ac AdminClient) getPolicy(ctx context.Context, name string) (*iampolicy.Policy, error) {
praw, err := ac.Client.InfoCannedPolicy(ctx, name)
info, err := ac.Client.InfoCannedPolicyV2(ctx, name)
if err != nil {
return nil, err
}
return iampolicy.ParseConfig(bytes.NewReader(praw))
return iampolicy.ParseConfig(bytes.NewReader(info.Policy))
}
// implements madmin.RemoveCannedPolicy()
@@ -234,6 +237,7 @@ func (ac AdminClient) addPolicy(ctx context.Context, name string, policy *iampol
// 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)
}
@@ -449,6 +453,7 @@ func NewMinioAdminClient(ctx context.Context, sessionClaims *models.Principal) (
if err != nil {
return nil, err
}
adminClient.SetAppInfo(globalAppName, pkg.Version)
return adminClient, nil
}
@@ -464,7 +469,8 @@ func newAdminFromClaims(claims *models.Principal, clientIP string) (*madmin.Admi
if err != nil {
return nil, err
}
adminClient.SetCustomTransport(GetConsoleHTTPClient(getMinIOServer(), clientIP).Transport)
adminClient.SetAppInfo(globalAppName, pkg.Version)
adminClient.SetCustomTransport(PrepareSTSClientTransport(clientIP))
return adminClient, nil
}
@@ -477,14 +483,14 @@ func newAdminFromCreds(accessKey, secretKey, endpoint string, tlsEnabled bool) (
if err != nil {
return nil, err
}
minioClient.SetAppInfo(globalAppName, pkg.Version)
return minioClient, nil
}
// isLocalAddress returns true if the url contains an IPv4/IPv6 hostname
// that points to the local machine - FQDN are not supported
func isLocalIPEndpoint(addr string) bool {
u, err := url.Parse(addr)
func isLocalIPEndpoint(endpoint string) bool {
u, err := url.Parse(endpoint)
if err != nil {
return false
}
@@ -497,6 +503,9 @@ func isLocalIPAddress(ipAddr string) bool {
if ipAddr == "" {
return false
}
if ipAddr == "localhost" {
return true
}
ip := net.ParseIP(ipAddr)
return ip != nil && ip.IsLoopback()
}
@@ -504,43 +513,75 @@ func isLocalIPAddress(ipAddr string) bool {
// GetConsoleHTTPClient caches different http clients depending on the target endpoint while taking
// in consideration CA certs stored in ${HOME}/.console/certs/CAs and ${HOME}/.minio/certs/CAs
// If the target endpoint points to a loopback device, skip the TLS verification.
func GetConsoleHTTPClient(address string, clientIP string) *http.Client {
u, err := url.Parse(address)
if err == nil {
address = u.Hostname()
}
client := PrepareConsoleHTTPClient(isLocalIPAddress(address), clientIP)
return client
func GetConsoleHTTPClient(clientIP string) *http.Client {
return PrepareConsoleHTTPClient(clientIP)
}
func getClientIP(r *http.Request) string {
// Try to get the IP address from the X-Real-IP header
// If the X-Real-IP header is not present, then it will return an empty string
xRealIP := r.Header.Get("X-Real-IP")
if xRealIP != "" {
return xRealIP
}
var (
// De-facto standard header keys.
xForwardedFor = http.CanonicalHeaderKey("X-Forwarded-For")
xRealIP = http.CanonicalHeaderKey("X-Real-IP")
)
// Try to get the IP address from the X-Forwarded-For header
// If the X-Forwarded-For header is not present, then it will return an empty string
xForwardedFor := r.Header.Get("X-Forwarded-For")
if xForwardedFor != "" {
// X-Forwarded-For can contain multiple addresses, we return the first one
split := strings.Split(xForwardedFor, ",")
if len(split) > 0 {
return strings.TrimSpace(split[0])
var (
// RFC7239 defines a new "Forwarded: " header designed to replace the
// existing use of X-Forwarded-* headers.
// e.g. Forwarded: for=192.0.2.60;proto=https;by=203.0.113.43
forwarded = http.CanonicalHeaderKey("Forwarded")
// Allows for a sub-match of the first value after 'for=' to the next
// comma, semi-colon or space. The match is case-insensitive.
forRegex = regexp.MustCompile(`(?i)(?:for=)([^(;|,| )]+)(.*)`)
)
// getSourceIPFromHeaders retrieves the IP from the X-Forwarded-For, X-Real-IP
// and RFC7239 Forwarded headers (in that order)
func getSourceIPFromHeaders(r *http.Request) string {
var addr string
if fwd := r.Header.Get(xForwardedFor); fwd != "" {
// Only grab the first (client) address. Note that '192.168.0.1,
// 10.1.1.1' is a valid key for X-Forwarded-For where addresses after
// the first may represent forwarding proxies earlier in the chain.
s := strings.Index(fwd, ", ")
if s == -1 {
s = len(fwd)
}
addr = fwd[:s]
} else if fwd := r.Header.Get(xRealIP); fwd != "" {
// X-Real-IP should only contain one IP address (the client making the
// request).
addr = fwd
} else if fwd := r.Header.Get(forwarded); fwd != "" {
// match should contain at least two elements if the protocol was
// specified in the Forwarded header. The first element will always be
// the 'for=' capture, which we ignore. In the case of multiple IP
// addresses (for=8.8.8.8, 8.8.4.4, 172.16.1.20 is valid) we only
// extract the first, which should be the client IP.
if match := forRegex.FindStringSubmatch(fwd); len(match) > 1 {
// IPv6 addresses in Forwarded headers are quoted-strings. We strip
// these quotes.
addr = strings.Trim(match[1], `"`)
}
}
// If neither header is present (or they were empty), then fall back to the connection's remote address
ip, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
// In case there's an error, return an empty string
return ""
return addr
}
// getClientIP retrieves the IP from the request headers
// and falls back to r.RemoteAddr when necessary.
// however returns without bracketing.
func getClientIP(r *http.Request) string {
addr := getSourceIPFromHeaders(r)
if addr == "" {
addr = r.RemoteAddr
}
return ip
// Default to remote address if headers not set.
raddr, _, _ := net.SplitHostPort(addr)
if raddr == "" {
return addr
}
return raddr
}
func (ac AdminClient) speedtest(ctx context.Context, opts madmin.SpeedtestOpts) (chan madmin.SpeedTestResult, error) {

View File

@@ -341,7 +341,7 @@ func stsCredentials(minioURL, accessKey, secretKey, location, clientIP string) (
DurationSeconds: int(xjwt.GetConsoleSTSDuration().Seconds()),
}
stsAssumeRole := &credentials.STSAssumeRole{
Client: GetConsoleHTTPClient(minioURL, clientIP),
Client: GetConsoleHTTPClient(clientIP),
STSEndpoint: minioURL,
Options: opts,
}
@@ -357,7 +357,7 @@ func NewConsoleCredentials(accessKey, secretKey, location, clientIP string) (*cr
// LDAP authentication for Console
case ldap.GetLDAPEnabled():
{
creds, err := auth.GetCredentialsFromLDAP(GetConsoleHTTPClient(minioURL, clientIP), minioURL, accessKey, secretKey)
creds, err := auth.GetCredentialsFromLDAP(GetConsoleHTTPClient(clientIP), minioURL, accessKey, secretKey)
if err != nil {
return nil, err
}
@@ -414,7 +414,7 @@ func newMinioClient(claims *models.Principal, clientIP string) (*minio.Client, e
minioClient, err := minio.New(endpoint, &minio.Options{
Creds: creds,
Secure: secure,
Transport: GetConsoleHTTPClient(getMinIOServer(), clientIP).Transport,
Transport: GetConsoleHTTPClient(clientIP).Transport,
})
if err != nil {
return nil, err
@@ -426,10 +426,9 @@ func newMinioClient(claims *models.Principal, clientIP string) (*minio.Client, e
// computeObjectURLWithoutEncode returns a MinIO url containing the object filename without encoding
func computeObjectURLWithoutEncode(bucketName, prefix string) (string, error) {
endpoint := getMinIOServer()
u, err := xnet.ParseHTTPURL(endpoint)
u, err := xnet.ParseHTTPURL(getMinIOServer())
if err != nil {
return "", fmt.Errorf("the provided endpoint is invalid")
return "", fmt.Errorf("the provided endpoint: '%s' is invalid", getMinIOServer())
}
var p string
if strings.TrimSpace(bucketName) != "" {
@@ -438,7 +437,7 @@ func computeObjectURLWithoutEncode(bucketName, prefix string) (string, error) {
if strings.TrimSpace(prefix) != "" {
p = pathJoinFinalSlash(p, prefix)
}
return fmt.Sprintf("%s://%s/%s", u.Scheme, u.Host, p), nil
return u.String() + "/" + p, nil
}
// newS3BucketClient creates a new mc S3Client to talk to the server based on a bucket
@@ -479,22 +478,18 @@ func pathJoinFinalSlash(elem ...string) string {
func newS3Config(endpoint, accessKey, secretKey, sessionToken string, clientIP string) *mc.Config {
// We have a valid alias and hostConfig. We populate the/
// consoleCredentials from the match found in the config file.
s3Config := new(mc.Config)
s3Config.AppName = globalAppName
s3Config.AppVersion = pkg.Version
s3Config.Debug = false
s3Config.HostURL = endpoint
s3Config.AccessKey = accessKey
s3Config.SecretKey = secretKey
s3Config.SessionToken = sessionToken
s3Config.Signature = "S3v4"
insecure := isLocalIPEndpoint(endpoint)
s3Config.Insecure = insecure
s3Config.Transport = PrepareSTSClientTransport(insecure, clientIP).Transport
return s3Config
return &mc.Config{
HostURL: endpoint,
AccessKey: accessKey,
SecretKey: secretKey,
SessionToken: sessionToken,
Signature: "S3v4",
AppName: globalAppName,
AppVersion: pkg.Version,
Insecure: isLocalIPEndpoint(endpoint),
Transport: &ConsoleTransport{
ClientIP: clientIP,
Transport: GlobalTransport,
},
}
}

View File

@@ -1,5 +1,5 @@
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
// Copyright (c) 2024 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
@@ -80,10 +80,11 @@ func Test_computeObjectURLWithoutEncode(t *testing.T) {
got, err := computeObjectURLWithoutEncode(tt.args.bucketName, tt.args.prefix)
if (err != nil) != tt.wantErr {
t.Errorf("computeObjectURLWithoutEncode() errors = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("computeObjectURLWithoutEncode() got = %v, want %v", got, tt.want)
if err == nil {
if got != tt.want {
t.Errorf("computeObjectURLWithoutEncode() got = %v, want %v", got, tt.want)
}
}
})
}

View File

@@ -17,10 +17,13 @@
package api
import (
"crypto/tls"
"crypto/x509"
"net"
"net/http"
"strconv"
"strings"
"time"
"github.com/minio/console/pkg/auth/idp/oauth2"
xcerts "github.com/minio/pkg/v2/certs"
@@ -54,6 +57,31 @@ var (
GlobalPublicCerts []*x509.Certificate
// GlobalTLSCertsManager custom TLS Manager for SNI support
GlobalTLSCertsManager *xcerts.Manager
// GlobalTransport is common transport used for all HTTP calls, this is set via
// MinIO server to be the correct transport, however we still define some defaults
// here just in case.
GlobalTransport = &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 10 * time.Second,
KeepAlive: 15 * time.Second,
}).DialContext,
MaxIdleConns: 1024,
MaxIdleConnsPerHost: 1024,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 10 * time.Second,
DisableCompression: true, // Set to avoid auto-decompression
TLSClientConfig: &tls.Config{
// Can't use SSLv3 because of POODLE and BEAST
// Can't use TLSv1.0 because of POODLE and BEAST using CBC cipher
// Can't use TLSv1.1 because of RC4 cipher usage
MinVersion: tls.VersionTLS12,
// Console runs in the same pod/node as MinIO this is acceptable.
InsecureSkipVerify: true,
RootCAs: GlobalRootCAs,
},
}
)
// MinIOConfig represents application configuration passed in from the MinIO

View File

@@ -1762,6 +1762,11 @@ func init() {
"name": "prefix",
"in": "query",
"required": true
},
{
"type": "string",
"name": "versionID",
"in": "query"
}
],
"responses": {
@@ -7225,6 +7230,9 @@ func init() {
"replicateDeletes": {
"type": "boolean"
},
"replicateExistingObjects": {
"type": "boolean"
},
"replicateMetadata": {
"type": "boolean"
},
@@ -10974,6 +10982,11 @@ func init() {
"name": "prefix",
"in": "query",
"required": true
},
{
"type": "string",
"name": "versionID",
"in": "query"
}
],
"responses": {
@@ -16626,6 +16639,9 @@ func init() {
"replicateDeletes": {
"type": "boolean"
},
"replicateExistingObjects": {
"type": "boolean"
},
"replicateMetadata": {
"type": "boolean"
},

View File

@@ -55,7 +55,7 @@ func getLicenseInfo(client http.Client, license string) (*licverifier.LicenseInf
}
func fetchLicensePlan() {
client := GetConsoleHTTPClient("", "127.0.0.1")
client := GetConsoleHTTPClient("127.0.0.1")
licenseInfo, err := getLicenseInfo(*client, os.Getenv(EnvSubnetLicense))
if err != nil {
return

View File

@@ -59,6 +59,10 @@ type GetObjectMetadataParams struct {
In: query
*/
Prefix string
/*
In: query
*/
VersionID *string
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
@@ -81,6 +85,11 @@ func (o *GetObjectMetadataParams) BindRequest(r *http.Request, route *middleware
if err := o.bindPrefix(qPrefix, qhkPrefix, route.Formats); err != nil {
res = append(res, err)
}
qVersionID, qhkVersionID, _ := qs.GetOK("versionID")
if err := o.bindVersionID(qVersionID, qhkVersionID, route.Formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
@@ -121,3 +130,21 @@ func (o *GetObjectMetadataParams) bindPrefix(rawData []string, hasKey bool, form
return nil
}
// bindVersionID binds and validates parameter VersionID from query.
func (o *GetObjectMetadataParams) bindVersionID(rawData []string, hasKey bool, formats strfmt.Registry) error {
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: false
// AllowEmptyValue: false
if raw == "" { // empty values pass all other validations
return nil
}
o.VersionID = &raw
return nil
}

View File

@@ -33,7 +33,8 @@ import (
type GetObjectMetadataURL struct {
BucketName string
Prefix string
Prefix string
VersionID *string
_basePath string
// avoid unkeyed usage
@@ -81,6 +82,14 @@ func (o *GetObjectMetadataURL) Build() (*url.URL, error) {
qs.Set("prefix", prefixQ)
}
var versionIDQ string
if o.VersionID != nil {
versionIDQ = *o.VersionID
}
if versionIDQ != "" {
qs.Set("versionID", versionIDQ)
}
_result.RawQuery = qs.Encode()
return &_result, nil

View File

@@ -57,7 +57,9 @@ func getDownloadPublicObjectResponse(params public.DownloadSharedObjectParams) (
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
resp, err := http.DefaultClient.Do(req)
clnt := PrepareConsoleHTTPClient(getClientIP(params.HTTPRequest))
resp, err := clnt.Do(req)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
@@ -91,7 +93,7 @@ func getDownloadPublicObjectResponse(params public.DownloadSharedObjectParams) (
// b64toMinIOStringURL decodes url and validates is a MinIO url endpoint
func b64toMinIOStringURL(inputEncodedURL string) (*string, error) {
inputURLDecoded, err := b64.StdEncoding.DecodeString(inputEncodedURL)
inputURLDecoded, err := b64.URLEncoding.DecodeString(inputEncodedURL)
if err != nil {
return nil, err
}

View File

@@ -76,6 +76,14 @@ func Test_b64toMinIOStringURL(t *testing.T) {
wantError: swag.String("unexpected scheme found "),
expected: nil,
},
{
test: "encoded url is url safe decoded",
args: args{
encodedURL: "aHR0cHM6Ly9sb2NhbGhvc3Q6OTAwMC9jZXN0ZXN0L0F1ZGlvJTIwaWNvbi5zdmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTY=",
},
wantError: nil,
expected: swag.String("https://localhost:9000/cestest/Audio%20icon.svg?X-Amz-Algorithm=AWS4-HMAC-SHA256"),
},
}
for _, tt := range tests {
@@ -84,16 +92,16 @@ func Test_b64toMinIOStringURL(t *testing.T) {
if tt.wantError != nil {
if err != nil {
if err.Error() != *tt.wantError {
t.Errorf("b64toMinIOStringURL() error: `%v`, wantErr: `%s`", err, *tt.wantError)
t.Errorf("b64toMinIOStringURL() error: `%v`, wantErr: `%s`, input: `%s`", err, *tt.wantError, tt.args.encodedURL)
return
}
} else {
t.Errorf("b64toMinIOStringURL() error: `%v`, wantErr: `%s`", err, *tt.wantError)
t.Errorf("b64toMinIOStringURL() error: `%v`, wantErr: `%s`, input: `%s`", err, *tt.wantError, tt.args.encodedURL)
return
}
} else {
if err != nil {
t.Errorf("b64toMinIOStringURL() error: `%s`, wantErr: `%v`", err, tt.wantError)
t.Errorf("b64toMinIOStringURL() error: `%s`, wantErr: `%v`, input: `%s`", err, tt.wantError, tt.args.encodedURL)
return
}
tAssert.Equal(*tt.expected, *url)

View File

@@ -153,14 +153,15 @@ func getCreateServiceAccountResponse(session *models.Principal, params saApi.Cre
// defining the client to be used
userAdminClient := AdminClient{Client: userAdmin}
var parsedExpiry time.Time
var expiry *time.Time
if params.Body.Expiry != "" {
parsedExpiry, err = time.Parse(time.RFC3339, params.Body.Expiry)
parsedExpiry, err := time.Parse(time.RFC3339, params.Body.Expiry)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
expiry = &parsedExpiry
}
saCreds, err := createServiceAccount(ctx, userAdminClient, params.Body.Policy, params.Body.Name, params.Body.Description, &parsedExpiry, params.Body.Comment)
saCreds, err := createServiceAccount(ctx, userAdminClient, params.Body.Policy, params.Body.Name, params.Body.Description, expiry, params.Body.Comment)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
@@ -203,14 +204,15 @@ func getCreateAUserServiceAccountResponse(session *models.Principal, params user
return nil, ErrorWithContext(ctx, err)
}
var parsedExpiry time.Time
var expiry *time.Time
if params.Body.Expiry != "" {
parsedExpiry, err = time.Parse(time.RFC3339, params.Body.Expiry)
parsedExpiry, err := time.Parse(time.RFC3339, params.Body.Expiry)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
expiry = &parsedExpiry
}
saCreds, err := createAUserServiceAccount(ctx, userAdminClient, params.Body.Policy, name, params.Body.Name, params.Body.Description, &parsedExpiry, params.Body.Comment)
saCreds, err := createAUserServiceAccount(ctx, userAdminClient, params.Body.Policy, name, params.Body.Name, params.Body.Description, expiry, params.Body.Comment)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
@@ -248,14 +250,15 @@ func getCreateAUserServiceAccountCredsResponse(session *models.Principal, params
}
}
var parsedExpiry time.Time
var expiry *time.Time
if serviceAccount.Expiry != "" {
parsedExpiry, err = time.Parse(time.RFC3339, serviceAccount.Expiry)
parsedExpiry, err := time.Parse(time.RFC3339, serviceAccount.Expiry)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
expiry = &parsedExpiry
}
saCreds, err := createAUserServiceAccountCreds(ctx, userAdminClient, serviceAccount.Policy, user, serviceAccount.AccessKey, serviceAccount.SecretKey, serviceAccount.Name, serviceAccount.Description, &parsedExpiry, serviceAccount.Comment)
saCreds, err := createAUserServiceAccountCreds(ctx, userAdminClient, serviceAccount.Policy, user, serviceAccount.AccessKey, serviceAccount.SecretKey, serviceAccount.Name, serviceAccount.Description, expiry, serviceAccount.Comment)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
@@ -289,15 +292,16 @@ func getCreateServiceAccountCredsResponse(session *models.Principal, params saAp
}
}
var parsedExpiry time.Time
var expiry *time.Time
if params.Body.Expiry != "" {
parsedExpiry, err = time.Parse(time.RFC3339, params.Body.Expiry)
parsedExpiry, err := time.Parse(time.RFC3339, params.Body.Expiry)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
expiry = &parsedExpiry
}
saCreds, err := createServiceAccountCreds(ctx, userAdminClient, serviceAccount.Policy, serviceAccount.AccessKey, serviceAccount.SecretKey, params.Body.Name, params.Body.Description, &parsedExpiry, params.Body.Comment)
saCreds, err := createServiceAccountCreds(ctx, userAdminClient, serviceAccount.Policy, serviceAccount.AccessKey, serviceAccount.SecretKey, params.Body.Name, params.Body.Description, expiry, params.Body.Comment)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
@@ -313,6 +317,25 @@ func getUserServiceAccounts(ctx context.Context, userClient MinioAdmin, user str
saList := models.ServiceAccounts{}
for _, acc := range listServAccs.Accounts {
if acc.AccountStatus != "" {
// Newer releases of MinIO would support enhanced listServiceAccounts()
// we can avoid infoServiceAccount() at that point, this scales well
// for 100's of service accounts.
expiry := ""
if acc.Expiration != nil {
expiry = acc.Expiration.Format(time.RFC3339)
}
saList = append(saList, &models.ServiceAccountsItems0{
AccountStatus: acc.AccountStatus,
Description: acc.Description,
Expiration: expiry,
Name: acc.Name,
AccessKey: acc.AccessKey,
})
continue
}
aInfo, err := userClient.infoServiceAccount(ctx, acc.AccessKey)
if err != nil {
continue
@@ -439,14 +462,14 @@ func getServiceAccountInfo(session *models.Principal, params saApi.GetServiceAcc
}
// setServiceAccountPolicy sets policy for a service account
func updateServiceAccountDetails(ctx context.Context, userClient MinioAdmin, accessKey string, policy string, expiry time.Time, name string, description string, status string, secretKey string) error {
func updateServiceAccountDetails(ctx context.Context, userClient MinioAdmin, accessKey string, policy string, expiry *time.Time, name string, description string, status string, secretKey string) error {
req := madmin.UpdateServiceAccountReq{
NewPolicy: json.RawMessage(policy),
NewSecretKey: secretKey,
NewStatus: status,
NewName: name,
NewDescription: description,
NewExpiration: &expiry,
NewExpiration: expiry,
}
err := userClient.updateServiceAccount(ctx, accessKey, req)
@@ -471,14 +494,15 @@ func updateSetServiceAccountResponse(session *models.Principal, params saApi.Upd
// defining the client to be used
userAdminClient := AdminClient{Client: userAdmin}
var parsedExpiry time.Time
var expiry *time.Time
if params.Body.Expiry != "" {
parsedExpiry, err = time.Parse(time.RFC3339, params.Body.Expiry)
parsedExpiry, err := time.Parse(time.RFC3339, params.Body.Expiry)
if err != nil {
return ErrorWithContext(ctx, err)
}
expiry = &parsedExpiry
}
err = updateServiceAccountDetails(ctx, userAdminClient, accessKey, policy, parsedExpiry, params.Body.Name, params.Body.Description, params.Body.Status, params.Body.SecretKey)
err = updateServiceAccountDetails(ctx, userAdminClient, accessKey, policy, expiry, params.Body.Name, params.Body.Description, params.Body.Status, params.Body.SecretKey)
if err != nil {
return ErrorWithContext(ctx, err)
}

View File

@@ -17,65 +17,35 @@
package api
import (
"crypto/tls"
"net"
"net/http"
"time"
)
type ConsoleTransport struct {
Transport *http.Transport
Transport http.RoundTripper
ClientIP string
}
func (t *ConsoleTransport) RoundTrip(req *http.Request) (*http.Response, error) {
req.Header.Add("X-Forwarded-For", t.ClientIP)
resp, err := t.Transport.RoundTrip(req)
return resp, err
if t.ClientIP != "" {
// Do not set an empty x-forwarded-for
req.Header.Add(xForwardedFor, t.ClientIP)
}
return t.Transport.RoundTrip(req)
}
// PrepareSTSClientTransport :
func PrepareSTSClientTransport(insecure bool, remoteAddress string) *ConsoleTransport {
// This takes github.com/minio/madmin-go/v3/transport.go as an example
//
// DefaultTransport - this default transport is similar to
// http.DefaultTransport but with additional param DisableCompression
// is set to true to avoid decompressing content with 'gzip' encoding.
DefaultTransport := &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 10 * time.Second,
KeepAlive: 15 * time.Second,
}).DialContext,
MaxIdleConns: 1024,
MaxIdleConnsPerHost: 1024,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 10 * time.Second,
DisableCompression: true,
TLSClientConfig: &tls.Config{
// Can't use SSLv3 because of POODLE and BEAST
// Can't use TLSv1.0 because of POODLE and BEAST using CBC cipher
// Can't use TLSv1.1 because of RC4 cipher usage
MinVersion: tls.VersionTLS12,
InsecureSkipVerify: insecure,
RootCAs: GlobalRootCAs,
},
func PrepareSTSClientTransport(clientIP string) *ConsoleTransport {
return &ConsoleTransport{
Transport: GlobalTransport,
ClientIP: clientIP,
}
t := &ConsoleTransport{
Transport: DefaultTransport,
ClientIP: remoteAddress,
}
return t
}
// PrepareConsoleHTTPClient returns an http.Client with custom configurations need it by *credentials.STSAssumeRole
// custom configurations include the use of CA certificates
func PrepareConsoleHTTPClient(insecure bool, clientIP string) *http.Client {
transport := PrepareSTSClientTransport(insecure, clientIP)
func PrepareConsoleHTTPClient(clientIP string) *http.Client {
// Return http client with default configuration
c := &http.Client{
Transport: transport,
return &http.Client{
Transport: PrepareSTSClientTransport(clientIP),
}
return c
}

View File

@@ -98,7 +98,7 @@ func getLogSearchResponse(session *models.Principal, params logApi.LogSearchPara
}
func logSearch(endpoint string, clientIP string) (*models.LogSearchResponse, error) {
httpClnt := GetConsoleHTTPClient(endpoint, clientIP)
httpClnt := GetConsoleHTTPClient(clientIP)
resp, err := httpClnt.Get(endpoint)
if err != nil {
return nil, fmt.Errorf("the Log Search API cannot be reached. Please review the URL and try again %v", err)

View File

@@ -191,8 +191,7 @@ func getLoginDetailsResponse(params authApi.LoginDetailParams, openIDProviders o
for name, provider := range openIDProviders {
// initialize new oauth2 client
oauth2Client, err := provider.GetOauth2Provider(name, nil, r, GetConsoleHTTPClient("", getClientIP(params.HTTPRequest)),
GetConsoleHTTPClient(getMinIOServer(), getClientIP(params.HTTPRequest)))
oauth2Client, err := provider.GetOauth2Provider(name, nil, r, GetConsoleHTTPClient(getClientIP(params.HTTPRequest)))
if err != nil {
continue
}
@@ -281,8 +280,8 @@ func getLoginOauth2AuthResponse(params authApi.LoginOauth2AuthParams, openIDProv
}
// Initialize new identity provider with new oauth2Client per IDPName
oauth2Client, err := providerCfg.GetOauth2Provider(IDPName, nil, r, GetConsoleHTTPClient("", getClientIP(params.HTTPRequest)),
GetConsoleHTTPClient(getMinIOServer(), getClientIP(params.HTTPRequest)))
oauth2Client, err := providerCfg.GetOauth2Provider(IDPName, nil, r,
GetConsoleHTTPClient(getClientIP(params.HTTPRequest)))
if err != nil {
return nil, ErrorWithContext(ctx, err)
}

View File

@@ -18,7 +18,6 @@ package api
import (
"context"
"crypto/tls"
"encoding/base64"
"encoding/json"
"net/http"
@@ -103,11 +102,7 @@ func logoutFromIDPProvider(r *http.Request, state string) error {
params.Add("client_secret", providerCfg.ClientSecret)
params.Add("refresh_token", refreshToken.Value)
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: GlobalRootCAs,
},
},
Transport: GlobalTransport,
}
_, err := client.PostForm(providerCfg.EndSessionEndpoint, params)
if err != nil {

View File

@@ -1100,7 +1100,7 @@ func getShareObjectURL(ctx context.Context, client MCClient, r *http.Request, ve
return nil, pErr.Cause
}
encodedMinIOURL := b64.StdEncoding.EncodeToString([]byte(minioURL))
encodedMinIOURL := b64.URLEncoding.EncodeToString([]byte(minioURL))
requestURL := getRequestURLWithScheme(r)
objURL := fmt.Sprintf("%s/api/v1/download-shared-object/%s", requestURL, encodedMinIOURL)
return &objURL, nil
@@ -1338,6 +1338,7 @@ func getObjectMetadataResponse(session *models.Principal, params objectApi.GetOb
// defining the client to be used
minioClient := minioClient{client: mClient}
var prefix string
var versionID string
if params.Prefix != "" {
encodedPrefix := SanitizeEncodedPrefix(params.Prefix)
@@ -1348,7 +1349,11 @@ func getObjectMetadataResponse(session *models.Principal, params objectApi.GetOb
prefix = string(decodedPrefix)
}
objectInfo, err := getObjectInfo(ctx, minioClient, params.BucketName, prefix)
if params.VersionID != nil {
versionID = *params.VersionID
}
objectInfo, err := getObjectInfo(ctx, minioClient, params.BucketName, prefix, versionID)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
@@ -1358,8 +1363,8 @@ func getObjectMetadataResponse(session *models.Principal, params objectApi.GetOb
return metadata, nil
}
func getObjectInfo(ctx context.Context, client MinioClient, bucketName, prefix string) (minio.ObjectInfo, error) {
objectData, err := client.statObject(ctx, bucketName, prefix, minio.GetObjectOptions{})
func getObjectInfo(ctx context.Context, client MinioClient, bucketName, prefix, versionID string) (minio.ObjectInfo, error) {
objectData, err := client.statObject(ctx, bucketName, prefix, minio.GetObjectOptions{VersionID: versionID})
if err != nil {
return minio.ObjectInfo{}, err
}

View File

@@ -927,7 +927,7 @@ func Test_shareObject(t *testing.T) {
expected string
}{
{
test: "Get share object url",
test: "return sharefunc url base64 encoded with host name",
args: args{
r: &http.Request{
TLS: nil,
@@ -944,7 +944,7 @@ func Test_shareObject(t *testing.T) {
expected: "http://localhost:9090/api/v1/download-shared-object/aHR0cDovL3NvbWV1cmw=",
},
{
test: "URL with TLS uses https scheme",
test: "return https scheme if url uses TLS",
args: args{
r: &http.Request{
TLS: &tls.ConnectionState{},
@@ -961,7 +961,7 @@ func Test_shareObject(t *testing.T) {
expected: "https://localhost:9090/api/v1/download-shared-object/aHR0cDovL3NvbWV1cmw=",
},
{
test: "handle invalid expire duration",
test: "returns invalid expire duration if expiration is invalid",
args: args{
r: &http.Request{
TLS: nil,
@@ -976,7 +976,7 @@ func Test_shareObject(t *testing.T) {
wantError: errors.New("time: invalid duration \"invalid\""),
},
{
test: "handle empty expire duration",
test: "add default expiration if expiration is empty",
args: args{
r: &http.Request{
TLS: nil,
@@ -992,7 +992,7 @@ func Test_shareObject(t *testing.T) {
expected: "http://localhost:9090/api/v1/download-shared-object/aHR0cDovL3NvbWV1cmw=",
},
{
test: "handle error on share func",
test: "return error if sharefunc returns error",
args: args{
r: &http.Request{
TLS: nil,
@@ -1006,6 +1006,23 @@ func Test_shareObject(t *testing.T) {
},
wantError: errors.New("probe error"),
},
{
test: "return shareFunc url base64 encoded url-safe",
args: args{
r: &http.Request{
TLS: nil,
Host: "localhost:9090",
},
versionID: "2121434",
expires: "3h",
shareFunc: func(_ context.Context, _ string, _ time.Duration) (string, *probe.Error) {
// https://127.0.0.1:9000/cestest/Audio%20icon.svg?X-Amz-Algorithm=AWS4-HMAC-SHA256 using StdEncoding adds an extra `/` making it not url safe
return "https://127.0.0.1:9000/cestest/Audio%20icon.svg?X-Amz-Algorithm=AWS4-HMAC-SHA256", nil
},
},
wantError: nil,
expected: "http://localhost:9090/api/v1/download-shared-object/aHR0cHM6Ly8xMjcuMC4wLjE6OTAwMC9jZXN0ZXN0L0F1ZGlvJTIwaWNvbi5zdmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTY=",
},
}
for _, tt := range tests {
@@ -1276,6 +1293,7 @@ func Test_getObjectInfo(t *testing.T) {
type args struct {
bucketName string
prefix string
versionID string
statFunc func(ctx context.Context, bucketName string, prefix string, opts minio.GetObjectOptions) (objectInfo minio.ObjectInfo, err error)
}
tests := []struct {
@@ -1288,6 +1306,7 @@ func Test_getObjectInfo(t *testing.T) {
args: args{
bucketName: "bucket1",
prefix: "someprefix",
versionID: "version123",
statFunc: func(_ context.Context, _ string, _ string, _ minio.GetObjectOptions) (minio.ObjectInfo, error) {
return minio.ObjectInfo{}, nil
},
@@ -1299,6 +1318,7 @@ func Test_getObjectInfo(t *testing.T) {
args: args{
bucketName: "bucket2",
prefix: "someprefi2",
versionID: "version456",
statFunc: func(_ context.Context, _ string, _ string, _ minio.GetObjectOptions) (minio.ObjectInfo, error) {
return minio.ObjectInfo{}, errors.New("new Error")
},
@@ -1309,7 +1329,7 @@ func Test_getObjectInfo(t *testing.T) {
for _, tt := range tests {
t.Run(tt.test, func(_ *testing.T) {
minioStatObjectMock = tt.args.statFunc
_, err := getObjectInfo(ctx, client, tt.args.bucketName, tt.args.prefix)
_, err := getObjectInfo(ctx, client, tt.args.bucketName, tt.args.prefix, tt.args.versionID)
if tt.wantError != nil {
fmt.Println(t.Name())
tAssert.Equal(tt.wantError.Error(), err.Error(), fmt.Sprintf("getObjectInfo() error: `%s`, wantErr: `%s`", err, tt.wantError))

View File

@@ -43,13 +43,26 @@ func (wsc *wsMinioClient) objectManager(session *models.Principal) {
writeChannel := make(chan WSResponse)
done := make(chan interface{})
sendWSResponse := func(r WSResponse) {
select {
case writeChannel <- r:
case <-done:
}
}
// Read goroutine
go func() {
defer close(writeChannel)
for {
select {
case <-done:
return
default:
}
mType, message, err := wsc.conn.readMessage()
if err != nil {
LogInfo("Error while reading objectManager message", err)
close(done)
return
}
@@ -60,8 +73,6 @@ func (wsc *wsMinioClient) objectManager(session *models.Principal) {
err := json.Unmarshal(message, &messageRequest)
if err != nil {
LogInfo("Error on message request unmarshal")
close(done)
return
}
@@ -74,7 +85,6 @@ func (wsc *wsMinioClient) objectManager(session *models.Principal) {
const itemsPerBatch = 1000
switch messageRequest.Mode {
case "close":
close(done)
return
case "cancel":
// if we have that request id, cancel it
@@ -97,12 +107,12 @@ func (wsc *wsMinioClient) objectManager(session *models.Principal) {
if err != nil {
LogInfo(fmt.Sprintf("Error during Objects OptionsParse %s", err.Error()))
writeChannel <- WSResponse{
sendWSResponse(WSResponse{
RequestID: messageRequest.RequestID,
Error: ErrorWithContext(ctx, err),
Prefix: messageRequest.Prefix,
BucketName: messageRequest.BucketName,
}
})
return
}
@@ -112,12 +122,12 @@ func (wsc *wsMinioClient) objectManager(session *models.Principal) {
return
}
if lsObj.Err != nil {
writeChannel <- WSResponse{
sendWSResponse(WSResponse{
RequestID: messageRequest.RequestID,
Error: ErrorWithContext(ctx, lsObj.Err),
Prefix: messageRequest.Prefix,
BucketName: messageRequest.BucketName,
}
})
continue
}
@@ -132,24 +142,24 @@ func (wsc *wsMinioClient) objectManager(session *models.Principal) {
buffer = append(buffer, objItem)
if len(buffer) >= itemsPerBatch {
writeChannel <- WSResponse{
sendWSResponse(WSResponse{
RequestID: messageRequest.RequestID,
Data: buffer,
}
})
buffer = nil
}
}
if len(buffer) > 0 {
writeChannel <- WSResponse{
sendWSResponse(WSResponse{
RequestID: messageRequest.RequestID,
Data: buffer,
}
})
}
writeChannel <- WSResponse{
sendWSResponse(WSResponse{
RequestID: messageRequest.RequestID,
RequestEnd: true,
}
})
// remove the cancellation context
delete(cancelContexts, messageRequest.RequestID)
@@ -168,12 +178,12 @@ func (wsc *wsMinioClient) objectManager(session *models.Principal) {
objectRqConfigs, err := getObjectsOptionsFromReq(messageRequest)
if err != nil {
LogInfo(fmt.Sprintf("Error during Objects OptionsParse %s", err.Error()))
writeChannel <- WSResponse{
sendWSResponse(WSResponse{
RequestID: messageRequest.RequestID,
Error: ErrorWithContext(ctx, err),
Prefix: messageRequest.Prefix,
BucketName: messageRequest.BucketName,
}
})
return
}
@@ -182,12 +192,12 @@ func (wsc *wsMinioClient) objectManager(session *models.Principal) {
s3Client, err := newS3BucketClient(session, objectRqConfigs.BucketName, objectRqConfigs.Prefix, clientIP)
if err != nil {
writeChannel <- WSResponse{
sendWSResponse(WSResponse{
RequestID: messageRequest.RequestID,
Error: ErrorWithContext(ctx, err),
Prefix: messageRequest.Prefix,
BucketName: messageRequest.BucketName,
}
})
cancel()
return
@@ -199,12 +209,12 @@ func (wsc *wsMinioClient) objectManager(session *models.Principal) {
for lsObj := range startRewindListing(ctx, mcS3C, objectRqConfigs) {
if lsObj.Err != nil {
writeChannel <- WSResponse{
sendWSResponse(WSResponse{
RequestID: messageRequest.RequestID,
Error: ErrorWithContext(ctx, lsObj.Err.ToGoError()),
Prefix: messageRequest.Prefix,
BucketName: messageRequest.BucketName,
}
})
continue
}
@@ -222,25 +232,25 @@ func (wsc *wsMinioClient) objectManager(session *models.Principal) {
buffer = append(buffer, objItem)
if len(buffer) >= itemsPerBatch {
writeChannel <- WSResponse{
sendWSResponse(WSResponse{
RequestID: messageRequest.RequestID,
Data: buffer,
}
})
buffer = nil
}
}
if len(buffer) > 0 {
writeChannel <- WSResponse{
sendWSResponse(WSResponse{
RequestID: messageRequest.RequestID,
Data: buffer,
}
})
}
writeChannel <- WSResponse{
sendWSResponse(WSResponse{
RequestID: messageRequest.RequestID,
RequestEnd: true,
}
})
// remove the cancellation context
delete(cancelContexts, messageRequest.RequestID)
@@ -250,27 +260,19 @@ func (wsc *wsMinioClient) objectManager(session *models.Principal) {
}
}()
// Write goroutine
go func() {
for {
select {
case <-done:
return
case writeM := <-writeChannel:
jsonData, err := json.Marshal(writeM)
if err != nil {
LogInfo("Error while marshaling the response", err)
return
}
defer close(done)
err = wsc.conn.writeMessage(websocket.TextMessage, jsonData)
if err != nil {
LogInfo("Error while writing the message", err)
return
}
}
for writeM := range writeChannel {
jsonData, err := json.Marshal(writeM)
if err != nil {
LogInfo("Error while marshaling the response", err)
return
}
}()
<-done
err = wsc.conn.writeMessage(websocket.TextMessage, jsonData)
if err != nil {
LogInfo("Error while writing the message", err)
return
}
}
}

View File

@@ -19,6 +19,7 @@ package main
import (
"context"
"fmt"
"net/http"
"strconv"
"time"
@@ -42,8 +43,8 @@ func StartServer(ctx *cli.Context) error {
xctx := context.Background()
transport := api.PrepareSTSClientTransport(false, api.LocalAddress)
if err := logger.InitializeLogger(xctx, transport.Transport); err != nil {
transport := api.PrepareSTSClientTransport(api.LocalAddress).Transport.(*http.Transport)
if err := logger.InitializeLogger(xctx, transport); err != nil {
fmt.Println("error InitializeLogger", err)
logger.CriticalIf(xctx, err)
}

56
go.mod
View File

@@ -17,13 +17,13 @@ require (
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/google/uuid v1.6.0
github.com/jessevdk/go-flags v1.5.0
github.com/klauspost/compress v1.17.7
github.com/klauspost/compress v1.17.8
github.com/minio/cli v1.24.2
github.com/minio/highwayhash v1.0.2
github.com/minio/kes v0.23.0
github.com/minio/madmin-go/v3 v3.0.50
github.com/minio/mc v0.0.0-20240330152952-9f8147bf0e03
github.com/minio/minio-go/v7 v7.0.69
github.com/minio/madmin-go/v3 v3.0.51
github.com/minio/mc v0.0.0-20240430174448-dcb911bed9d5
github.com/minio/minio-go/v7 v7.0.70
github.com/minio/selfupdate v0.6.0
github.com/minio/websocket v1.6.0
github.com/mitchellh/go-homedir v1.1.0
@@ -32,8 +32,8 @@ require (
github.com/stretchr/testify v1.9.0
github.com/tidwall/gjson v1.17.1
github.com/unrolled/secure v1.14.0
golang.org/x/crypto v0.21.0
golang.org/x/net v0.23.0
golang.org/x/crypto v0.22.0
golang.org/x/net v0.24.0
golang.org/x/oauth2 v0.18.0
// Added to include security fix for
// https://github.com/golang/go/issues/56152
@@ -43,7 +43,7 @@ require (
require (
github.com/mattn/go-ieproxy v0.0.11
github.com/minio/pkg/v2 v2.0.13
github.com/minio/pkg/v2 v2.0.17
)
require (
@@ -54,7 +54,7 @@ require (
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/charmbracelet/bubbles v0.18.0 // indirect
github.com/charmbracelet/bubbletea v0.25.0 // indirect
github.com/charmbracelet/lipgloss v0.10.0 // indirect
@@ -63,11 +63,9 @@ require (
github.com/coreos/go-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/fatih/structs v1.1.0 // indirect
github.com/gdamore/encoding v1.0.0 // indirect
github.com/gdamore/tcell/v2 v2.7.4 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-openapi/analysis v0.23.0 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
@@ -79,9 +77,8 @@ require (
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jedib0t/go-pretty/v6 v6.5.4 // indirect
github.com/jedib0t/go-pretty/v6 v6.5.8 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/juju/ratelimit v1.0.2 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect
@@ -91,7 +88,7 @@ require (
github.com/lestrrat-go/jwx v1.2.29 // indirect
github.com/lestrrat-go/option v1.0.1 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a // indirect
github.com/lufia/plan9stats v0.0.0-20240408141607-282e7b5d6b74 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
@@ -102,16 +99,12 @@ require (
github.com/minio/filepath v1.0.0 // indirect
github.com/minio/kes-go v0.2.1 // indirect
github.com/minio/md5-simd v1.1.2 // indirect
github.com/minio/sha256-simd v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/montanaflynn/stats v0.7.1 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/reflow v0.3.0 // indirect
github.com/muesli/termenv v0.15.2 // indirect
github.com/navidys/tvxwidgets v0.6.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/philhofer/fwd v1.1.2 // indirect
@@ -121,36 +114,35 @@ require (
github.com/posener/complete v1.2.3 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
github.com/prometheus/client_golang v1.19.0 // indirect
github.com/prometheus/client_model v0.6.0 // indirect
github.com/prometheus/common v0.50.0 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.52.3 // indirect
github.com/prometheus/procfs v0.13.0 // indirect
github.com/prometheus/prom2json v1.3.3 // indirect
github.com/rivo/tview v0.0.0-20240307173318-e804876934a1 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rjeczalik/notify v0.9.3 // indirect
github.com/safchain/ethtool v0.3.0 // indirect
github.com/shirou/gopsutil/v3 v3.24.2 // indirect
github.com/shirou/gopsutil/v3 v3.24.3 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/tinylib/msgp v1.1.9 // indirect
github.com/tklauser/go-sysconf v0.3.13 // indirect
github.com/tklauser/numcpus v0.7.0 // indirect
github.com/vbauerster/mpb/v8 v8.7.2 // indirect
github.com/vbauerster/mpb/v8 v8.7.3 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.etcd.io/etcd/api/v3 v3.5.12 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.12 // indirect
go.etcd.io/etcd/client/v3 v3.5.12 // indirect
go.etcd.io/etcd/api/v3 v3.5.13 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.13 // indirect
go.etcd.io/etcd/client/v3 v3.5.13 // indirect
go.mongodb.org/mongo-driver v1.14.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/term v0.18.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/term v0.19.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240311173647-c811ad7063a7 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240311173647-c811ad7063a7 // indirect
google.golang.org/grpc v1.62.1 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect
google.golang.org/grpc v1.63.2 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect

124
go.sum
View File

@@ -16,8 +16,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0=
github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw=
github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM=
@@ -38,8 +38,9 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
@@ -49,12 +50,6 @@ github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/gdamore/tcell/v2 v2.7.4 h1:sg6/UnTM9jGpZU+oFYAsDahfchWAFW8Xx2yFinNSAYU=
github.com/gdamore/tcell/v2 v2.7.4/go.mod h1:dSXtXTSK0VsW1biw65DZLZ2NKr7j0qP/0J7ONmsraWg=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
@@ -78,8 +73,6 @@ github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+Gr
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
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-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
@@ -97,9 +90,6 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd h1:1FjCyPC+syAzJ5/2S8fqdZK1R22vvA0J7JZKcuOIQ7Y=
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
@@ -112,20 +102,18 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jedib0t/go-pretty/v6 v6.5.4 h1:gOGo0613MoqUcf0xCj+h/V3sHDaZasfv152G6/5l91s=
github.com/jedib0t/go-pretty/v6 v6.5.4/go.mod h1:5LQIxa52oJ/DlDSLv0HEkWOFMDGoWkJb9ss5KqPpJBg=
github.com/jedib0t/go-pretty/v6 v6.5.8 h1:8BCzJdSvUbaDuRba4YVh+SKMGcAAKdkcF3SVFbrHAtQ=
github.com/jedib0t/go-pretty/v6 v6.5.8/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E=
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/juju/ratelimit v1.0.2 h1:sRxmtRiajbvrcLQT7S+JbqU0ntsb9W2yhSdNN8tWfaI=
github.com/juju/ratelimit v1.0.2/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg=
github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
@@ -149,8 +137,8 @@ github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmt
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a h1:3Bm7EwfUQUvhNeKIkUct/gl9eod1TcXuj8stxvi/GoI=
github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
github.com/lufia/plan9stats v0.0.0-20240408141607-282e7b5d6b74 h1:1KuuSOy4ZNgW0KA2oYIngXVFhQcXxhLqCVK7cBcldkk=
github.com/lufia/plan9stats v0.0.0-20240408141607-282e7b5d6b74/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
@@ -184,33 +172,26 @@ github.com/minio/kes v0.23.0 h1:T0zHtyDoI3JdKrVvzdM4xwVryYYyh5pKwNUVBoqxsNs=
github.com/minio/kes v0.23.0/go.mod h1:vvXVGcgu9mYLkbVWlEvFFl6bYR196RQlOU2Q+rHApl8=
github.com/minio/kes-go v0.2.1 h1:KnqS+p6xoSFJZbQhmJaz/PbxeA6nQyRqT/ywrn5lU2o=
github.com/minio/kes-go v0.2.1/go.mod h1:76xf7l41Wrh+IifisABXK2S8uZWYgWV1IGBKC3GdOJk=
github.com/minio/madmin-go/v3 v3.0.50 h1:+RQMetVFvPQmAOEDN/xmLhwk9+xOzu3rqwnlZEskgvg=
github.com/minio/madmin-go/v3 v3.0.50/go.mod h1:ZDF7kf5fhmxLhbGTqyq5efs4ao0v4eWf7nOuef/ljJs=
github.com/minio/mc v0.0.0-20240330152952-9f8147bf0e03 h1:xF1hntqvs/CVEHGBETSrIMTW3iSU3k2j/YCFXGDWoBs=
github.com/minio/mc v0.0.0-20240330152952-9f8147bf0e03/go.mod h1:RMCe706GTL9EOO6pxzFXd9Vp+3w2L1uctPiycmLDr9U=
github.com/minio/madmin-go/v3 v3.0.51 h1:brGOvDP8KvoHb/bdzCHUPFCbTtrN8o507uPHZpyuinM=
github.com/minio/madmin-go/v3 v3.0.51/go.mod h1:IFAwr0XMrdsLovxAdCcuq/eoL4nRuMVQQv0iubJANQw=
github.com/minio/mc v0.0.0-20240430174448-dcb911bed9d5 h1:VDXLzvY0Jxk4lzIntGXZuw0VH7S1JgQBmjWGkz7xphU=
github.com/minio/mc v0.0.0-20240430174448-dcb911bed9d5/go.mod h1:aOiBeSNmpfJn1yyz+EujrTM+XmUwkXiM69zSXg12VDM=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
github.com/minio/minio-go/v7 v7.0.69 h1:l8AnsQFyY1xiwa/DaQskY4NXSLA2yrGsW5iD9nRPVS0=
github.com/minio/minio-go/v7 v7.0.69/go.mod h1:XAvOPJQ5Xlzk5o3o/ArO2NMbhSGkimC+bpW/ngRKDmQ=
github.com/minio/minio-go/v7 v7.0.70 h1:1u9NtMgfK1U42kUxcsl5v0yj6TEOPR497OAQxpJnn2g=
github.com/minio/minio-go/v7 v7.0.70/go.mod h1:4yBA8v80xGA30cfM3fz0DKYMXunWl/AV/6tWEs9ryzo=
github.com/minio/mux v1.9.0 h1:dWafQFyEfGhJvK6AwLOt83bIG5bxKxKJnKMCi0XAaoA=
github.com/minio/mux v1.9.0/go.mod h1:1pAare17ZRL5GpmNL+9YmqHoWnLmMZF9C/ioUCfy0BQ=
github.com/minio/pkg/v2 v2.0.13 h1:Tm4koPzm+gVVCU5YLPtzXzfwkCR5sd/asXCu/RABSeA=
github.com/minio/pkg/v2 v2.0.13/go.mod h1:zbVATXCinLCo+L/4vsPyqgiA4OYPXCJb+/E4KfE396A=
github.com/minio/pkg/v2 v2.0.17 h1:ndmGlitUj/eCVRPmfsAw3KlbtVNxqk0lQIvDXlcTHiQ=
github.com/minio/pkg/v2 v2.0.17/go.mod h1:V+OP/fKRD/qhJMQpdXXrCXcLYjGMpHKEE26zslthm5k=
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/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
github.com/minio/websocket v1.6.0 h1:CPvnQvNvlVaQmvw5gtJNyYQhg4+xRmrPNhBbv8BdpAE=
github.com/minio/websocket v1.6.0/go.mod h1:COH1CePZfHT9Ec1O7vZjTlX5uEPpyYnrifPNbu665DM=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
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=
@@ -221,16 +202,10 @@ github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
github.com/navidys/tvxwidgets v0.6.0 h1:ARIXGfx4aURHMhq+LW5vIoCCDx1X/PdTF8AcUq+nWZ0=
github.com/navidys/tvxwidgets v0.6.0/go.mod h1:wd6aS2OzjZczFbg8GCaVuwkFcY1eixlT/y7Lc/YIwlg=
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo/v2 v2.16.0 h1:7q1w9frJDzninhXxjZd+Y/x54XNjG/UlRLIYPZafsPM=
github.com/onsi/ginkgo/v2 v2.16.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo=
github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0=
github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw=
github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -247,19 +222,16 @@ github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU=
github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k=
github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos=
github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8=
github.com/prometheus/common v0.50.0 h1:YSZE6aa9+luNa2da6/Tik0q0A5AbR+U003TItK57CPQ=
github.com/prometheus/common v0.50.0/go.mod h1:wHFBCEVWVmHMUpg7pYcOm2QUR/ocQdYSJVQJKnHc3xQ=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.52.3 h1:5f8uj6ZwHSscOGNdIQg6OiZv/ybiK2CO2q2drVZAQSA=
github.com/prometheus/common v0.52.3/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U=
github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o=
github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g=
github.com/prometheus/prom2json v1.3.3 h1:IYfSMiZ7sSOfliBoo89PcufjWO4eAR0gznGcETyaUgo=
github.com/prometheus/prom2json v1.3.3/go.mod h1:Pv4yIPktEkK7btWsrUTWDDDrnpUrAELaOCj+oFwlgmc=
github.com/rivo/tview v0.0.0-20240307173318-e804876934a1 h1:bWLHTRekAy497pE7+nXSuzXwwFHI0XauRzz6roUvY+s=
github.com/rivo/tview v0.0.0-20240307173318-e804876934a1/go.mod h1:02iFIz7K/A9jGCvrizLPvoqr4cEIx7q54RH5Qudkrss=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rjeczalik/notify v0.9.3 h1:6rJAzHTGKXGj76sbRgDiDcYj/HniypXmSJo1SWakZeY=
@@ -272,8 +244,8 @@ github.com/safchain/ethtool v0.3.0 h1:gimQJpsI6sc1yIqP/y8GYgiXn/NjgvpM0RNoWLVVmP
github.com/safchain/ethtool v0.3.0/go.mod h1:SA9BwrgyAqNo7M+uaL6IYbxpm5wk3L7Mm6ocLW+CJUs=
github.com/secure-io/sio-go v0.3.1 h1:dNvY9awjabXTYGsTF1PiCySl9Ltofk9GA3VdWlo7rRc=
github.com/secure-io/sio-go v0.3.1/go.mod h1:+xbkjDzPjwh4Axd07pRKSNriS9SCiYksWnZqdnfpQxs=
github.com/shirou/gopsutil/v3 v3.24.2 h1:kcR0erMbLg5/3LcInpw0X/rrPSqq4CDPyI6A6ZRC18Y=
github.com/shirou/gopsutil/v3 v3.24.2/go.mod h1:tSg/594BcA+8UdQU2XcW803GWYgdtauFFPgJCJKZlVk=
github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE=
github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
@@ -282,7 +254,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
@@ -307,19 +278,19 @@ github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr
github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY=
github.com/unrolled/secure v1.14.0 h1:u9vJTU/pR4Bny0ntLUMxdfLtmIRGvQf2sEFuA0TG9AE=
github.com/unrolled/secure v1.14.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40=
github.com/vbauerster/mpb/v8 v8.7.2 h1:SMJtxhNho1MV3OuFgS1DAzhANN1Ejc5Ct+0iSaIkB14=
github.com/vbauerster/mpb/v8 v8.7.2/go.mod h1:ZFnrjzspgDHoxYLGvxIruiNk73GNTPG4YHgVNpR10VY=
github.com/vbauerster/mpb/v8 v8.7.3 h1:n/mKPBav4FFWp5fH4U0lPpXfiOmCEgl5Yx/NM3tKJA0=
github.com/vbauerster/mpb/v8 v8.7.3/go.mod h1:9nFlNpDGVoTmQ4QvNjSLtwLmAFjwmq0XaAF26toHGNM=
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.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.etcd.io/etcd/api/v3 v3.5.12 h1:W4sw5ZoU2Juc9gBWuLk5U6fHfNVyY1WC5g9uiXZio/c=
go.etcd.io/etcd/api/v3 v3.5.12/go.mod h1:Ot+o0SWSyT6uHhA56al1oCED0JImsRiU9Dc26+C2a+4=
go.etcd.io/etcd/client/pkg/v3 v3.5.12 h1:EYDL6pWwyOsylrQyLp2w+HkQ46ATiOvoEdMarindU2A=
go.etcd.io/etcd/client/pkg/v3 v3.5.12/go.mod h1:seTzl2d9APP8R5Y2hFL3NVlD6qC/dOT+3kvrqPyTas4=
go.etcd.io/etcd/client/v3 v3.5.12 h1:v5lCPXn1pf1Uu3M4laUE2hp/geOTc5uPcYYsNe1lDxg=
go.etcd.io/etcd/client/v3 v3.5.12/go.mod h1:tSbBCakoWmmddL+BKVAJHa9km+O/E+bumDe9mSbPiqw=
go.etcd.io/etcd/api/v3 v3.5.13 h1:8WXU2/NBge6AUF1K1gOexB6e07NgsN1hXK0rSTtgSp4=
go.etcd.io/etcd/api/v3 v3.5.13/go.mod h1:gBqlqkcMMZMVTMm4NDZloEVJzxQOQIls8splbqBDa0c=
go.etcd.io/etcd/client/pkg/v3 v3.5.13 h1:RVZSAnWWWiI5IrYAXjQorajncORbS0zI48LQlE2kQWg=
go.etcd.io/etcd/client/pkg/v3 v3.5.13/go.mod h1:XxHT4u1qU12E2+po+UVPrEeL94Um6zL58ppuJWXSAB8=
go.etcd.io/etcd/client/v3 v3.5.13 h1:o0fHTNJLeO0MyVbc7I3fsCf6nrOqn5d+diSarKnB2js=
go.etcd.io/etcd/client/v3 v3.5.13/go.mod h1:cqiAeY8b5DEEcpxvgWKsbLIWNM/8Wy2xJSDMtioMcoI=
go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80=
go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
@@ -336,8 +307,9 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
@@ -352,8 +324,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI=
golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -362,8 +334,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -389,16 +361,18 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
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-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -414,20 +388,18 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/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-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
google.golang.org/genproto/googleapis/api v0.0.0-20240311173647-c811ad7063a7 h1:oqta3O3AnlWbmIE3bFnWbu4bRxZjfbWCp0cKSuZh01E=
google.golang.org/genproto/googleapis/api v0.0.0-20240311173647-c811ad7063a7/go.mod h1:VQW3tUculP/D4B+xVCo+VgSq8As6wA9ZjHl//pmk+6s=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240311173647-c811ad7063a7 h1:8EeVk1VKMD+GD/neyEHGmz7pFblqPjHoi+PGQIlLx2s=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240311173647-c811ad7063a7/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk=
google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be h1:Zz7rLWqp0ApfsR/l7+zSHhY3PMiH2xqgxlfYfAfNpoU=
google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be/go.mod h1:dvdCTIoAGbkWbcIKBniID56/7XHTt6WfxXNMxuziJ+w=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be h1:LG9vZxsWGOmUKieR8wPAUR3u3MpnYFQZROPIMaXh7/A=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM=
google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=

View File

@@ -68,6 +68,9 @@ type MultiBucketReplication struct {
// replicate deletes
ReplicateDeletes bool `json:"replicateDeletes,omitempty"`
// replicate existing objects
ReplicateExistingObjects bool `json:"replicateExistingObjects,omitempty"`
// replicate metadata
ReplicateMetadata bool `json:"replicateMetadata,omitempty"`

View File

@@ -52,9 +52,9 @@ type ProviderConfig struct {
//
// We only support Authentication with the Authorization Code Flow - spec:
// https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth
func (pc ProviderConfig) GetOauth2Provider(name string, scopes []string, r *http.Request, idpClient, stsClient *http.Client) (provider *Provider, err error) {
func (pc ProviderConfig) GetOauth2Provider(name string, scopes []string, r *http.Request, clnt *http.Client) (provider *Provider, err error) {
var ddoc DiscoveryDoc
ddoc, err = parseDiscoveryDoc(r.Context(), pc.URL, idpClient)
ddoc, err = parseDiscoveryDoc(r.Context(), pc.URL, clnt)
if err != nil {
return nil, err
}
@@ -112,9 +112,7 @@ func (pc ProviderConfig) GetOauth2Provider(name string, scopes []string, r *http
client.IDPName = name
client.UserInfo = pc.Userinfo
client.provHTTPClient = idpClient
client.stsHTTPClient = stsClient
client.client = clnt
return client, nil
}

View File

@@ -109,11 +109,10 @@ type Provider struct {
// - Scopes specifies optional requested permissions.
IDPName string
// if enabled means that we need extrace access_token as well
UserInfo bool
RefreshToken string
oauth2Config Configuration
provHTTPClient *http.Client
stsHTTPClient *http.Client
UserInfo bool
RefreshToken string
oauth2Config Configuration
client *http.Client
}
// DefaultDerivedKey is the key used to compute the HMAC for signing the oauth state parameter
@@ -204,7 +203,7 @@ func NewOauth2ProviderClient(scopes []string, r *http.Request, httpClient *http.
client.IDPName = GetIDPClientID()
client.UserInfo = GetIDPUserInfo()
client.provHTTPClient = httpClient
client.client = httpClient
return client, nil
}
@@ -212,12 +211,12 @@ func NewOauth2ProviderClient(scopes []string, r *http.Request, httpClient *http.
var defaultScopes = []string{"openid", "profile", "email"}
// NewOauth2ProviderClientByName returns a provider if present specified by the input name of the provider.
func (ois OpenIDPCfg) NewOauth2ProviderClientByName(name string, scopes []string, r *http.Request, idpClient, stsClient *http.Client) (provider *Provider, err error) {
func (ois OpenIDPCfg) NewOauth2ProviderClientByName(name string, scopes []string, r *http.Request, clnt *http.Client) (provider *Provider, err error) {
oi, ok := ois[name]
if !ok {
return nil, fmt.Errorf("%s IDP provider does not exist", name)
}
return oi.GetOauth2Provider(name, scopes, r, idpClient, stsClient)
return oi.GetOauth2Provider(name, scopes, r, clnt)
}
// NewOauth2ProviderClient instantiates a new oauth2 client using the
@@ -227,9 +226,9 @@ func (ois OpenIDPCfg) NewOauth2ProviderClientByName(name string, scopes []string
//
// We only support Authentication with the Authorization Code Flow - spec:
// https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth
func (ois OpenIDPCfg) NewOauth2ProviderClient(scopes []string, r *http.Request, idpClient, stsClient *http.Client) (provider *Provider, providerCfg ProviderConfig, err error) {
func (ois OpenIDPCfg) NewOauth2ProviderClient(scopes []string, r *http.Request, clnt *http.Client) (provider *Provider, providerCfg ProviderConfig, err error) {
for name, oi := range ois {
provider, err = oi.GetOauth2Provider(name, scopes, r, idpClient, stsClient)
provider, err = oi.GetOauth2Provider(name, scopes, r, clnt)
if err != nil {
// Upon error look for the next IDP.
continue
@@ -278,7 +277,7 @@ func (client *Provider) VerifyIdentity(ctx context.Context, code, state, roleARN
return nil, err
}
getWebTokenExpiry := func() (*credentials.WebIdentityToken, error) {
customCtx := context.WithValue(ctx, oauth2.HTTPClient, client.provHTTPClient)
customCtx := context.WithValue(ctx, oauth2.HTTPClient, client.client)
oauth2Token, err := client.oauth2Config.Exchange(customCtx, code)
if err != nil {
return nil, err
@@ -328,7 +327,7 @@ func (client *Provider) VerifyIdentity(ctx context.Context, code, state, roleARN
stsEndpoint := GetSTSEndpoint()
sts := credentials.New(&credentials.STSWebIdentity{
Client: client.stsHTTPClient,
Client: client.client,
STSEndpoint: stsEndpoint,
GetWebIDTokenExpiry: getWebTokenExpiry,
RoleARN: roleARN,
@@ -342,7 +341,7 @@ func (client *Provider) VerifyIdentityForOperator(ctx context.Context, code, sta
if err := validateOauth2State(state, keyFunc); err != nil {
return nil, err
}
customCtx := context.WithValue(ctx, oauth2.HTTPClient, client.provHTTPClient)
customCtx := context.WithValue(ctx, oauth2.HTTPClient, client.client)
oauth2Token, err := client.oauth2Config.Exchange(customCtx, code)
if err != nil {
return nil, err

View File

@@ -703,6 +703,9 @@ paths:
in: query
required: true
type: string
- name: versionID
in: query
type: string
responses:
200:
description: A successful response.
@@ -4219,6 +4222,8 @@ definitions:
type: string
tags:
type: string
replicateExistingObjects:
type: boolean
replicateDeleteMarkers:
type: boolean
replicateDeletes:

View File

@@ -1,10 +1,10 @@
{
"files": {
"main.css": "./static/css/main.e60e4760.css",
"main.js": "./static/js/main.6d775e33.js",
"main.js": "./static/js/main.bc79b8d1.js",
"static/js/5301.2c626a41.chunk.js": "./static/js/5301.2c626a41.chunk.js",
"static/js/9361.3fc638a6.chunk.js": "./static/js/9361.3fc638a6.chunk.js",
"static/js/843.8502a4fd.chunk.js": "./static/js/843.8502a4fd.chunk.js",
"static/js/843.d7a5defb.chunk.js": "./static/js/843.d7a5defb.chunk.js",
"static/js/3035.b2eb0918.chunk.js": "./static/js/3035.b2eb0918.chunk.js",
"static/js/9537.675a2ebb.chunk.js": "./static/js/9537.675a2ebb.chunk.js",
"static/js/5711.c58de6bb.chunk.js": "./static/js/5711.c58de6bb.chunk.js",
@@ -12,7 +12,7 @@
"static/js/2033.a09fb9da.chunk.js": "./static/js/2033.a09fb9da.chunk.js",
"static/js/8821.44b4fe0f.chunk.js": "./static/js/8821.44b4fe0f.chunk.js",
"static/js/9987.15024980.chunk.js": "./static/js/9987.15024980.chunk.js",
"static/js/689.d9f80e6e.chunk.js": "./static/js/689.d9f80e6e.chunk.js",
"static/js/689.5e705237.chunk.js": "./static/js/689.5e705237.chunk.js",
"static/js/6164.993b302b.chunk.js": "./static/js/6164.993b302b.chunk.js",
"static/js/2372.aaeaeefa.chunk.js": "./static/js/2372.aaeaeefa.chunk.js",
"static/js/1324.beff0285.chunk.js": "./static/js/1324.beff0285.chunk.js",
@@ -21,7 +21,7 @@
"static/js/6758.b6da6dc7.chunk.js": "./static/js/6758.b6da6dc7.chunk.js",
"static/js/755.ac098541.chunk.js": "./static/js/755.ac098541.chunk.js",
"static/js/8715.0aaa4c38.chunk.js": "./static/js/8715.0aaa4c38.chunk.js",
"static/js/7880.6f98d22b.chunk.js": "./static/js/7880.6f98d22b.chunk.js",
"static/js/7880.d04a7a8e.chunk.js": "./static/js/7880.d04a7a8e.chunk.js",
"static/js/2209.3b0ca7fa.chunk.js": "./static/js/2209.3b0ca7fa.chunk.js",
"static/js/7435.eb0888fa.chunk.js": "./static/js/7435.eb0888fa.chunk.js",
"static/js/9340.8c56fae7.chunk.js": "./static/js/9340.8c56fae7.chunk.js",
@@ -40,7 +40,7 @@
"static/js/4103.b6a51725.chunk.js": "./static/js/4103.b6a51725.chunk.js",
"static/js/1702.9ff3a82e.chunk.js": "./static/js/1702.9ff3a82e.chunk.js",
"static/js/7601.4e033e78.chunk.js": "./static/js/7601.4e033e78.chunk.js",
"static/js/2959.25a10423.chunk.js": "./static/js/2959.25a10423.chunk.js",
"static/js/2959.e0878952.chunk.js": "./static/js/2959.e0878952.chunk.js",
"static/js/9619.572ad00d.chunk.js": "./static/js/9619.572ad00d.chunk.js",
"static/js/8017.d5b163f3.chunk.js": "./static/js/8017.d5b163f3.chunk.js",
"static/js/3323.f86a698b.chunk.js": "./static/js/3323.f86a698b.chunk.js",
@@ -72,7 +72,7 @@
"static/js/12.ab9b7ed0.chunk.js": "./static/js/12.ab9b7ed0.chunk.js",
"static/js/8010.8ce54818.chunk.js": "./static/js/8010.8ce54818.chunk.js",
"static/js/2689.5e76c1cd.chunk.js": "./static/js/2689.5e76c1cd.chunk.js",
"static/js/872.aa8f9f90.chunk.js": "./static/js/872.aa8f9f90.chunk.js",
"static/js/872.6f58df17.chunk.js": "./static/js/872.6f58df17.chunk.js",
"static/js/4676.578844c1.chunk.js": "./static/js/4676.578844c1.chunk.js",
"static/js/8825.e5adf924.chunk.js": "./static/js/8825.e5adf924.chunk.js",
"static/js/614.f6cdf349.chunk.js": "./static/js/614.f6cdf349.chunk.js",
@@ -92,7 +92,7 @@
"static/js/1303.12f6ca82.chunk.js": "./static/js/1303.12f6ca82.chunk.js",
"static/js/5079.a0847792.chunk.js": "./static/js/5079.a0847792.chunk.js",
"static/js/4581.41480fcf.chunk.js": "./static/js/4581.41480fcf.chunk.js",
"static/js/6016.dcb3bcb4.chunk.js": "./static/js/6016.dcb3bcb4.chunk.js",
"static/js/6016.3475b798.chunk.js": "./static/js/6016.3475b798.chunk.js",
"static/js/8144.0cc85475.chunk.js": "./static/js/8144.0cc85475.chunk.js",
"static/js/1195.955963a0.chunk.js": "./static/js/1195.955963a0.chunk.js",
"static/js/1011.13d372c8.chunk.js": "./static/js/1011.13d372c8.chunk.js",
@@ -119,10 +119,10 @@
"static/media/placeholderimage.png": "./static/media/placeholderimage.077ea48bd1ef1f4a883f.png",
"index.html": "./index.html",
"main.e60e4760.css.map": "./static/css/main.e60e4760.css.map",
"main.6d775e33.js.map": "./static/js/main.6d775e33.js.map",
"main.bc79b8d1.js.map": "./static/js/main.bc79b8d1.js.map",
"5301.2c626a41.chunk.js.map": "./static/js/5301.2c626a41.chunk.js.map",
"9361.3fc638a6.chunk.js.map": "./static/js/9361.3fc638a6.chunk.js.map",
"843.8502a4fd.chunk.js.map": "./static/js/843.8502a4fd.chunk.js.map",
"843.d7a5defb.chunk.js.map": "./static/js/843.d7a5defb.chunk.js.map",
"3035.b2eb0918.chunk.js.map": "./static/js/3035.b2eb0918.chunk.js.map",
"9537.675a2ebb.chunk.js.map": "./static/js/9537.675a2ebb.chunk.js.map",
"5711.c58de6bb.chunk.js.map": "./static/js/5711.c58de6bb.chunk.js.map",
@@ -130,7 +130,7 @@
"2033.a09fb9da.chunk.js.map": "./static/js/2033.a09fb9da.chunk.js.map",
"8821.44b4fe0f.chunk.js.map": "./static/js/8821.44b4fe0f.chunk.js.map",
"9987.15024980.chunk.js.map": "./static/js/9987.15024980.chunk.js.map",
"689.d9f80e6e.chunk.js.map": "./static/js/689.d9f80e6e.chunk.js.map",
"689.5e705237.chunk.js.map": "./static/js/689.5e705237.chunk.js.map",
"6164.993b302b.chunk.js.map": "./static/js/6164.993b302b.chunk.js.map",
"2372.aaeaeefa.chunk.js.map": "./static/js/2372.aaeaeefa.chunk.js.map",
"1324.beff0285.chunk.js.map": "./static/js/1324.beff0285.chunk.js.map",
@@ -139,7 +139,7 @@
"6758.b6da6dc7.chunk.js.map": "./static/js/6758.b6da6dc7.chunk.js.map",
"755.ac098541.chunk.js.map": "./static/js/755.ac098541.chunk.js.map",
"8715.0aaa4c38.chunk.js.map": "./static/js/8715.0aaa4c38.chunk.js.map",
"7880.6f98d22b.chunk.js.map": "./static/js/7880.6f98d22b.chunk.js.map",
"7880.d04a7a8e.chunk.js.map": "./static/js/7880.d04a7a8e.chunk.js.map",
"2209.3b0ca7fa.chunk.js.map": "./static/js/2209.3b0ca7fa.chunk.js.map",
"7435.eb0888fa.chunk.js.map": "./static/js/7435.eb0888fa.chunk.js.map",
"9340.8c56fae7.chunk.js.map": "./static/js/9340.8c56fae7.chunk.js.map",
@@ -158,7 +158,7 @@
"4103.b6a51725.chunk.js.map": "./static/js/4103.b6a51725.chunk.js.map",
"1702.9ff3a82e.chunk.js.map": "./static/js/1702.9ff3a82e.chunk.js.map",
"7601.4e033e78.chunk.js.map": "./static/js/7601.4e033e78.chunk.js.map",
"2959.25a10423.chunk.js.map": "./static/js/2959.25a10423.chunk.js.map",
"2959.e0878952.chunk.js.map": "./static/js/2959.e0878952.chunk.js.map",
"9619.572ad00d.chunk.js.map": "./static/js/9619.572ad00d.chunk.js.map",
"8017.d5b163f3.chunk.js.map": "./static/js/8017.d5b163f3.chunk.js.map",
"3323.f86a698b.chunk.js.map": "./static/js/3323.f86a698b.chunk.js.map",
@@ -190,7 +190,7 @@
"12.ab9b7ed0.chunk.js.map": "./static/js/12.ab9b7ed0.chunk.js.map",
"8010.8ce54818.chunk.js.map": "./static/js/8010.8ce54818.chunk.js.map",
"2689.5e76c1cd.chunk.js.map": "./static/js/2689.5e76c1cd.chunk.js.map",
"872.aa8f9f90.chunk.js.map": "./static/js/872.aa8f9f90.chunk.js.map",
"872.6f58df17.chunk.js.map": "./static/js/872.6f58df17.chunk.js.map",
"4676.578844c1.chunk.js.map": "./static/js/4676.578844c1.chunk.js.map",
"8825.e5adf924.chunk.js.map": "./static/js/8825.e5adf924.chunk.js.map",
"614.f6cdf349.chunk.js.map": "./static/js/614.f6cdf349.chunk.js.map",
@@ -210,13 +210,13 @@
"1303.12f6ca82.chunk.js.map": "./static/js/1303.12f6ca82.chunk.js.map",
"5079.a0847792.chunk.js.map": "./static/js/5079.a0847792.chunk.js.map",
"4581.41480fcf.chunk.js.map": "./static/js/4581.41480fcf.chunk.js.map",
"6016.dcb3bcb4.chunk.js.map": "./static/js/6016.dcb3bcb4.chunk.js.map",
"6016.3475b798.chunk.js.map": "./static/js/6016.3475b798.chunk.js.map",
"8144.0cc85475.chunk.js.map": "./static/js/8144.0cc85475.chunk.js.map",
"1195.955963a0.chunk.js.map": "./static/js/1195.955963a0.chunk.js.map",
"1011.13d372c8.chunk.js.map": "./static/js/1011.13d372c8.chunk.js.map"
},
"entrypoints": [
"static/css/main.e60e4760.css",
"static/js/main.6d775e33.js"
"static/js/main.bc79b8d1.js"
]
}

View File

@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><base href="/"/><meta content="width=device-width,initial-scale=1" name="viewport"/><meta content="#081C42" media="(prefers-color-scheme: light)" name="theme-color"/><meta content="#081C42" media="(prefers-color-scheme: dark)" name="theme-color"/><meta content="MinIO Console" name="description"/><meta name="minio-license" content="agpl"/><link href="./styles/root-styles.css" rel="stylesheet"/><link href="./apple-icon-180x180.png" rel="apple-touch-icon" sizes="180x180"/><link href="./favicon-32x32.png" rel="icon" sizes="32x32" type="image/png"/><link href="./favicon-96x96.png" rel="icon" sizes="96x96" type="image/png"/><link href="./favicon-16x16.png" rel="icon" sizes="16x16" type="image/png"/><link href="./manifest.json" rel="manifest"/><link color="#3a4e54" href="./safari-pinned-tab.svg" rel="mask-icon"/><title>MinIO Console</title><script defer="defer" src="./static/js/main.6d775e33.js"></script><link href="./static/css/main.e60e4760.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"><div id="preload"><img src="./images/background.svg"/> <img src="./images/background-wave-orig2.svg"/></div><div id="loader-block"><img src="./Loader.svg"/></div></div></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><base href="/"/><meta content="width=device-width,initial-scale=1" name="viewport"/><meta content="#081C42" media="(prefers-color-scheme: light)" name="theme-color"/><meta content="#081C42" media="(prefers-color-scheme: dark)" name="theme-color"/><meta content="MinIO Console" name="description"/><meta name="minio-license" content="agpl"/><link href="./styles/root-styles.css" rel="stylesheet"/><link href="./apple-icon-180x180.png" rel="apple-touch-icon" sizes="180x180"/><link href="./favicon-32x32.png" rel="icon" sizes="32x32" type="image/png"/><link href="./favicon-96x96.png" rel="icon" sizes="96x96" type="image/png"/><link href="./favicon-16x16.png" rel="icon" sizes="16x16" type="image/png"/><link href="./manifest.json" rel="manifest"/><link color="#3a4e54" href="./safari-pinned-tab.svg" rel="mask-icon"/><title>MinIO Console</title><script defer="defer" src="./static/js/main.bc79b8d1.js"></script><link href="./static/css/main.e60e4760.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"><div id="preload"><img src="./images/background.svg"/> <img src="./images/background-wave-orig2.svg"/></div><div id="loader-block"><img src="./Loader.svg"/></div></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -85,7 +85,7 @@
*/
/**
* @remix-run/router v1.15.3
* @remix-run/router v1.16.0
*
* Copyright (c) Remix Software Inc.
*
@@ -96,7 +96,7 @@
*/
/**
* React Router DOM v6.22.3
* React Router DOM v6.23.0
*
* Copyright (c) Remix Software Inc.
*
@@ -107,7 +107,7 @@
*/
/**
* React Router v6.22.3
* React Router v6.23.0
*
* Copyright (c) Remix Software Inc.
*

File diff suppressed because one or more lines are too long

View File

@@ -11,23 +11,24 @@
"local-storage-fallback": "^4.1.1",
"lodash": "^4.17.21",
"luxon": "^3.4.3",
"mds": "https://github.com/minio/mds.git#v1.0.0",
"mds": "https://github.com/minio/mds.git#v1.0.2",
"pdfjs-dist": "3.11.174",
"react": "^18.1.0",
"react": "^18.3.1",
"react-component-export-image": "^1.0.6",
"react-copy-to-clipboard": "^5.0.2",
"react-dom": "^18.1.0",
"react-dom": "^18.3.1",
"react-dropzone": "^14.2.3",
"react-markdown": "8.0.7",
"react-pdf": "7.7.1",
"react-redux": "^8.1.3",
"react-router-dom": "6.22.3",
"react-router-dom": "6.23.0",
"react-use-websocket": "^4.8.1",
"react-virtualized": "^9.22.5",
"react-window": "^1.8.10",
"react-window-infinite-loader": "^1.0.9",
"recharts": "^2.12.4",
"recharts": "^2.12.6",
"styled-components": "5.3.11",
"superagent": "^8.0.8",
"superagent": "^9.0.2",
"tinycolor2": "^1.6.0"
},
"scripts": {
@@ -60,14 +61,13 @@
"proxy": "http://localhost:9090/",
"devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@playwright/test": "^1.43.0",
"@playwright/test": "^1.43.1",
"@types/lodash": "^4.17.0",
"@types/luxon": "^3.4.2",
"@types/minio": "7.1.1",
"@types/node": "18.16.0",
"@types/react": "18.2.75",
"@types/node": "20.12.8",
"@types/react": "18.3.1",
"@types/react-copy-to-clipboard": "^5.0.5",
"@types/react-dom": "18.2.24",
"@types/react-dom": "18.3.0",
"@types/react-redux": "^7.1.32",
"@types/react-virtualized": "^9.21.30",
"@types/react-window": "^1.8.6",
@@ -77,19 +77,19 @@
"@types/webpack-env": "^1.18.2",
"babel-plugin-istanbul": "^6.1.1",
"customize-cra": "^1.0.0",
"minio": "^7.1.3",
"minio": "^8.0.0",
"nyc": "^15.1.0",
"prettier": "3.2.5",
"react-app-rewire-hot-loader": "^2.0.1",
"react-app-rewired": "^2.2.1",
"react-scripts": "5.0.1",
"testcafe": "^2.6.2",
"testcafe": "3.5.0",
"ts-prune": "^0.10.3",
"typescript": "^4.4.3"
},
"resolutions": {
"nth-check": "^2.0.1",
"yaml": "^2.4.1",
"yaml": "^2.4.2",
"postcss": "^8.4.38",
"react-scripts/**/node-forge": "^1.3.0",
"react-scripts/**/async": "^2.6.4",
@@ -103,8 +103,8 @@
"recharts/**/d3-color": "^3.1.0",
"fast-xml-parser": "^4.3.6",
"semver": "^7.5.2",
"testcafe/**/tough-cookie": "^4.1.3",
"styled-components/**/@babel/traverse": "^7.24.1"
"testcafe/**/tough-cookie": "^4.1.4",
"styled-components/**/@babel/traverse": "^7.24.5"
},
"main": "index.js"
}

View File

@@ -385,6 +385,7 @@ export interface MultiBucketReplication {
healthCheckPeriod?: number;
prefix?: string;
tags?: string;
replicateExistingObjects?: boolean;
replicateDeleteMarkers?: boolean;
replicateDeletes?: boolean;
replicateMetadata?: boolean;
@@ -2397,6 +2398,7 @@ export class Api<
bucketName: string,
query: {
prefix: string;
versionID?: string;
},
params: RequestParams = {},
) =>

View File

@@ -60,7 +60,7 @@ const AddBucketReplication = () => {
const [repDeleteMarker, setRepDeleteMarker] = useState<boolean>(true);
const [repDelete, setRepDelete] = useState<boolean>(true);
const [metadataSync, setMetadataSync] = useState<boolean>(true);
const [repExisting, setRepExisting] = useState<boolean>(false);
const [repExisting, setRepExisting] = useState<boolean>(true);
const [tags, setTags] = useState<string>("");
const [replicationMode, setReplicationMode] = useState<"async" | "sync">(
"async",
@@ -124,8 +124,8 @@ const AddBucketReplication = () => {
if (itemVal.errorString && itemVal.errorString !== "") {
dispatch(
setErrorSnackMessage({
errorMessage: itemVal.errorString,
detailedError: "There was an error",
errorMessage: "There was an error",
detailedError: itemVal.errorString,
}),
);
// navigate(backLink);
@@ -201,11 +201,10 @@ const AddBucketReplication = () => {
</Box>
<Box sx={{ paddingTop: "10px" }}>
MinIO supports automatically replicating existing objects in
a bucket, however it does not enable existing object
replication by default. Objects created before replication
was configured or while replication is disabled are not
synchronized to the target deployment unless replication of
existing objects is enabled.
a bucket; this setting is enabled by default. Please note
that objects created before replication was configured or
while replication is disabled are not synchronized to the
target deployment in case this setting is not enabled.
</Box>
<Box sx={{ paddingTop: "10px" }}>
MinIO supports replicating delete operations, where MinIO

View File

@@ -188,6 +188,21 @@ const BucketLifecyclePanel = () => {
}
},
},
{
label: "Expire Delete Marker",
elementKey: "expire_delete_marker",
renderFunction: (el: LifeCycleItem) => {
if (!el) {
return <Fragment />;
}
if (el.expiration && el.expiration.delete_marker !== undefined) {
return <span>{el.expiration.delete_marker ? "true" : "false"}</span>;
} else {
return <Fragment />;
}
},
renderFullObject: true,
},
{
label: "Tier",
elementKey: "storage_class",

View File

@@ -216,6 +216,7 @@ const ObjectDetailPanel = ({
api.buckets
.getObjectMetadata(bucketName, {
prefix: internalPaths,
versionID: actualInfo?.version_id || "",
})
.then((res) => {
let metadata = get(res.data, "objectMetadata", {});
@@ -228,7 +229,7 @@ const ObjectDetailPanel = ({
setLoadingMetadata(false);
});
}
}, [bucketName, internalPaths, loadMetadata]);
}, [bucketName, internalPaths, loadMetadata, actualInfo?.version_id]);
let tagKeys: string[] = [];

View File

@@ -51,6 +51,7 @@ const PreviewFile = ({
api.buckets
.getObjectMetadata(bucketName, {
prefix: encodedPath,
versionID: actualInfo.version_id || "",
})
.then((res) => {
let metadata = get(res.data, "objectMetadata", {});
@@ -66,7 +67,7 @@ const PreviewFile = ({
setIsMetaDataLoaded(true);
});
}
}, [bucketName, objectName, isMetaDataLoaded]);
}, [bucketName, objectName, isMetaDataLoaded, actualInfo.version_id]);
useEffect(() => {
if (bucketName && objectName) {

View File

@@ -202,9 +202,6 @@ const AddTierConfiguration = () => {
if (bucket === "") {
valid = false;
}
if (prefix === "") {
valid = false;
}
if (region === "" && type !== "minio") {
valid = false;
}
@@ -445,7 +442,6 @@ const AddTierConfiguration = () => {
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setPrefix(e.target.value);
}}
required
/>
<RegionSelectWrapper
onChange={(value) => {

View File

@@ -14,7 +14,7 @@
// 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/>.
import React, { Fragment, useEffect, useState } from "react";
import { Fragment, useEffect, useState } from "react";
import { DateTime } from "luxon";
import { useSelector } from "react-redux";
import {
@@ -41,8 +41,7 @@ import { setHelpName } from "../../../systemSlice";
import TooltipWrapper from "../Common/TooltipWrapper/TooltipWrapper";
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";
import HelpMenu from "../HelpMenu";
var socket: any = null;
import useWebSocket, { ReadyState } from "react-use-websocket";
const Trace = () => {
const dispatch = useAppDispatch();
@@ -65,68 +64,82 @@ const Trace = () => {
const [errors, setErrors] = useState<boolean>(false);
const [toggleFilter, setToggleFilter] = useState<boolean>(false);
const [logActive, setLogActive] = useState(false);
const [wsUrl, setWsUrl] = useState<string>("");
const startTrace = () => {
dispatch(traceResetMessages());
useEffect(() => {
const url = new URL(window.location.toString());
const isDev = process.env.NODE_ENV === "development";
const port = isDev ? "9090" : url.port;
let calls = `${s3 ? "s3," : ""}${internal ? "internal," : ""}${
storage ? "storage," : ""
}${os ? "os," : ""}`;
if (all) {
calls = "all";
}
// check if we are using base path, if not this always is `/`
const baseLocation = new URL(document.baseURI);
const baseUrl = baseLocation.pathname;
const wsProt = wsProtocol(url.protocol);
socket = new WebSocket(
`${wsProt}://${
url.hostname
}:${port}${baseUrl}ws/trace?calls=${calls}&threshold=${threshold}&onlyErrors=${
errors ? "yes" : "no"
}&statusCode=${statusCode}&method=${method}&funcname=${func}&path=${path}`,
const port = process.env.NODE_ENV === "development" ? "9090" : url.port;
const calls = all
? "all"
: (() => {
const c = [];
if (s3) c.push("s3");
if (internal) c.push("internal");
if (storage) c.push("storage");
if (os) c.push("os");
return c.join(",");
})();
// check if we are using base path, if not this always is `/`
const baseLocation = new URL(document.baseURI).pathname;
const wsUrl = new URL(
`${wsProt}://${url.hostname}:${port}${baseLocation}ws/trace`,
);
wsUrl.searchParams.append("calls", calls);
wsUrl.searchParams.append("threshold", threshold.toString());
wsUrl.searchParams.append("onlyErrors", errors ? "yes" : "no");
wsUrl.searchParams.append("statusCode", statusCode);
wsUrl.searchParams.append("method", method);
wsUrl.searchParams.append("funcname", func);
wsUrl.searchParams.append("path", path);
setWsUrl(wsUrl.href);
}, [
all,
s3,
internal,
storage,
os,
threshold,
errors,
statusCode,
method,
func,
path,
]);
const { sendMessage, lastJsonMessage, readyState } =
useWebSocket<TraceMessage>(
wsUrl,
{
heartbeat: {
message: "ok",
interval: 10 * 1000, // send ok every 10 seconds
timeout: 365 * 24 * 60 * 60 * 1000, // disconnect after 365 days (workaround, because heartbeat gets no response)
},
},
logActive,
);
let interval: any | null = null;
if (socket !== null) {
socket.onopen = () => {
console.log("WebSocket Client Connected");
dispatch(setTraceStarted(true));
socket.send("ok");
interval = setInterval(() => {
socket.send("ok");
}, 10 * 1000);
};
socket.onmessage = (message: MessageEvent) => {
let m: TraceMessage = JSON.parse(message.data.toString());
m.ptime = DateTime.fromISO(m.time).toJSDate();
m.key = Math.random();
dispatch(traceMessageReceived(m));
};
socket.onclose = () => {
clearInterval(interval);
console.log("connection closed by server");
dispatch(setTraceStarted(false));
};
return () => {
socket.close(1000);
clearInterval(interval);
console.log("closing websockets");
setTraceStarted(false);
};
useEffect(() => {
if (readyState === ReadyState.CONNECTING) {
dispatch(traceResetMessages());
} else if (readyState === ReadyState.OPEN) {
dispatch(setTraceStarted(true));
} else if (readyState === ReadyState.CLOSED) {
dispatch(setTraceStarted(false));
}
};
}, [readyState, dispatch, sendMessage]);
const stopTrace = () => {
socket.close(1000);
dispatch(setTraceStarted(false));
};
useEffect(() => {
if (lastJsonMessage) {
lastJsonMessage.ptime = DateTime.fromISO(lastJsonMessage.time).toJSDate();
lastJsonMessage.key = Math.random();
dispatch(traceMessageReceived(lastJsonMessage));
}
}, [lastJsonMessage, dispatch]);
useEffect(() => {
dispatch(setHelpName("trace"));
@@ -187,9 +200,7 @@ const Trace = () => {
id={"all_calls"}
name={"all_calls"}
label={"All"}
onChange={() => {
setAll(!all);
}}
onChange={() => setAll(!all)}
value={"all"}
disabled={traceStarted}
/>
@@ -198,9 +209,7 @@ const Trace = () => {
id={"s3_calls"}
name={"s3_calls"}
label={"S3"}
onChange={() => {
setS3(!s3);
}}
onChange={() => setS3(!s3)}
value={"s3"}
disabled={all || traceStarted}
/>
@@ -209,9 +218,7 @@ const Trace = () => {
id={"internal_calls"}
name={"internal_calls"}
label={"Internal"}
onChange={() => {
setInternal(!internal);
}}
onChange={() => setInternal(!internal)}
value={"internal"}
disabled={all || traceStarted}
/>
@@ -220,9 +227,7 @@ const Trace = () => {
id={"storage_calls"}
name={"storage_calls"}
label={"Storage"}
onChange={() => {
setStorage(!storage);
}}
onChange={() => setStorage(!storage)}
value={"storage"}
disabled={all || traceStarted}
/>
@@ -231,9 +236,7 @@ const Trace = () => {
id={"os_calls"}
name={"os_calls"}
label={"OS"}
onChange={() => {
setOS(!os);
}}
onChange={() => setOS(!os)}
value={"os"}
disabled={all || traceStarted}
/>
@@ -249,9 +252,7 @@ const Trace = () => {
<TooltipWrapper tooltip={"More filter options"}>
<Button
id={"filter-toggle"}
onClick={() => {
setToggleFilter(!toggleFilter);
}}
onClick={() => setToggleFilter(!toggleFilter)}
label={"Filters"}
icon={<FilterIcon />}
variant={"regular"}
@@ -269,7 +270,7 @@ const Trace = () => {
label={"Start"}
data-test-id={"trace-start-button"}
variant="callAction"
onClick={startTrace}
onClick={() => setLogActive(true)}
style={{
width: "118px",
}}
@@ -281,7 +282,7 @@ const Trace = () => {
label={"Stop Trace"}
data-test-id={"trace-stop-button"}
variant="callAction"
onClick={stopTrace}
onClick={() => setLogActive(false)}
style={{
width: "118px",
}}
@@ -330,9 +331,7 @@ const Trace = () => {
label="Status Code"
placeholder="e.g. 503"
value={statusCode}
onChange={(e) => {
setStatusCode(e.target.value);
}}
onChange={(e) => setStatusCode(e.target.value)}
disabled={traceStarted}
/>
@@ -343,9 +342,7 @@ const Trace = () => {
label="Function Name"
placeholder="e.g. FunctionName2055"
value={func}
onChange={(e) => {
setFunc(e.target.value);
}}
onChange={(e) => setFunc(e.target.value)}
disabled={traceStarted}
/>
@@ -356,9 +353,7 @@ const Trace = () => {
label="Method"
placeholder="e.g. Method 2056"
value={method}
onChange={(e) => {
setMethod(e.target.value);
}}
onChange={(e) => setMethod(e.target.value)}
disabled={traceStarted}
/>
</Box>
@@ -384,9 +379,7 @@ const Trace = () => {
label="Path"
placeholder="e.g. my-bucket/my-prefix/*"
value={path}
onChange={(e) => {
setPath(e.target.value);
}}
onChange={(e) => setPath(e.target.value)}
disabled={traceStarted}
/>
</Box>
@@ -403,9 +396,7 @@ const Trace = () => {
type="number"
placeholder="e.g. website.io.3249.114.12"
value={`${threshold}`}
onChange={(e) => {
setThreshold(parseInt(e.target.value));
}}
onChange={(e) => setThreshold(parseInt(e.target.value))}
disabled={traceStarted}
/>
</Box>
@@ -423,9 +414,7 @@ const Trace = () => {
id={"only_errors"}
name={"only_errors"}
label={"Display only Errors"}
onChange={() => {
setErrors(!errors);
}}
onChange={() => setErrors(!errors)}
value={"only_errors"}
disabled={traceStarted}
/>

View File

@@ -33,13 +33,8 @@ export const setUpNamedBucket = (t, name) => {
accessKey: "minioadmin",
secretKey: "minioadmin",
});
return new Promise((resolve, reject) => {
minioClient.makeBucket(name, "us-east-1", (err) => {
if (err) {
console.log(err);
}
resolve("done: " + err);
});
return minioClient.makeBucket(name, "us-east-1").catch((err) => {
console.log(err);
});
};
@@ -48,7 +43,7 @@ export const uploadObjectToBucket = (t, modifier, objectName, objectPath) => {
return uploadNamedObjectToBucket(t, bucketName, objectName, objectPath);
};
export const uploadNamedObjectToBucket = (
export const uploadNamedObjectToBucket = async (
t,
modifier,
objectName,
@@ -62,14 +57,11 @@ export const uploadNamedObjectToBucket = (
accessKey: "minioadmin",
secretKey: "minioadmin",
});
return new Promise((resolve, reject) => {
minioClient.fPutObject(bucketName, objectName, objectPath, {}, (err) => {
if (err) {
console.log(err);
}
resolve("done");
return minioClient
.fPutObject(bucketName, objectName, objectPath, {})
.catch((err) => {
console.log(err);
});
});
};
export const setVersioned = (t, modifier) => {
@@ -139,9 +131,11 @@ export const cleanUpNamedBucketAndUploads = (t, bucket) => {
var stream = minioClient.listObjects(bucket, "", true);
let proms = [];
let proms: any[] = [];
stream.on("data", function (obj) {
proms.push(minioClient.removeObject(bucket, obj.name));
if (obj.name) {
proms.push(minioClient.removeObject(bucket, obj.name));
}
});
stream.on("end", () => {

File diff suppressed because it is too large Load Diff