Deprecated Site Replication in UI (#3469)

* Deprecated Sire Replication in UI

Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>

* fix-workflow-issue

---------

Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
Alex
2024-11-11 14:26:19 -06:00
committed by GitHub
parent 18e50975d4
commit 4e5dcf0fc3
53 changed files with 15 additions and 6455 deletions

View File

@@ -228,7 +228,7 @@ jobs:
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
run: npx testcafe "firefox:headless" web-app/tests/subpath-nginx/ -q --skip-js-errors -c 3
- name: Clean up docker
if: always()
@@ -282,7 +282,7 @@ jobs:
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
run: npx testcafe "firefox:headless" web-app/tests/permissions-1/ -q --skip-js-errors -c 3
- name: Clean up users & policies
run: |
@@ -334,7 +334,7 @@ jobs:
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
run: npx testcafe "firefox:headless" web-app/tests/permissions-2/ -q --skip-js-errors -c 3
- name: Clean up users & policies
run: |
@@ -386,7 +386,7 @@ jobs:
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
run: npx testcafe "firefox:headless" web-app/tests/permissions-3/ -q --skip-js-errors -c 3
- name: Clean up users & policies
run: |
@@ -439,7 +439,7 @@ jobs:
- name: Run TestCafe Tests
timeout-minutes: 10
run: npx testcafe "chrome:headless" web-app/tests/permissions-4/ --skip-js-errors
run: npx testcafe "firefox:headless" web-app/tests/permissions-4/ --skip-js-errors
all-permissions-5:
name: Permissions Tests Part 5
@@ -487,7 +487,7 @@ jobs:
- name: Run TestCafe Tests
timeout-minutes: 5
run: npx testcafe "chrome:headless" web-app/tests/permissions-5/ --skip-js-errors
run: npx testcafe "firefox:headless" web-app/tests/permissions-5/ --skip-js-errors
all-permissions-6:
name: Permissions Tests Part 6
@@ -535,7 +535,7 @@ jobs:
- name: Run TestCafe Tests
timeout-minutes: 5
run: npx testcafe "chrome:headless" web-app/tests/permissions-6/ --skip-js-errors
run: npx testcafe "firefox:headless" web-app/tests/permissions-6/ --skip-js-errors
all-permissions-7:
name: Permissions Tests Part 7
@@ -582,7 +582,7 @@ jobs:
- name: Run TestCafe Tests
timeout-minutes: 5
run: npx testcafe "chrome:headless" web-app/tests/permissions-7/ --skip-js-errors
run: npx testcafe "firefox:headless" web-app/tests/permissions-7/ --skip-js-errors
all-permissions-8:
name: Permissions Tests Part 8
@@ -630,7 +630,7 @@ jobs:
- name: Run TestCafe Tests
timeout-minutes: 5
run: npx testcafe "chrome:headless" web-app/tests/permissions-8/ --skip-js-errors
run: npx testcafe "firefox:headless" web-app/tests/permissions-8/ --skip-js-errors
all-permissions-A:
name: Permissions Tests Part A
@@ -677,7 +677,7 @@ jobs:
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
run: npx testcafe "firefox:headless" web-app/tests/permissions-A/ --skip-js-errors -c 3
- name: Clean up users & policies
run: |
@@ -728,7 +728,7 @@ jobs:
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
run: npx testcafe "firefox:headless" web-app/tests/permissions-B/ --skip-js-errors -c 3
- name: Clean up users & policies
run: |
@@ -900,88 +900,7 @@ jobs:
- name: Run tests
working-directory: ./web-app
run: yarn test
replication:
name: Site Replication Test
needs:
- lint-job
- ui-assets
- semgrep-static-code-analysis
- latest-minio
runs-on: [ubuntu-latest]
strategy:
matrix:
go-version: [1.22.x]
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
id: go
- name: Clone github.com/minio/minio
uses: actions/checkout@master
with:
repository: minio/minio
path: "minio_repository"
- name: Check-out matching MinIO branch
env:
GH_BRANCH: ${{ github.head_ref || github.ref_name }}
GH_PR_REPO: ${{ github.event.pull_request.head.repo.full_name }}
run: |
GH_PR_ACCOUNT=`echo $GH_PR_REPO | sed "s/\\/.*//"`
if [ ! -z "$GH_PR_ACCOUNT" ] && [ ! "$GH_PR_ACCOUNT" = "minio" ]; then
ALTREPO="https://github.com/$GH_PR_ACCOUNT/minio.git"
echo "Attempting to fetch $ALTREPO..."
git remote add alt $ALTREPO
(git fetch alt && git checkout "alt/$GH_BRANCH") || echo "$ALTREPO ($GH_BRANCH) not available, so keeping default repository/branch"
fi
- uses: actions/cache@v4
id: minio-latest-cache
name: MinIO Latest Cache
with:
path: |
./minio
key: ${{ runner.os }}-minio-latest-${{ hashFiles('./minio_repository/go.sum') }}
- name: Build on ${{ matrix.os }}
run: |
echo "The idea is to build minio image from downloaded repository";
cd $GITHUB_WORKSPACE/minio_repository;
echo "Get git version to build MinIO Image";
VERSION=`git rev-parse HEAD`;
echo $VERSION;
echo "Create MinIO image";
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";
MINIO_VERSION="minio/minio:$VERSION";
echo $MINIO_VERSION;
make test-replication MINIO_VERSION=$MINIO_VERSION;
- uses: actions/cache@v4
id: coverage-cache-replication
name: Coverage Cache Replication
with:
path: |
./replication/coverage/
key: ${{ runner.os }}-replication-coverage-2-${{ github.run_id }}
# To save our replication.out file into an artifact.
# By default, GitHub stores build logs and artifacts for 90 days.
- uses: actions/upload-artifact@v4
with:
name: replication-artifact
path: ./replication/coverage/replication.out
if-no-files-found: error
sso-integration:
name: SSO Integration Test
needs:
@@ -1074,7 +993,6 @@ jobs:
- test-api-on-go
- test-pkg-on-go
- sso-integration
- replication
runs-on: ${{ matrix.os }}
strategy:
matrix:
@@ -1110,14 +1028,6 @@ jobs:
./sso-integration/coverage/
key: ${{ runner.os }}-sso-coverage-2-${{ github.run_id }}
- uses: actions/cache@v4
id: coverage-cache-replication
name: Coverage Cache Replication
with:
path: |
./replication/coverage/
key: ${{ runner.os }}-replication-coverage-2-${{ github.run_id }}
- uses: actions/cache@v4
id: coverage-cache-api
name: Coverage Cache API
@@ -1134,12 +1044,6 @@ jobs:
./pkg/coverage/
key: ${{ runner.os }}-coverage-pkg-2-${{ github.run_id }}
# Get the replication.out file from the artifact since this is working for self host runner.
- uses: actions/download-artifact@v4
with:
name: replication-artifact
path: replication/coverage
- name: Get coverage
run: |
echo "change directory to gocovmerge"
@@ -1151,12 +1055,12 @@ jobs:
echo "go build gocoverage.go"
go build gocovmerge.go
echo "put together the outs for final coverage resolution"
./gocovmerge ../integration/coverage/system.out ../replication/coverage/replication.out ../sso-integration/coverage/sso-system.out ../api/coverage/coverage.out ../pkg/coverage/coverage-pkg.out > all.out
./gocovmerge ../integration/coverage/system.out ../sso-integration/coverage/sso-system.out ../api/coverage/coverage.out ../pkg/coverage/coverage-pkg.out > all.out
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 "Only run our test if play is up and running since we require it for replication tests here."
echo "Only run our test if play is up and running"
PLAY_IS_ON=`wget --spider --server-response https://play.min.io:9443/login 2>&1 | grep '200\ OK' | wc -l`
if [ $PLAY_IS_ON == 1 ]
then
@@ -1180,11 +1084,6 @@ jobs:
./mc cp system.html play/builds/${{ github.repository }}/${{ github.event.number }}/latest/ || true
./mc cp ../integration/coverage/system.out play/builds/${{ github.repository }}/${{ github.event.number }}/${{ github.run_id }}/ || true
./mc cp ../integration/coverage/system.out play/builds/${{ github.repository }}/${{ github.event.number }}/latest/ || true
go tool cover -html=../replication/coverage/replication.out -o replication.html
./mc cp replication.html play/builds/${{ github.repository }}/${{ github.event.number }}/${{ github.run_id }}/ || true
./mc cp replication.html play/builds/${{ github.repository }}/${{ github.event.number }}/latest/ || true
./mc cp ../replication/coverage/replication.out play/builds/${{ github.repository }}/${{ github.event.number }}/${{ github.run_id }}/ || true
./mc cp ../replication/coverage/replication.out play/builds/${{ github.repository }}/${{ github.event.number }}/latest/ || true
go tool cover -html=../sso-integration/coverage/sso-system.out -o sso-system.html
./mc cp sso-system.html play/builds/${{ github.repository }}/${{ github.event.number }}/${{ github.run_id }}/ || true
./mc cp sso-system.html play/builds/${{ github.repository }}/${{ github.event.number }}/latest/ || true

View File

@@ -1,86 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package api
import (
"context"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/api/operations"
siteRepApi "github.com/minio/console/api/operations/site_replication"
"github.com/minio/console/models"
"github.com/minio/madmin-go/v3"
)
func registerSiteReplicationStatusHandler(api *operations.ConsoleAPI) {
api.SiteReplicationGetSiteReplicationStatusHandler = siteRepApi.GetSiteReplicationStatusHandlerFunc(func(params siteRepApi.GetSiteReplicationStatusParams, session *models.Principal) middleware.Responder {
rInfo, err := getSRStatusResponse(session, params)
if err != nil {
return siteRepApi.NewGetSiteReplicationStatusDefault(err.Code).WithPayload(err.APIError)
}
return siteRepApi.NewGetSiteReplicationStatusOK().WithPayload(rInfo)
})
}
func getSRStatusResponse(session *models.Principal, params siteRepApi.GetSiteReplicationStatusParams) (*models.SiteReplicationStatusResponse, *CodedAPIError) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
adminClient := AdminClient{Client: mAdmin}
res, err := getSRStats(ctx, adminClient, params)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
return res, nil
}
func getSRStats(ctx context.Context, client MinioAdmin, params siteRepApi.GetSiteReplicationStatusParams) (info *models.SiteReplicationStatusResponse, err error) {
srParams := madmin.SRStatusOptions{
Buckets: *params.Buckets,
Policies: *params.Policies,
Users: *params.Users,
Groups: *params.Groups,
}
if params.EntityType != nil && params.EntityValue != nil {
srParams.Entity = madmin.GetSREntityType(*params.EntityType)
srParams.EntityValue = *params.EntityValue
}
srInfo, err := client.getSiteReplicationStatus(ctx, srParams)
retInfo := models.SiteReplicationStatusResponse{
BucketStats: &srInfo.BucketStats,
Enabled: srInfo.Enabled,
GroupStats: srInfo.GroupStats,
MaxBuckets: int64(srInfo.MaxBuckets),
MaxGroups: int64(srInfo.MaxGroups),
MaxPolicies: int64(srInfo.MaxPolicies),
MaxUsers: int64(srInfo.MaxUsers),
PolicyStats: &srInfo.PolicyStats,
Sites: &srInfo.Sites,
StatsSummary: srInfo.StatsSummary,
UserStats: &srInfo.UserStats,
}
if err != nil {
return nil, err
}
return &retInfo, nil
}

View File

@@ -1,242 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package api
import (
"context"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/api/operations"
siteRepApi "github.com/minio/console/api/operations/site_replication"
"github.com/minio/console/models"
"github.com/minio/madmin-go/v3"
)
func registerSiteReplicationHandler(api *operations.ConsoleAPI) {
api.SiteReplicationGetSiteReplicationInfoHandler = siteRepApi.GetSiteReplicationInfoHandlerFunc(func(params siteRepApi.GetSiteReplicationInfoParams, session *models.Principal) middleware.Responder {
rInfo, err := getSRInfoResponse(session, params)
if err != nil {
return siteRepApi.NewGetSiteReplicationInfoDefault(err.Code).WithPayload(err.APIError)
}
return siteRepApi.NewGetSiteReplicationInfoOK().WithPayload(rInfo)
})
api.SiteReplicationSiteReplicationInfoAddHandler = siteRepApi.SiteReplicationInfoAddHandlerFunc(func(params siteRepApi.SiteReplicationInfoAddParams, session *models.Principal) middleware.Responder {
eInfo, err := getSRAddResponse(session, params)
if err != nil {
return siteRepApi.NewSiteReplicationInfoAddDefault(err.Code).WithPayload(err.APIError)
}
return siteRepApi.NewSiteReplicationInfoAddOK().WithPayload(eInfo)
})
api.SiteReplicationSiteReplicationRemoveHandler = siteRepApi.SiteReplicationRemoveHandlerFunc(func(params siteRepApi.SiteReplicationRemoveParams, session *models.Principal) middleware.Responder {
remRes, err := getSRRemoveResponse(session, params)
if err != nil {
return siteRepApi.NewSiteReplicationRemoveDefault(err.Code).WithPayload(err.APIError)
}
return siteRepApi.NewSiteReplicationRemoveNoContent().WithPayload(remRes)
})
api.SiteReplicationSiteReplicationEditHandler = siteRepApi.SiteReplicationEditHandlerFunc(func(params siteRepApi.SiteReplicationEditParams, session *models.Principal) middleware.Responder {
eInfo, err := getSREditResponse(session, params)
if err != nil {
return siteRepApi.NewSiteReplicationRemoveDefault(err.Code).WithPayload(err.APIError)
}
return siteRepApi.NewSiteReplicationEditOK().WithPayload(eInfo)
})
}
func getSRInfoResponse(session *models.Principal, params siteRepApi.GetSiteReplicationInfoParams) (*models.SiteReplicationInfoResponse, *CodedAPIError) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
adminClient := AdminClient{Client: mAdmin}
res, err := getSRConfig(ctx, adminClient)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
return res, nil
}
func getSRAddResponse(session *models.Principal, params siteRepApi.SiteReplicationInfoAddParams) (*models.SiteReplicationAddResponse, *CodedAPIError) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
adminClient := AdminClient{Client: mAdmin}
res, err := addSiteReplication(ctx, adminClient, &params)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
return res, nil
}
func getSREditResponse(session *models.Principal, params siteRepApi.SiteReplicationEditParams) (*models.PeerSiteEditResponse, *CodedAPIError) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
adminClient := AdminClient{Client: mAdmin}
eRes, err := editSiteReplication(ctx, adminClient, &params)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
return eRes, nil
}
func getSRRemoveResponse(session *models.Principal, params siteRepApi.SiteReplicationRemoveParams) (*models.PeerSiteRemoveResponse, *CodedAPIError) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
adminClient := AdminClient{Client: mAdmin}
rRes, err := removeSiteReplication(ctx, adminClient, &params)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
return rRes, nil
}
func getSRConfig(ctx context.Context, client MinioAdmin) (info *models.SiteReplicationInfoResponse, err error) {
srInfo, err := client.getSiteReplicationInfo(ctx)
if err != nil {
return nil, err
}
var sites []*models.PeerInfo
if len(srInfo.Sites) > 0 {
for _, s := range srInfo.Sites {
pInfo := &models.PeerInfo{
DeploymentID: s.DeploymentID,
Endpoint: s.Endpoint,
Name: s.Name,
}
sites = append(sites, pInfo)
}
}
res := &models.SiteReplicationInfoResponse{
Enabled: srInfo.Enabled,
Name: srInfo.Name,
ServiceAccountAccessKey: srInfo.ServiceAccountAccessKey,
Sites: sites,
}
return res, nil
}
func addSiteReplication(ctx context.Context, client MinioAdmin, params *siteRepApi.SiteReplicationInfoAddParams) (info *models.SiteReplicationAddResponse, err error) {
var rSites []madmin.PeerSite
if len(params.Body) > 0 {
for _, aSite := range params.Body {
pInfo := &madmin.PeerSite{
AccessKey: aSite.AccessKey,
Name: aSite.Name,
SecretKey: aSite.SecretKey,
Endpoint: aSite.Endpoint,
}
rSites = append(rSites, *pInfo)
}
}
qs := runtime.Values(params.HTTPRequest.URL.Query())
_, qhkReplicateILMExpiry, _ := qs.GetOK("replicate-ilm-expiry")
var opts madmin.SRAddOptions
if qhkReplicateILMExpiry {
opts.ReplicateILMExpiry = true
}
cc, err := client.addSiteReplicationInfo(ctx, rSites, opts)
if err != nil {
return nil, err
}
res := &models.SiteReplicationAddResponse{
ErrorDetail: cc.ErrDetail,
InitialSyncErrorMessage: cc.InitialSyncErrorMessage,
Status: cc.Status,
Success: cc.Success,
}
return res, nil
}
func editSiteReplication(ctx context.Context, client MinioAdmin, params *siteRepApi.SiteReplicationEditParams) (info *models.PeerSiteEditResponse, err error) {
peerSiteInfo := &madmin.PeerInfo{
Endpoint: params.Body.Endpoint, // only endpoint can be edited.
Name: params.Body.Name, // does not get updated.
DeploymentID: params.Body.DeploymentID, // readonly
}
qs := runtime.Values(params.HTTPRequest.URL.Query())
_, qhkDisableILMExpiryReplication, _ := qs.GetOK("disable-ilm-expiry-replication")
_, qhkEnableILMExpiryReplication, _ := qs.GetOK("enable-ilm-expiry-replication")
var opts madmin.SREditOptions
if qhkDisableILMExpiryReplication {
opts.DisableILMExpiryReplication = true
}
if qhkEnableILMExpiryReplication {
opts.EnableILMExpiryReplication = true
}
eRes, err := client.editSiteReplicationInfo(ctx, *peerSiteInfo, opts)
if err != nil {
return nil, err
}
editRes := &models.PeerSiteEditResponse{
ErrorDetail: eRes.ErrDetail,
Status: eRes.Status,
Success: eRes.Success,
}
return editRes, nil
}
func removeSiteReplication(ctx context.Context, client MinioAdmin, params *siteRepApi.SiteReplicationRemoveParams) (info *models.PeerSiteRemoveResponse, err error) {
delAll := params.Body.All
siteNames := params.Body.Sites
var req *madmin.SRRemoveReq
if delAll {
req = &madmin.SRRemoveReq{
RemoveAll: delAll,
}
} else {
req = &madmin.SRRemoveReq{
SiteNames: siteNames,
RemoveAll: delAll,
}
}
rRes, err := client.deleteSiteReplicationInfo(ctx, *req)
if err != nil {
return nil, err
}
removeRes := &models.PeerSiteRemoveResponse{
ErrorDetail: rRes.ErrDetail,
Status: rRes.Status,
}
return removeRes, nil
}

View File

@@ -1,255 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// These tests are for AdminAPI Tag based on swagger-console.yml
package api
import (
"context"
"fmt"
"testing"
"github.com/minio/madmin-go/v3"
"github.com/stretchr/testify/assert"
)
func TestGetSiteReplicationInfo(t *testing.T) {
assert := assert.New(t)
// mock minIO client
adminClient := AdminClientMock{}
function := "getSiteReplicationInfo()"
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
retValueMock := madmin.SiteReplicationInfo{
Enabled: true,
Name: "site1",
Sites: []madmin.PeerInfo{
{
Endpoint: "http://localhost:9000",
Name: "site1",
DeploymentID: "12345",
},
{
Endpoint: "http://localhost:9001",
Name: "site2",
DeploymentID: "123456",
},
},
ServiceAccountAccessKey: "test-key",
}
expValueMock := &madmin.SiteReplicationInfo{
Enabled: true,
Name: "site1",
Sites: []madmin.PeerInfo{
{
Endpoint: "http://localhost:9000",
Name: "site1",
DeploymentID: "12345",
},
{
Endpoint: "http://localhost:9001",
Name: "site2",
DeploymentID: "123456",
},
},
ServiceAccountAccessKey: "test-key",
}
getSiteReplicationInfo = func(_ context.Context) (info *madmin.SiteReplicationInfo, err error) {
return &retValueMock, nil
}
srInfo, err := adminClient.getSiteReplicationInfo(ctx)
assert.Nil(err)
assert.Equal(expValueMock, srInfo, fmt.Sprintf("Failed on %s: length of lists is not the same", function))
}
func TestAddSiteReplicationInfo(t *testing.T) {
assert := assert.New(t)
// mock minIO client
adminClient := AdminClientMock{}
function := "addSiteReplicationInfo()"
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
retValueMock := &madmin.ReplicateAddStatus{
Success: true,
Status: "success",
ErrDetail: "",
InitialSyncErrorMessage: "",
}
expValueMock := &madmin.ReplicateAddStatus{
Success: true,
Status: "success",
ErrDetail: "",
InitialSyncErrorMessage: "",
}
addSiteReplicationInfo = func(_ context.Context, _ []madmin.PeerSite) (res *madmin.ReplicateAddStatus, err error) {
return retValueMock, nil
}
sites := []madmin.PeerSite{
{
Name: "site1",
Endpoint: "http://localhost:9000",
AccessKey: "test",
SecretKey: "test",
},
{
Name: "site2",
Endpoint: "http://localhost:9001",
AccessKey: "test",
SecretKey: "test",
},
}
srInfo, err := adminClient.addSiteReplicationInfo(ctx, sites, madmin.SRAddOptions{})
assert.Nil(err)
assert.Equal(expValueMock, srInfo, fmt.Sprintf("Failed on %s: length of lists is not the same", function))
}
func TestEditSiteReplicationInfo(t *testing.T) {
assert := assert.New(t)
// mock minIO client
adminClient := AdminClientMock{}
function := "editSiteReplicationInfo()"
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
retValueMock := &madmin.ReplicateEditStatus{
Success: true,
Status: "success",
ErrDetail: "",
}
expValueMock := &madmin.ReplicateEditStatus{
Success: true,
Status: "success",
ErrDetail: "",
}
editSiteReplicationInfo = func(_ context.Context, _ madmin.PeerInfo) (res *madmin.ReplicateEditStatus, err error) {
return retValueMock, nil
}
site := madmin.PeerInfo{
Name: "",
Endpoint: "",
DeploymentID: "12345",
}
srInfo, err := adminClient.editSiteReplicationInfo(ctx, site, madmin.SREditOptions{})
assert.Nil(err)
assert.Equal(expValueMock, srInfo, fmt.Sprintf("Failed on %s: length of lists is not the same", function))
}
func TestDeleteSiteReplicationInfo(t *testing.T) {
assert := assert.New(t)
// mock minIO client
adminClient := AdminClientMock{}
function := "deleteSiteReplicationInfo()"
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
retValueMock := &madmin.ReplicateRemoveStatus{
Status: "success",
ErrDetail: "",
}
expValueMock := &madmin.ReplicateRemoveStatus{
Status: "success",
ErrDetail: "",
}
deleteSiteReplicationInfoMock = func(_ context.Context, _ madmin.SRRemoveReq) (res *madmin.ReplicateRemoveStatus, err error) {
return retValueMock, nil
}
remReq := madmin.SRRemoveReq{
SiteNames: []string{
"test1",
},
RemoveAll: false,
}
srInfo, err := adminClient.deleteSiteReplicationInfo(ctx, remReq)
assert.Nil(err)
assert.Equal(expValueMock, srInfo, fmt.Sprintf("Failed on %s: length of lists is not the same", function))
}
func TestSiteReplicationStatus(t *testing.T) {
assert := assert.New(t)
// mock minIO client
adminClient := AdminClientMock{}
function := "getSiteReplicationStatus()"
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
retValueMock := madmin.SRStatusInfo{
Enabled: true,
MaxBuckets: 0,
MaxUsers: 0,
MaxGroups: 0,
MaxPolicies: 0,
Sites: nil,
StatsSummary: nil,
BucketStats: nil,
PolicyStats: nil,
UserStats: nil,
GroupStats: nil,
}
expValueMock := &madmin.SRStatusInfo{
Enabled: true,
MaxBuckets: 0,
MaxUsers: 0,
MaxGroups: 0,
MaxPolicies: 0,
Sites: nil,
StatsSummary: nil,
BucketStats: nil,
PolicyStats: nil,
UserStats: nil,
GroupStats: nil,
}
getSiteReplicationStatus = func(_ context.Context, _ madmin.SRStatusOptions) (info *madmin.SRStatusInfo, err error) {
return &retValueMock, nil
}
reqValues := madmin.SRStatusOptions{
Buckets: true,
Policies: true,
Users: true,
Groups: true,
}
srInfo, err := adminClient.getSiteReplicationStatus(ctx, reqValues)
if err != nil {
assert.Error(err)
}
assert.Equal(expValueMock, srInfo, fmt.Sprintf("Failed on %s: expected result is not same", function))
}

View File

@@ -154,9 +154,6 @@ func configureAPI(api *operations.ConsoleAPI) http.Handler {
// Register nodes handlers
registerNodesHandler(api)
registerSiteReplicationHandler(api)
registerSiteReplicationStatusHandler(api)
// Operator Console
// Register Object's Handlers

View File

@@ -313,187 +313,6 @@ func init() {
}
}
},
"/admin/site-replication": {
"get": {
"tags": [
"SiteReplication"
],
"summary": "Get list of Replication Sites",
"operationId": "GetSiteReplicationInfo",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/siteReplicationInfoResponse"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
},
"put": {
"tags": [
"SiteReplication"
],
"summary": "Edit a Replication Site",
"operationId": "SiteReplicationEdit",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/peerInfo"
}
}
],
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/peerSiteEditResponse"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
},
"post": {
"tags": [
"SiteReplication"
],
"summary": "Add a Replication Site",
"operationId": "SiteReplicationInfoAdd",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/siteReplicationAddRequest"
}
}
],
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/siteReplicationAddResponse"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
},
"delete": {
"tags": [
"SiteReplication"
],
"summary": "Remove a Replication Site",
"operationId": "SiteReplicationRemove",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/peerInfoRemove"
}
}
],
"responses": {
"204": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/peerSiteRemoveResponse"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/admin/site-replication/status": {
"get": {
"tags": [
"SiteReplication"
],
"summary": "Display overall site replication status",
"operationId": "GetSiteReplicationStatus",
"parameters": [
{
"type": "boolean",
"default": true,
"description": "Include Bucket stats",
"name": "buckets",
"in": "query"
},
{
"type": "boolean",
"default": true,
"description": "Include Group stats",
"name": "groups",
"in": "query"
},
{
"type": "boolean",
"default": true,
"description": "Include Policies stats",
"name": "policies",
"in": "query"
},
{
"type": "boolean",
"default": true,
"description": "Include Policies stats",
"name": "users",
"in": "query"
},
{
"type": "string",
"description": "Entity Type to lookup",
"name": "entityType",
"in": "query"
},
{
"type": "string",
"description": "Entity Value to lookup",
"name": "entityValue",
"in": "query"
}
],
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/siteReplicationStatusResponse"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/admin/tiers": {
"get": {
"tags": [
@@ -8635,187 +8454,6 @@ func init() {
}
}
},
"/admin/site-replication": {
"get": {
"tags": [
"SiteReplication"
],
"summary": "Get list of Replication Sites",
"operationId": "GetSiteReplicationInfo",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/siteReplicationInfoResponse"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
},
"put": {
"tags": [
"SiteReplication"
],
"summary": "Edit a Replication Site",
"operationId": "SiteReplicationEdit",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/peerInfo"
}
}
],
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/peerSiteEditResponse"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
},
"post": {
"tags": [
"SiteReplication"
],
"summary": "Add a Replication Site",
"operationId": "SiteReplicationInfoAdd",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/siteReplicationAddRequest"
}
}
],
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/siteReplicationAddResponse"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
},
"delete": {
"tags": [
"SiteReplication"
],
"summary": "Remove a Replication Site",
"operationId": "SiteReplicationRemove",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/peerInfoRemove"
}
}
],
"responses": {
"204": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/peerSiteRemoveResponse"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/admin/site-replication/status": {
"get": {
"tags": [
"SiteReplication"
],
"summary": "Display overall site replication status",
"operationId": "GetSiteReplicationStatus",
"parameters": [
{
"type": "boolean",
"default": true,
"description": "Include Bucket stats",
"name": "buckets",
"in": "query"
},
{
"type": "boolean",
"default": true,
"description": "Include Group stats",
"name": "groups",
"in": "query"
},
{
"type": "boolean",
"default": true,
"description": "Include Policies stats",
"name": "policies",
"in": "query"
},
{
"type": "boolean",
"default": true,
"description": "Include Policies stats",
"name": "users",
"in": "query"
},
{
"type": "string",
"description": "Entity Type to lookup",
"name": "entityType",
"in": "query"
},
{
"type": "string",
"description": "Entity Value to lookup",
"name": "entityValue",
"in": "query"
}
],
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/siteReplicationStatusResponse"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/admin/tiers": {
"get": {
"tags": [

View File

@@ -51,7 +51,6 @@ import (
"github.com/minio/console/api/operations/release"
"github.com/minio/console/api/operations/service"
"github.com/minio/console/api/operations/service_account"
"github.com/minio/console/api/operations/site_replication"
"github.com/minio/console/api/operations/system"
"github.com/minio/console/api/operations/tiering"
"github.com/minio/console/api/operations/user"
@@ -262,12 +261,6 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI {
ServiceAccountGetServiceAccountHandler: service_account.GetServiceAccountHandlerFunc(func(params service_account.GetServiceAccountParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation service_account.GetServiceAccount has not yet been implemented")
}),
SiteReplicationGetSiteReplicationInfoHandler: site_replication.GetSiteReplicationInfoHandlerFunc(func(params site_replication.GetSiteReplicationInfoParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation site_replication.GetSiteReplicationInfo has not yet been implemented")
}),
SiteReplicationGetSiteReplicationStatusHandler: site_replication.GetSiteReplicationStatusHandlerFunc(func(params site_replication.GetSiteReplicationStatusParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation site_replication.GetSiteReplicationStatus has not yet been implemented")
}),
TieringGetTierHandler: tiering.GetTierHandlerFunc(func(params tiering.GetTierParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation tiering.GetTier has not yet been implemented")
}),
@@ -457,15 +450,6 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI {
ObjectShareObjectHandler: object.ShareObjectHandlerFunc(func(params object.ShareObjectParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation object.ShareObject has not yet been implemented")
}),
SiteReplicationSiteReplicationEditHandler: site_replication.SiteReplicationEditHandlerFunc(func(params site_replication.SiteReplicationEditParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation site_replication.SiteReplicationEdit has not yet been implemented")
}),
SiteReplicationSiteReplicationInfoAddHandler: site_replication.SiteReplicationInfoAddHandlerFunc(func(params site_replication.SiteReplicationInfoAddParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation site_replication.SiteReplicationInfoAdd has not yet been implemented")
}),
SiteReplicationSiteReplicationRemoveHandler: site_replication.SiteReplicationRemoveHandlerFunc(func(params site_replication.SiteReplicationRemoveParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation site_replication.SiteReplicationRemove has not yet been implemented")
}),
TieringTiersListHandler: tiering.TiersListHandlerFunc(func(params tiering.TiersListParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation tiering.TiersList has not yet been implemented")
}),
@@ -676,10 +660,6 @@ type ConsoleAPI struct {
PolicyGetSAUserPolicyHandler policy.GetSAUserPolicyHandler
// ServiceAccountGetServiceAccountHandler sets the operation handler for the get service account operation
ServiceAccountGetServiceAccountHandler service_account.GetServiceAccountHandler
// SiteReplicationGetSiteReplicationInfoHandler sets the operation handler for the get site replication info operation
SiteReplicationGetSiteReplicationInfoHandler site_replication.GetSiteReplicationInfoHandler
// SiteReplicationGetSiteReplicationStatusHandler sets the operation handler for the get site replication status operation
SiteReplicationGetSiteReplicationStatusHandler site_replication.GetSiteReplicationStatusHandler
// TieringGetTierHandler sets the operation handler for the get tier operation
TieringGetTierHandler tiering.GetTierHandler
// UserGetUserInfoHandler sets the operation handler for the get user info operation
@@ -806,12 +786,6 @@ type ConsoleAPI struct {
PolicySetPolicyMultipleHandler policy.SetPolicyMultipleHandler
// ObjectShareObjectHandler sets the operation handler for the share object operation
ObjectShareObjectHandler object.ShareObjectHandler
// SiteReplicationSiteReplicationEditHandler sets the operation handler for the site replication edit operation
SiteReplicationSiteReplicationEditHandler site_replication.SiteReplicationEditHandler
// SiteReplicationSiteReplicationInfoAddHandler sets the operation handler for the site replication info add operation
SiteReplicationSiteReplicationInfoAddHandler site_replication.SiteReplicationInfoAddHandler
// SiteReplicationSiteReplicationRemoveHandler sets the operation handler for the site replication remove operation
SiteReplicationSiteReplicationRemoveHandler site_replication.SiteReplicationRemoveHandler
// TieringTiersListHandler sets the operation handler for the tiers list operation
TieringTiersListHandler tiering.TiersListHandler
// TieringTiersListNamesHandler sets the operation handler for the tiers list names operation
@@ -1100,12 +1074,6 @@ func (o *ConsoleAPI) Validate() error {
if o.ServiceAccountGetServiceAccountHandler == nil {
unregistered = append(unregistered, "service_account.GetServiceAccountHandler")
}
if o.SiteReplicationGetSiteReplicationInfoHandler == nil {
unregistered = append(unregistered, "site_replication.GetSiteReplicationInfoHandler")
}
if o.SiteReplicationGetSiteReplicationStatusHandler == nil {
unregistered = append(unregistered, "site_replication.GetSiteReplicationStatusHandler")
}
if o.TieringGetTierHandler == nil {
unregistered = append(unregistered, "tiering.GetTierHandler")
}
@@ -1295,15 +1263,6 @@ func (o *ConsoleAPI) Validate() error {
if o.ObjectShareObjectHandler == nil {
unregistered = append(unregistered, "object.ShareObjectHandler")
}
if o.SiteReplicationSiteReplicationEditHandler == nil {
unregistered = append(unregistered, "site_replication.SiteReplicationEditHandler")
}
if o.SiteReplicationSiteReplicationInfoAddHandler == nil {
unregistered = append(unregistered, "site_replication.SiteReplicationInfoAddHandler")
}
if o.SiteReplicationSiteReplicationRemoveHandler == nil {
unregistered = append(unregistered, "site_replication.SiteReplicationRemoveHandler")
}
if o.TieringTiersListHandler == nil {
unregistered = append(unregistered, "tiering.TiersListHandler")
}
@@ -1682,14 +1641,6 @@ func (o *ConsoleAPI) initHandlerCache() {
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/admin/site-replication"] = site_replication.NewGetSiteReplicationInfo(o.context, o.SiteReplicationGetSiteReplicationInfoHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/admin/site-replication/status"] = site_replication.NewGetSiteReplicationStatus(o.context, o.SiteReplicationGetSiteReplicationStatusHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/admin/tiers/{type}/{name}"] = tiering.NewGetTier(o.context, o.TieringGetTierHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
@@ -1939,18 +1890,6 @@ func (o *ConsoleAPI) initHandlerCache() {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/buckets/{bucket_name}/objects/share"] = object.NewShareObject(o.context, o.ObjectShareObjectHandler)
if o.handlers["PUT"] == nil {
o.handlers["PUT"] = make(map[string]http.Handler)
}
o.handlers["PUT"]["/admin/site-replication"] = site_replication.NewSiteReplicationEdit(o.context, o.SiteReplicationSiteReplicationEditHandler)
if o.handlers["POST"] == nil {
o.handlers["POST"] = make(map[string]http.Handler)
}
o.handlers["POST"]["/admin/site-replication"] = site_replication.NewSiteReplicationInfoAdd(o.context, o.SiteReplicationSiteReplicationInfoAddHandler)
if o.handlers["DELETE"] == nil {
o.handlers["DELETE"] = make(map[string]http.Handler)
}
o.handlers["DELETE"]["/admin/site-replication"] = site_replication.NewSiteReplicationRemove(o.context, o.SiteReplicationSiteReplicationRemoveHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}

View File

@@ -1,88 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package site_replication
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"net/http"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models"
)
// GetSiteReplicationInfoHandlerFunc turns a function with the right signature into a get site replication info handler
type GetSiteReplicationInfoHandlerFunc func(GetSiteReplicationInfoParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn GetSiteReplicationInfoHandlerFunc) Handle(params GetSiteReplicationInfoParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// GetSiteReplicationInfoHandler interface for that can handle valid get site replication info params
type GetSiteReplicationInfoHandler interface {
Handle(GetSiteReplicationInfoParams, *models.Principal) middleware.Responder
}
// NewGetSiteReplicationInfo creates a new http.Handler for the get site replication info operation
func NewGetSiteReplicationInfo(ctx *middleware.Context, handler GetSiteReplicationInfoHandler) *GetSiteReplicationInfo {
return &GetSiteReplicationInfo{Context: ctx, Handler: handler}
}
/*
GetSiteReplicationInfo swagger:route GET /admin/site-replication SiteReplication getSiteReplicationInfo
Get list of Replication Sites
*/
type GetSiteReplicationInfo struct {
Context *middleware.Context
Handler GetSiteReplicationInfoHandler
}
func (o *GetSiteReplicationInfo) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewGetSiteReplicationInfoParams()
uprinc, aCtx, err := o.Context.Authorize(r, route)
if err != nil {
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
if aCtx != nil {
*r = *aCtx
}
var principal *models.Principal
if uprinc != nil {
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
}
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params, principal) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -1,63 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package site_replication
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime/middleware"
)
// NewGetSiteReplicationInfoParams creates a new GetSiteReplicationInfoParams object
//
// There are no default values defined in the spec.
func NewGetSiteReplicationInfoParams() GetSiteReplicationInfoParams {
return GetSiteReplicationInfoParams{}
}
// GetSiteReplicationInfoParams contains all the bound params for the get site replication info operation
// typically these are obtained from a http.Request
//
// swagger:parameters GetSiteReplicationInfo
type GetSiteReplicationInfoParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
// for simple values it will use straight method calls.
//
// To ensure default values, the struct must have been initialized with NewGetSiteReplicationInfoParams() beforehand.
func (o *GetSiteReplicationInfoParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,135 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package site_replication
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/runtime"
"github.com/minio/console/models"
)
// GetSiteReplicationInfoOKCode is the HTTP code returned for type GetSiteReplicationInfoOK
const GetSiteReplicationInfoOKCode int = 200
/*
GetSiteReplicationInfoOK A successful response.
swagger:response getSiteReplicationInfoOK
*/
type GetSiteReplicationInfoOK struct {
/*
In: Body
*/
Payload *models.SiteReplicationInfoResponse `json:"body,omitempty"`
}
// NewGetSiteReplicationInfoOK creates GetSiteReplicationInfoOK with default headers values
func NewGetSiteReplicationInfoOK() *GetSiteReplicationInfoOK {
return &GetSiteReplicationInfoOK{}
}
// WithPayload adds the payload to the get site replication info o k response
func (o *GetSiteReplicationInfoOK) WithPayload(payload *models.SiteReplicationInfoResponse) *GetSiteReplicationInfoOK {
o.Payload = payload
return o
}
// SetPayload sets the payload to the get site replication info o k response
func (o *GetSiteReplicationInfoOK) SetPayload(payload *models.SiteReplicationInfoResponse) {
o.Payload = payload
}
// WriteResponse to the client
func (o *GetSiteReplicationInfoOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(200)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}
/*
GetSiteReplicationInfoDefault Generic error response.
swagger:response getSiteReplicationInfoDefault
*/
type GetSiteReplicationInfoDefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.APIError `json:"body,omitempty"`
}
// NewGetSiteReplicationInfoDefault creates GetSiteReplicationInfoDefault with default headers values
func NewGetSiteReplicationInfoDefault(code int) *GetSiteReplicationInfoDefault {
if code <= 0 {
code = 500
}
return &GetSiteReplicationInfoDefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the get site replication info default response
func (o *GetSiteReplicationInfoDefault) WithStatusCode(code int) *GetSiteReplicationInfoDefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the get site replication info default response
func (o *GetSiteReplicationInfoDefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the get site replication info default response
func (o *GetSiteReplicationInfoDefault) WithPayload(payload *models.APIError) *GetSiteReplicationInfoDefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the get site replication info default response
func (o *GetSiteReplicationInfoDefault) SetPayload(payload *models.APIError) {
o.Payload = payload
}
// WriteResponse to the client
func (o *GetSiteReplicationInfoDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(o._statusCode)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}

View File

@@ -1,104 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package site_replication
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"errors"
"net/url"
golangswaggerpaths "path"
)
// GetSiteReplicationInfoURL generates an URL for the get site replication info operation
type GetSiteReplicationInfoURL struct {
_basePath string
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *GetSiteReplicationInfoURL) WithBasePath(bp string) *GetSiteReplicationInfoURL {
o.SetBasePath(bp)
return o
}
// SetBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *GetSiteReplicationInfoURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *GetSiteReplicationInfoURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/admin/site-replication"
_basePath := o._basePath
if _basePath == "" {
_basePath = "/api/v1"
}
_result.Path = golangswaggerpaths.Join(_basePath, _path)
return &_result, nil
}
// Must is a helper function to panic when the url builder returns an error
func (o *GetSiteReplicationInfoURL) Must(u *url.URL, err error) *url.URL {
if err != nil {
panic(err)
}
if u == nil {
panic("url can't be nil")
}
return u
}
// String returns the string representation of the path with query string
func (o *GetSiteReplicationInfoURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *GetSiteReplicationInfoURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on GetSiteReplicationInfoURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on GetSiteReplicationInfoURL")
}
base, err := o.Build()
if err != nil {
return nil, err
}
base.Scheme = scheme
base.Host = host
return base, nil
}
// StringFull returns the string representation of a complete url
func (o *GetSiteReplicationInfoURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -1,88 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package site_replication
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"net/http"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models"
)
// GetSiteReplicationStatusHandlerFunc turns a function with the right signature into a get site replication status handler
type GetSiteReplicationStatusHandlerFunc func(GetSiteReplicationStatusParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn GetSiteReplicationStatusHandlerFunc) Handle(params GetSiteReplicationStatusParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// GetSiteReplicationStatusHandler interface for that can handle valid get site replication status params
type GetSiteReplicationStatusHandler interface {
Handle(GetSiteReplicationStatusParams, *models.Principal) middleware.Responder
}
// NewGetSiteReplicationStatus creates a new http.Handler for the get site replication status operation
func NewGetSiteReplicationStatus(ctx *middleware.Context, handler GetSiteReplicationStatusHandler) *GetSiteReplicationStatus {
return &GetSiteReplicationStatus{Context: ctx, Handler: handler}
}
/*
GetSiteReplicationStatus swagger:route GET /admin/site-replication/status SiteReplication getSiteReplicationStatus
Display overall site replication status
*/
type GetSiteReplicationStatus struct {
Context *middleware.Context
Handler GetSiteReplicationStatusHandler
}
func (o *GetSiteReplicationStatus) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewGetSiteReplicationStatusParams()
uprinc, aCtx, err := o.Context.Authorize(r, route)
if err != nil {
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
if aCtx != nil {
*r = *aCtx
}
var principal *models.Principal
if uprinc != nil {
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
}
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params, principal) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -1,275 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package site_replication
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// NewGetSiteReplicationStatusParams creates a new GetSiteReplicationStatusParams object
// with the default values initialized.
func NewGetSiteReplicationStatusParams() GetSiteReplicationStatusParams {
var (
// initialize parameters with default values
bucketsDefault = bool(true)
groupsDefault = bool(true)
policiesDefault = bool(true)
usersDefault = bool(true)
)
return GetSiteReplicationStatusParams{
Buckets: &bucketsDefault,
Groups: &groupsDefault,
Policies: &policiesDefault,
Users: &usersDefault,
}
}
// GetSiteReplicationStatusParams contains all the bound params for the get site replication status operation
// typically these are obtained from a http.Request
//
// swagger:parameters GetSiteReplicationStatus
type GetSiteReplicationStatusParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
/*Include Bucket stats
In: query
Default: true
*/
Buckets *bool
/*Entity Type to lookup
In: query
*/
EntityType *string
/*Entity Value to lookup
In: query
*/
EntityValue *string
/*Include Group stats
In: query
Default: true
*/
Groups *bool
/*Include Policies stats
In: query
Default: true
*/
Policies *bool
/*Include Policies stats
In: query
Default: true
*/
Users *bool
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
// for simple values it will use straight method calls.
//
// To ensure default values, the struct must have been initialized with NewGetSiteReplicationStatusParams() beforehand.
func (o *GetSiteReplicationStatusParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
qs := runtime.Values(r.URL.Query())
qBuckets, qhkBuckets, _ := qs.GetOK("buckets")
if err := o.bindBuckets(qBuckets, qhkBuckets, route.Formats); err != nil {
res = append(res, err)
}
qEntityType, qhkEntityType, _ := qs.GetOK("entityType")
if err := o.bindEntityType(qEntityType, qhkEntityType, route.Formats); err != nil {
res = append(res, err)
}
qEntityValue, qhkEntityValue, _ := qs.GetOK("entityValue")
if err := o.bindEntityValue(qEntityValue, qhkEntityValue, route.Formats); err != nil {
res = append(res, err)
}
qGroups, qhkGroups, _ := qs.GetOK("groups")
if err := o.bindGroups(qGroups, qhkGroups, route.Formats); err != nil {
res = append(res, err)
}
qPolicies, qhkPolicies, _ := qs.GetOK("policies")
if err := o.bindPolicies(qPolicies, qhkPolicies, route.Formats); err != nil {
res = append(res, err)
}
qUsers, qhkUsers, _ := qs.GetOK("users")
if err := o.bindUsers(qUsers, qhkUsers, route.Formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// bindBuckets binds and validates parameter Buckets from query.
func (o *GetSiteReplicationStatusParams) bindBuckets(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
// Default values have been previously initialized by NewGetSiteReplicationStatusParams()
return nil
}
value, err := swag.ConvertBool(raw)
if err != nil {
return errors.InvalidType("buckets", "query", "bool", raw)
}
o.Buckets = &value
return nil
}
// bindEntityType binds and validates parameter EntityType from query.
func (o *GetSiteReplicationStatusParams) bindEntityType(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.EntityType = &raw
return nil
}
// bindEntityValue binds and validates parameter EntityValue from query.
func (o *GetSiteReplicationStatusParams) bindEntityValue(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.EntityValue = &raw
return nil
}
// bindGroups binds and validates parameter Groups from query.
func (o *GetSiteReplicationStatusParams) bindGroups(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
// Default values have been previously initialized by NewGetSiteReplicationStatusParams()
return nil
}
value, err := swag.ConvertBool(raw)
if err != nil {
return errors.InvalidType("groups", "query", "bool", raw)
}
o.Groups = &value
return nil
}
// bindPolicies binds and validates parameter Policies from query.
func (o *GetSiteReplicationStatusParams) bindPolicies(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
// Default values have been previously initialized by NewGetSiteReplicationStatusParams()
return nil
}
value, err := swag.ConvertBool(raw)
if err != nil {
return errors.InvalidType("policies", "query", "bool", raw)
}
o.Policies = &value
return nil
}
// bindUsers binds and validates parameter Users from query.
func (o *GetSiteReplicationStatusParams) bindUsers(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
// Default values have been previously initialized by NewGetSiteReplicationStatusParams()
return nil
}
value, err := swag.ConvertBool(raw)
if err != nil {
return errors.InvalidType("users", "query", "bool", raw)
}
o.Users = &value
return nil
}

View File

@@ -1,135 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package site_replication
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/runtime"
"github.com/minio/console/models"
)
// GetSiteReplicationStatusOKCode is the HTTP code returned for type GetSiteReplicationStatusOK
const GetSiteReplicationStatusOKCode int = 200
/*
GetSiteReplicationStatusOK A successful response.
swagger:response getSiteReplicationStatusOK
*/
type GetSiteReplicationStatusOK struct {
/*
In: Body
*/
Payload *models.SiteReplicationStatusResponse `json:"body,omitempty"`
}
// NewGetSiteReplicationStatusOK creates GetSiteReplicationStatusOK with default headers values
func NewGetSiteReplicationStatusOK() *GetSiteReplicationStatusOK {
return &GetSiteReplicationStatusOK{}
}
// WithPayload adds the payload to the get site replication status o k response
func (o *GetSiteReplicationStatusOK) WithPayload(payload *models.SiteReplicationStatusResponse) *GetSiteReplicationStatusOK {
o.Payload = payload
return o
}
// SetPayload sets the payload to the get site replication status o k response
func (o *GetSiteReplicationStatusOK) SetPayload(payload *models.SiteReplicationStatusResponse) {
o.Payload = payload
}
// WriteResponse to the client
func (o *GetSiteReplicationStatusOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(200)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}
/*
GetSiteReplicationStatusDefault Generic error response.
swagger:response getSiteReplicationStatusDefault
*/
type GetSiteReplicationStatusDefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.APIError `json:"body,omitempty"`
}
// NewGetSiteReplicationStatusDefault creates GetSiteReplicationStatusDefault with default headers values
func NewGetSiteReplicationStatusDefault(code int) *GetSiteReplicationStatusDefault {
if code <= 0 {
code = 500
}
return &GetSiteReplicationStatusDefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the get site replication status default response
func (o *GetSiteReplicationStatusDefault) WithStatusCode(code int) *GetSiteReplicationStatusDefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the get site replication status default response
func (o *GetSiteReplicationStatusDefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the get site replication status default response
func (o *GetSiteReplicationStatusDefault) WithPayload(payload *models.APIError) *GetSiteReplicationStatusDefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the get site replication status default response
func (o *GetSiteReplicationStatusDefault) SetPayload(payload *models.APIError) {
o.Payload = payload
}
// WriteResponse to the client
func (o *GetSiteReplicationStatusDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(o._statusCode)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}

View File

@@ -1,167 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package site_replication
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"errors"
"net/url"
golangswaggerpaths "path"
"github.com/go-openapi/swag"
)
// GetSiteReplicationStatusURL generates an URL for the get site replication status operation
type GetSiteReplicationStatusURL struct {
Buckets *bool
EntityType *string
EntityValue *string
Groups *bool
Policies *bool
Users *bool
_basePath string
// avoid unkeyed usage
_ struct{}
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *GetSiteReplicationStatusURL) WithBasePath(bp string) *GetSiteReplicationStatusURL {
o.SetBasePath(bp)
return o
}
// SetBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *GetSiteReplicationStatusURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *GetSiteReplicationStatusURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/admin/site-replication/status"
_basePath := o._basePath
if _basePath == "" {
_basePath = "/api/v1"
}
_result.Path = golangswaggerpaths.Join(_basePath, _path)
qs := make(url.Values)
var bucketsQ string
if o.Buckets != nil {
bucketsQ = swag.FormatBool(*o.Buckets)
}
if bucketsQ != "" {
qs.Set("buckets", bucketsQ)
}
var entityTypeQ string
if o.EntityType != nil {
entityTypeQ = *o.EntityType
}
if entityTypeQ != "" {
qs.Set("entityType", entityTypeQ)
}
var entityValueQ string
if o.EntityValue != nil {
entityValueQ = *o.EntityValue
}
if entityValueQ != "" {
qs.Set("entityValue", entityValueQ)
}
var groupsQ string
if o.Groups != nil {
groupsQ = swag.FormatBool(*o.Groups)
}
if groupsQ != "" {
qs.Set("groups", groupsQ)
}
var policiesQ string
if o.Policies != nil {
policiesQ = swag.FormatBool(*o.Policies)
}
if policiesQ != "" {
qs.Set("policies", policiesQ)
}
var usersQ string
if o.Users != nil {
usersQ = swag.FormatBool(*o.Users)
}
if usersQ != "" {
qs.Set("users", usersQ)
}
_result.RawQuery = qs.Encode()
return &_result, nil
}
// Must is a helper function to panic when the url builder returns an error
func (o *GetSiteReplicationStatusURL) Must(u *url.URL, err error) *url.URL {
if err != nil {
panic(err)
}
if u == nil {
panic("url can't be nil")
}
return u
}
// String returns the string representation of the path with query string
func (o *GetSiteReplicationStatusURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *GetSiteReplicationStatusURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on GetSiteReplicationStatusURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on GetSiteReplicationStatusURL")
}
base, err := o.Build()
if err != nil {
return nil, err
}
base.Scheme = scheme
base.Host = host
return base, nil
}
// StringFull returns the string representation of a complete url
func (o *GetSiteReplicationStatusURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -1,88 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package site_replication
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"net/http"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models"
)
// SiteReplicationEditHandlerFunc turns a function with the right signature into a site replication edit handler
type SiteReplicationEditHandlerFunc func(SiteReplicationEditParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn SiteReplicationEditHandlerFunc) Handle(params SiteReplicationEditParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// SiteReplicationEditHandler interface for that can handle valid site replication edit params
type SiteReplicationEditHandler interface {
Handle(SiteReplicationEditParams, *models.Principal) middleware.Responder
}
// NewSiteReplicationEdit creates a new http.Handler for the site replication edit operation
func NewSiteReplicationEdit(ctx *middleware.Context, handler SiteReplicationEditHandler) *SiteReplicationEdit {
return &SiteReplicationEdit{Context: ctx, Handler: handler}
}
/*
SiteReplicationEdit swagger:route PUT /admin/site-replication SiteReplication siteReplicationEdit
Edit a Replication Site
*/
type SiteReplicationEdit struct {
Context *middleware.Context
Handler SiteReplicationEditHandler
}
func (o *SiteReplicationEdit) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewSiteReplicationEditParams()
uprinc, aCtx, err := o.Context.Authorize(r, route)
if err != nil {
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
if aCtx != nil {
*r = *aCtx
}
var principal *models.Principal
if uprinc != nil {
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
}
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params, principal) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -1,101 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package site_replication
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"io"
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/validate"
"github.com/minio/console/models"
)
// NewSiteReplicationEditParams creates a new SiteReplicationEditParams object
//
// There are no default values defined in the spec.
func NewSiteReplicationEditParams() SiteReplicationEditParams {
return SiteReplicationEditParams{}
}
// SiteReplicationEditParams contains all the bound params for the site replication edit operation
// typically these are obtained from a http.Request
//
// swagger:parameters SiteReplicationEdit
type SiteReplicationEditParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
/*
Required: true
In: body
*/
Body *models.PeerInfo
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
// for simple values it will use straight method calls.
//
// To ensure default values, the struct must have been initialized with NewSiteReplicationEditParams() beforehand.
func (o *SiteReplicationEditParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
if runtime.HasBody(r) {
defer r.Body.Close()
var body models.PeerInfo
if err := route.Consumer.Consume(r.Body, &body); err != nil {
if err == io.EOF {
res = append(res, errors.Required("body", "body", ""))
} else {
res = append(res, errors.NewParseError("body", "body", "", err))
}
} else {
// validate body object
if err := body.Validate(route.Formats); err != nil {
res = append(res, err)
}
ctx := validate.WithOperationRequest(r.Context())
if err := body.ContextValidate(ctx, route.Formats); err != nil {
res = append(res, err)
}
if len(res) == 0 {
o.Body = &body
}
}
} else {
res = append(res, errors.Required("body", "body", ""))
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,135 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package site_replication
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/runtime"
"github.com/minio/console/models"
)
// SiteReplicationEditOKCode is the HTTP code returned for type SiteReplicationEditOK
const SiteReplicationEditOKCode int = 200
/*
SiteReplicationEditOK A successful response.
swagger:response siteReplicationEditOK
*/
type SiteReplicationEditOK struct {
/*
In: Body
*/
Payload *models.PeerSiteEditResponse `json:"body,omitempty"`
}
// NewSiteReplicationEditOK creates SiteReplicationEditOK with default headers values
func NewSiteReplicationEditOK() *SiteReplicationEditOK {
return &SiteReplicationEditOK{}
}
// WithPayload adds the payload to the site replication edit o k response
func (o *SiteReplicationEditOK) WithPayload(payload *models.PeerSiteEditResponse) *SiteReplicationEditOK {
o.Payload = payload
return o
}
// SetPayload sets the payload to the site replication edit o k response
func (o *SiteReplicationEditOK) SetPayload(payload *models.PeerSiteEditResponse) {
o.Payload = payload
}
// WriteResponse to the client
func (o *SiteReplicationEditOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(200)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}
/*
SiteReplicationEditDefault Generic error response.
swagger:response siteReplicationEditDefault
*/
type SiteReplicationEditDefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.APIError `json:"body,omitempty"`
}
// NewSiteReplicationEditDefault creates SiteReplicationEditDefault with default headers values
func NewSiteReplicationEditDefault(code int) *SiteReplicationEditDefault {
if code <= 0 {
code = 500
}
return &SiteReplicationEditDefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the site replication edit default response
func (o *SiteReplicationEditDefault) WithStatusCode(code int) *SiteReplicationEditDefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the site replication edit default response
func (o *SiteReplicationEditDefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the site replication edit default response
func (o *SiteReplicationEditDefault) WithPayload(payload *models.APIError) *SiteReplicationEditDefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the site replication edit default response
func (o *SiteReplicationEditDefault) SetPayload(payload *models.APIError) {
o.Payload = payload
}
// WriteResponse to the client
func (o *SiteReplicationEditDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(o._statusCode)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}

View File

@@ -1,104 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package site_replication
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"errors"
"net/url"
golangswaggerpaths "path"
)
// SiteReplicationEditURL generates an URL for the site replication edit operation
type SiteReplicationEditURL struct {
_basePath string
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *SiteReplicationEditURL) WithBasePath(bp string) *SiteReplicationEditURL {
o.SetBasePath(bp)
return o
}
// SetBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *SiteReplicationEditURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *SiteReplicationEditURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/admin/site-replication"
_basePath := o._basePath
if _basePath == "" {
_basePath = "/api/v1"
}
_result.Path = golangswaggerpaths.Join(_basePath, _path)
return &_result, nil
}
// Must is a helper function to panic when the url builder returns an error
func (o *SiteReplicationEditURL) Must(u *url.URL, err error) *url.URL {
if err != nil {
panic(err)
}
if u == nil {
panic("url can't be nil")
}
return u
}
// String returns the string representation of the path with query string
func (o *SiteReplicationEditURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *SiteReplicationEditURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on SiteReplicationEditURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on SiteReplicationEditURL")
}
base, err := o.Build()
if err != nil {
return nil, err
}
base.Scheme = scheme
base.Host = host
return base, nil
}
// StringFull returns the string representation of a complete url
func (o *SiteReplicationEditURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -1,88 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package site_replication
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"net/http"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models"
)
// SiteReplicationInfoAddHandlerFunc turns a function with the right signature into a site replication info add handler
type SiteReplicationInfoAddHandlerFunc func(SiteReplicationInfoAddParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn SiteReplicationInfoAddHandlerFunc) Handle(params SiteReplicationInfoAddParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// SiteReplicationInfoAddHandler interface for that can handle valid site replication info add params
type SiteReplicationInfoAddHandler interface {
Handle(SiteReplicationInfoAddParams, *models.Principal) middleware.Responder
}
// NewSiteReplicationInfoAdd creates a new http.Handler for the site replication info add operation
func NewSiteReplicationInfoAdd(ctx *middleware.Context, handler SiteReplicationInfoAddHandler) *SiteReplicationInfoAdd {
return &SiteReplicationInfoAdd{Context: ctx, Handler: handler}
}
/*
SiteReplicationInfoAdd swagger:route POST /admin/site-replication SiteReplication siteReplicationInfoAdd
Add a Replication Site
*/
type SiteReplicationInfoAdd struct {
Context *middleware.Context
Handler SiteReplicationInfoAddHandler
}
func (o *SiteReplicationInfoAdd) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewSiteReplicationInfoAddParams()
uprinc, aCtx, err := o.Context.Authorize(r, route)
if err != nil {
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
if aCtx != nil {
*r = *aCtx
}
var principal *models.Principal
if uprinc != nil {
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
}
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params, principal) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -1,101 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package site_replication
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"io"
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/validate"
"github.com/minio/console/models"
)
// NewSiteReplicationInfoAddParams creates a new SiteReplicationInfoAddParams object
//
// There are no default values defined in the spec.
func NewSiteReplicationInfoAddParams() SiteReplicationInfoAddParams {
return SiteReplicationInfoAddParams{}
}
// SiteReplicationInfoAddParams contains all the bound params for the site replication info add operation
// typically these are obtained from a http.Request
//
// swagger:parameters SiteReplicationInfoAdd
type SiteReplicationInfoAddParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
/*
Required: true
In: body
*/
Body models.SiteReplicationAddRequest
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
// for simple values it will use straight method calls.
//
// To ensure default values, the struct must have been initialized with NewSiteReplicationInfoAddParams() beforehand.
func (o *SiteReplicationInfoAddParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
if runtime.HasBody(r) {
defer r.Body.Close()
var body models.SiteReplicationAddRequest
if err := route.Consumer.Consume(r.Body, &body); err != nil {
if err == io.EOF {
res = append(res, errors.Required("body", "body", ""))
} else {
res = append(res, errors.NewParseError("body", "body", "", err))
}
} else {
// validate body object
if err := body.Validate(route.Formats); err != nil {
res = append(res, err)
}
ctx := validate.WithOperationRequest(r.Context())
if err := body.ContextValidate(ctx, route.Formats); err != nil {
res = append(res, err)
}
if len(res) == 0 {
o.Body = body
}
}
} else {
res = append(res, errors.Required("body", "body", ""))
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,135 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package site_replication
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/runtime"
"github.com/minio/console/models"
)
// SiteReplicationInfoAddOKCode is the HTTP code returned for type SiteReplicationInfoAddOK
const SiteReplicationInfoAddOKCode int = 200
/*
SiteReplicationInfoAddOK A successful response.
swagger:response siteReplicationInfoAddOK
*/
type SiteReplicationInfoAddOK struct {
/*
In: Body
*/
Payload *models.SiteReplicationAddResponse `json:"body,omitempty"`
}
// NewSiteReplicationInfoAddOK creates SiteReplicationInfoAddOK with default headers values
func NewSiteReplicationInfoAddOK() *SiteReplicationInfoAddOK {
return &SiteReplicationInfoAddOK{}
}
// WithPayload adds the payload to the site replication info add o k response
func (o *SiteReplicationInfoAddOK) WithPayload(payload *models.SiteReplicationAddResponse) *SiteReplicationInfoAddOK {
o.Payload = payload
return o
}
// SetPayload sets the payload to the site replication info add o k response
func (o *SiteReplicationInfoAddOK) SetPayload(payload *models.SiteReplicationAddResponse) {
o.Payload = payload
}
// WriteResponse to the client
func (o *SiteReplicationInfoAddOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(200)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}
/*
SiteReplicationInfoAddDefault Generic error response.
swagger:response siteReplicationInfoAddDefault
*/
type SiteReplicationInfoAddDefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.APIError `json:"body,omitempty"`
}
// NewSiteReplicationInfoAddDefault creates SiteReplicationInfoAddDefault with default headers values
func NewSiteReplicationInfoAddDefault(code int) *SiteReplicationInfoAddDefault {
if code <= 0 {
code = 500
}
return &SiteReplicationInfoAddDefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the site replication info add default response
func (o *SiteReplicationInfoAddDefault) WithStatusCode(code int) *SiteReplicationInfoAddDefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the site replication info add default response
func (o *SiteReplicationInfoAddDefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the site replication info add default response
func (o *SiteReplicationInfoAddDefault) WithPayload(payload *models.APIError) *SiteReplicationInfoAddDefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the site replication info add default response
func (o *SiteReplicationInfoAddDefault) SetPayload(payload *models.APIError) {
o.Payload = payload
}
// WriteResponse to the client
func (o *SiteReplicationInfoAddDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(o._statusCode)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}

View File

@@ -1,104 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package site_replication
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"errors"
"net/url"
golangswaggerpaths "path"
)
// SiteReplicationInfoAddURL generates an URL for the site replication info add operation
type SiteReplicationInfoAddURL struct {
_basePath string
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *SiteReplicationInfoAddURL) WithBasePath(bp string) *SiteReplicationInfoAddURL {
o.SetBasePath(bp)
return o
}
// SetBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *SiteReplicationInfoAddURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *SiteReplicationInfoAddURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/admin/site-replication"
_basePath := o._basePath
if _basePath == "" {
_basePath = "/api/v1"
}
_result.Path = golangswaggerpaths.Join(_basePath, _path)
return &_result, nil
}
// Must is a helper function to panic when the url builder returns an error
func (o *SiteReplicationInfoAddURL) Must(u *url.URL, err error) *url.URL {
if err != nil {
panic(err)
}
if u == nil {
panic("url can't be nil")
}
return u
}
// String returns the string representation of the path with query string
func (o *SiteReplicationInfoAddURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *SiteReplicationInfoAddURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on SiteReplicationInfoAddURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on SiteReplicationInfoAddURL")
}
base, err := o.Build()
if err != nil {
return nil, err
}
base.Scheme = scheme
base.Host = host
return base, nil
}
// StringFull returns the string representation of a complete url
func (o *SiteReplicationInfoAddURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -1,88 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package site_replication
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"net/http"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models"
)
// SiteReplicationRemoveHandlerFunc turns a function with the right signature into a site replication remove handler
type SiteReplicationRemoveHandlerFunc func(SiteReplicationRemoveParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn SiteReplicationRemoveHandlerFunc) Handle(params SiteReplicationRemoveParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// SiteReplicationRemoveHandler interface for that can handle valid site replication remove params
type SiteReplicationRemoveHandler interface {
Handle(SiteReplicationRemoveParams, *models.Principal) middleware.Responder
}
// NewSiteReplicationRemove creates a new http.Handler for the site replication remove operation
func NewSiteReplicationRemove(ctx *middleware.Context, handler SiteReplicationRemoveHandler) *SiteReplicationRemove {
return &SiteReplicationRemove{Context: ctx, Handler: handler}
}
/*
SiteReplicationRemove swagger:route DELETE /admin/site-replication SiteReplication siteReplicationRemove
Remove a Replication Site
*/
type SiteReplicationRemove struct {
Context *middleware.Context
Handler SiteReplicationRemoveHandler
}
func (o *SiteReplicationRemove) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewSiteReplicationRemoveParams()
uprinc, aCtx, err := o.Context.Authorize(r, route)
if err != nil {
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
if aCtx != nil {
*r = *aCtx
}
var principal *models.Principal
if uprinc != nil {
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
}
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params, principal) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -1,101 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package site_replication
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"io"
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/validate"
"github.com/minio/console/models"
)
// NewSiteReplicationRemoveParams creates a new SiteReplicationRemoveParams object
//
// There are no default values defined in the spec.
func NewSiteReplicationRemoveParams() SiteReplicationRemoveParams {
return SiteReplicationRemoveParams{}
}
// SiteReplicationRemoveParams contains all the bound params for the site replication remove operation
// typically these are obtained from a http.Request
//
// swagger:parameters SiteReplicationRemove
type SiteReplicationRemoveParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
/*
Required: true
In: body
*/
Body *models.PeerInfoRemove
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
// for simple values it will use straight method calls.
//
// To ensure default values, the struct must have been initialized with NewSiteReplicationRemoveParams() beforehand.
func (o *SiteReplicationRemoveParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
if runtime.HasBody(r) {
defer r.Body.Close()
var body models.PeerInfoRemove
if err := route.Consumer.Consume(r.Body, &body); err != nil {
if err == io.EOF {
res = append(res, errors.Required("body", "body", ""))
} else {
res = append(res, errors.NewParseError("body", "body", "", err))
}
} else {
// validate body object
if err := body.Validate(route.Formats); err != nil {
res = append(res, err)
}
ctx := validate.WithOperationRequest(r.Context())
if err := body.ContextValidate(ctx, route.Formats); err != nil {
res = append(res, err)
}
if len(res) == 0 {
o.Body = &body
}
}
} else {
res = append(res, errors.Required("body", "body", ""))
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,135 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package site_replication
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/runtime"
"github.com/minio/console/models"
)
// SiteReplicationRemoveNoContentCode is the HTTP code returned for type SiteReplicationRemoveNoContent
const SiteReplicationRemoveNoContentCode int = 204
/*
SiteReplicationRemoveNoContent A successful response.
swagger:response siteReplicationRemoveNoContent
*/
type SiteReplicationRemoveNoContent struct {
/*
In: Body
*/
Payload *models.PeerSiteRemoveResponse `json:"body,omitempty"`
}
// NewSiteReplicationRemoveNoContent creates SiteReplicationRemoveNoContent with default headers values
func NewSiteReplicationRemoveNoContent() *SiteReplicationRemoveNoContent {
return &SiteReplicationRemoveNoContent{}
}
// WithPayload adds the payload to the site replication remove no content response
func (o *SiteReplicationRemoveNoContent) WithPayload(payload *models.PeerSiteRemoveResponse) *SiteReplicationRemoveNoContent {
o.Payload = payload
return o
}
// SetPayload sets the payload to the site replication remove no content response
func (o *SiteReplicationRemoveNoContent) SetPayload(payload *models.PeerSiteRemoveResponse) {
o.Payload = payload
}
// WriteResponse to the client
func (o *SiteReplicationRemoveNoContent) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(204)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}
/*
SiteReplicationRemoveDefault Generic error response.
swagger:response siteReplicationRemoveDefault
*/
type SiteReplicationRemoveDefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.APIError `json:"body,omitempty"`
}
// NewSiteReplicationRemoveDefault creates SiteReplicationRemoveDefault with default headers values
func NewSiteReplicationRemoveDefault(code int) *SiteReplicationRemoveDefault {
if code <= 0 {
code = 500
}
return &SiteReplicationRemoveDefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the site replication remove default response
func (o *SiteReplicationRemoveDefault) WithStatusCode(code int) *SiteReplicationRemoveDefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the site replication remove default response
func (o *SiteReplicationRemoveDefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the site replication remove default response
func (o *SiteReplicationRemoveDefault) WithPayload(payload *models.APIError) *SiteReplicationRemoveDefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the site replication remove default response
func (o *SiteReplicationRemoveDefault) SetPayload(payload *models.APIError) {
o.Payload = payload
}
// WriteResponse to the client
func (o *SiteReplicationRemoveDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(o._statusCode)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}

View File

@@ -1,104 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package site_replication
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"errors"
"net/url"
golangswaggerpaths "path"
)
// SiteReplicationRemoveURL generates an URL for the site replication remove operation
type SiteReplicationRemoveURL struct {
_basePath string
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *SiteReplicationRemoveURL) WithBasePath(bp string) *SiteReplicationRemoveURL {
o.SetBasePath(bp)
return o
}
// SetBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *SiteReplicationRemoveURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *SiteReplicationRemoveURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/admin/site-replication"
_basePath := o._basePath
if _basePath == "" {
_basePath = "/api/v1"
}
_result.Path = golangswaggerpaths.Join(_basePath, _path)
return &_result, nil
}
// Must is a helper function to panic when the url builder returns an error
func (o *SiteReplicationRemoveURL) Must(u *url.URL, err error) *url.URL {
if err != nil {
panic(err)
}
if u == nil {
panic("url can't be nil")
}
return u
}
// String returns the string representation of the path with query string
func (o *SiteReplicationRemoveURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *SiteReplicationRemoveURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on SiteReplicationRemoveURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on SiteReplicationRemoveURL")
}
base, err := o.Build()
if err != nil {
return nil, err
}
base.Scheme = scheme
base.Host = host
return base, nil
}
// StringFull returns the string representation of a complete url
func (o *SiteReplicationRemoveURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -2394,129 +2394,6 @@ paths:
tags:
- Configuration
/admin/site-replication:
get:
summary: Get list of Replication Sites
operationId: GetSiteReplicationInfo
responses:
200:
description: A successful response.
schema:
$ref: "#/definitions/siteReplicationInfoResponse"
default:
description: Generic error response.
schema:
$ref: "#/definitions/ApiError"
tags:
- SiteReplication
post:
summary: Add a Replication Site
operationId: SiteReplicationInfoAdd
parameters:
- name: body
in: body
required: true
schema:
$ref: "#/definitions/siteReplicationAddRequest"
responses:
200:
description: A successful response.
schema:
$ref: "#/definitions/siteReplicationAddResponse"
default:
description: Generic error response.
schema:
$ref: "#/definitions/ApiError"
tags:
- SiteReplication
put:
summary: Edit a Replication Site
operationId: SiteReplicationEdit
parameters:
- name: body
in: body
required: true
schema:
$ref: "#/definitions/peerInfo"
responses:
200:
description: A successful response.
schema:
$ref: "#/definitions/peerSiteEditResponse"
default:
description: Generic error response.
schema:
$ref: "#/definitions/ApiError"
tags:
- SiteReplication
delete:
summary: Remove a Replication Site
operationId: SiteReplicationRemove
parameters:
- name: body
in: body
required: true
schema:
$ref: "#/definitions/peerInfoRemove"
responses:
204:
description: A successful response.
schema:
$ref: "#/definitions/peerSiteRemoveResponse"
default:
description: Generic error response.
schema:
$ref: "#/definitions/ApiError"
tags:
- SiteReplication
/admin/site-replication/status:
get:
summary: Display overall site replication status
operationId: GetSiteReplicationStatus
parameters:
- name: buckets
description: Include Bucket stats
in: query
type: boolean
default: true
- name: groups
description: Include Group stats
in: query
type: boolean
default: true
- name: policies
description: Include Policies stats
in: query
type: boolean
default: true
- name: users
description: Include Policies stats
in: query
type: boolean
default: true
- name: entityType
description: Entity Type to lookup
in: query
type: string
required: false
- name: entityValue
description: Entity Value to lookup
in: query
type: string
required: false
responses:
200:
description: A successful response.
schema:
$ref: "#/definitions/siteReplicationStatusResponse"
default:
description: Generic error response.
schema:
$ref: "#/definitions/ApiError"
tags:
- SiteReplication
/admin/tiers:
get:
summary: Returns a list of tiers for ilm

View File

@@ -16,15 +16,11 @@
import { useEffect, useState } from "react";
import { Navigate, useLocation } from "react-router-dom";
import useApi from "./screens/Console/Common/Hooks/useApi";
import { ErrorResponseHandler } from "./common/types";
import { ReplicationSite } from "./screens/Console/Configurations/SiteReplication/SiteReplication";
import { useSelector } from "react-redux";
import { SRInfoStateType } from "./types";
import { AppState, useAppDispatch } from "./store";
import LoadingComponent from "./common/LoadingComponent";
import { fetchSession } from "./screens/LoginPage/sessionThunk";
import { setSiteReplicationInfo, setLocationPath } from "./systemSlice";
import { setLocationPath } from "./systemSlice";
import { SessionCallStates } from "./screens/Console/consoleSlice.types";
interface ProtectedRouteProps {
@@ -39,9 +35,6 @@ const ProtectedRoute = ({ Component }: ProtectedRouteProps) => {
const sessionLoadingState = useSelector(
(state: AppState) => state.console.sessionLoadingState,
);
const anonymousMode = useSelector(
(state: AppState) => state.system.anonymousMode,
);
const { pathname = "" } = useLocation();
const StorePathAndRedirect = () => {
@@ -63,40 +56,6 @@ const ProtectedRoute = ({ Component }: ProtectedRouteProps) => {
}
}, [dispatch, sessionLoadingState]);
const [, invokeSRInfoApi] = useApi(
(res: any) => {
const { name: curSiteName, enabled = false } = res || {};
let siteList = res.site;
if (!siteList) {
siteList = [];
}
const isSiteNameInList = siteList.find((si: ReplicationSite) => {
return si.name === curSiteName;
});
const isCurSite = enabled && isSiteNameInList;
const siteReplicationDetail: SRInfoStateType = {
enabled: enabled,
curSite: isCurSite,
siteName: isCurSite ? curSiteName : "",
};
dispatch(setSiteReplicationInfo(siteReplicationDetail));
},
(err: ErrorResponseHandler) => {
// we will fail this call silently, but show it on the console
console.error(`Error loading site replication status`, err);
},
);
useEffect(() => {
if (userLoggedIn && !componentLoading && !anonymousMode) {
invokeSRInfoApi("GET", `api/v1/admin/site-replication`);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [userLoggedIn, componentLoading]);
// if we're still trying to retrieve user session render nothing
if (componentLoading) {
return <LoadingComponent />;

View File

@@ -4073,134 +4073,6 @@ export class Api<
...params,
}),
/**
* No description
*
* @tags SiteReplication
* @name GetSiteReplicationInfo
* @summary Get list of Replication Sites
* @request GET:/admin/site-replication
* @secure
*/
getSiteReplicationInfo: (params: RequestParams = {}) =>
this.request<SiteReplicationInfoResponse, ApiError>({
path: `/admin/site-replication`,
method: "GET",
secure: true,
format: "json",
...params,
}),
/**
* No description
*
* @tags SiteReplication
* @name SiteReplicationInfoAdd
* @summary Add a Replication Site
* @request POST:/admin/site-replication
* @secure
*/
siteReplicationInfoAdd: (
body: SiteReplicationAddRequest,
params: RequestParams = {},
) =>
this.request<SiteReplicationAddResponse, ApiError>({
path: `/admin/site-replication`,
method: "POST",
body: body,
secure: true,
type: ContentType.Json,
format: "json",
...params,
}),
/**
* No description
*
* @tags SiteReplication
* @name SiteReplicationEdit
* @summary Edit a Replication Site
* @request PUT:/admin/site-replication
* @secure
*/
siteReplicationEdit: (body: PeerInfo, params: RequestParams = {}) =>
this.request<PeerSiteEditResponse, ApiError>({
path: `/admin/site-replication`,
method: "PUT",
body: body,
secure: true,
type: ContentType.Json,
format: "json",
...params,
}),
/**
* No description
*
* @tags SiteReplication
* @name SiteReplicationRemove
* @summary Remove a Replication Site
* @request DELETE:/admin/site-replication
* @secure
*/
siteReplicationRemove: (body: PeerInfoRemove, params: RequestParams = {}) =>
this.request<PeerSiteRemoveResponse, ApiError>({
path: `/admin/site-replication`,
method: "DELETE",
body: body,
secure: true,
type: ContentType.Json,
format: "json",
...params,
}),
/**
* No description
*
* @tags SiteReplication
* @name GetSiteReplicationStatus
* @summary Display overall site replication status
* @request GET:/admin/site-replication/status
* @secure
*/
getSiteReplicationStatus: (
query?: {
/**
* Include Bucket stats
* @default true
*/
buckets?: boolean;
/**
* Include Group stats
* @default true
*/
groups?: boolean;
/**
* Include Policies stats
* @default true
*/
policies?: boolean;
/**
* Include Policies stats
* @default true
*/
users?: boolean;
/** Entity Type to lookup */
entityType?: string;
/** Entity Value to lookup */
entityValue?: string;
},
params: RequestParams = {},
) =>
this.request<SiteReplicationStatusResponse, ApiError>({
path: `/admin/site-replication/status`,
method: "GET",
query: query,
secure: true,
format: "json",
...params,
}),
/**
* No description
*

View File

@@ -197,9 +197,6 @@ export const IAM_PAGES = {
TIERS: "/settings/tiers",
TIERS_ADD: "/settings/tiers/add",
TIERS_ADD_SERVICE: "/settings/tiers/add/:service",
SITE_REPLICATION: "/settings/site-replication",
SITE_REPLICATION_STATUS: "/settings/site-replication/status",
SITE_REPLICATION_ADD: "/settings/site-replication/add",
};
// roles
@@ -391,18 +388,6 @@ export const IAM_PAGES_PERMISSIONS = {
IAM_SCOPES.ADMIN_SERVER_INFO,
IAM_SCOPES.ADMIN_CONFIG_UPDATE,
],
[IAM_PAGES.SITE_REPLICATION]: [
IAM_SCOPES.ADMIN_SERVER_INFO,
IAM_SCOPES.ADMIN_CONFIG_UPDATE,
],
[IAM_PAGES.SITE_REPLICATION_STATUS]: [
IAM_SCOPES.ADMIN_SERVER_INFO,
IAM_SCOPES.ADMIN_CONFIG_UPDATE,
],
[IAM_PAGES.SITE_REPLICATION_ADD]: [
IAM_SCOPES.ADMIN_SERVER_INFO,
IAM_SCOPES.ADMIN_CONFIG_UPDATE,
],
[IAM_PAGES.KMS]: [IAM_SCOPES.KMS_ALL_ACTIONS],
[IAM_PAGES.KMS_STATUS]: [IAM_SCOPES.KMS_ALL_ACTIONS, IAM_SCOPES.KMS_STATUS],
[IAM_PAGES.KMS_KEYS]: [

View File

@@ -1,624 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import {
BackLink,
Button,
ClustersIcon,
HelpBox,
PageLayout,
Box,
Grid,
ProgressBar,
InputLabel,
SectionTitle,
} from "mds";
import useApi from "../../Common/Hooks/useApi";
import { IAM_PAGES } from "../../../../common/SecureComponent/permissions";
import {
setErrorSnackMessage,
setHelpName,
setSnackBarMessage,
} from "../../../../systemSlice";
import { useAppDispatch } from "../../../../store";
import { useSelector } from "react-redux";
import { selSession } from "../../consoleSlice";
import SRSiteInputRow from "./SRSiteInputRow";
import { SiteInputRow } from "./Types";
import PageHeaderWrapper from "../../Common/PageHeaderWrapper/PageHeaderWrapper";
import HelpMenu from "../../HelpMenu";
const isValidEndPoint = (ep: string) => {
let isValidEndPointUrl = false;
try {
new URL(ep);
isValidEndPointUrl = true;
} catch (err) {
isValidEndPointUrl = false;
}
if (isValidEndPointUrl) {
return "";
} else {
return "Invalid Endpoint";
}
};
const isEmptyValue = (value: string): boolean => {
return value?.trim() === "";
};
const TableHeader = () => {
return (
<React.Fragment>
<Box>
<InputLabel>Site Name</InputLabel>
</Box>
<Box>
<InputLabel>Endpoint {"*"}</InputLabel>
</Box>
<Box>
<InputLabel>Access Key {"*"}</InputLabel>
</Box>
<Box>
<InputLabel>Secret Key {"*"}</InputLabel>
</Box>
<Box> </Box>
</React.Fragment>
);
};
const SiteTypeHeader = ({ title }: { title: string }) => {
return (
<Grid item xs={12}>
<Box
sx={{
marginBottom: "15px",
fontSize: "14px",
fontWeight: 600,
}}
>
{title}
</Box>
</Grid>
);
};
const AddReplicationSites = () => {
const dispatch = useAppDispatch();
const navigate = useNavigate();
const { serverEndPoint = "" } = useSelector(selSession);
const [currentSite, setCurrentSite] = useState<SiteInputRow[]>([
{
endpoint: serverEndPoint,
name: "",
accessKey: "",
secretKey: "",
},
]);
const [existingSites, setExistingSites] = useState<SiteInputRow[]>([]);
const setDefaultNewRows = () => {
const defaultNewSites = [
{ endpoint: "", name: "", accessKey: "", secretKey: "" },
];
setExistingSites(defaultNewSites);
};
const [isSiteInfoLoading, invokeSiteInfoApi] = useApi(
(res: any) => {
const { sites: siteList, name: curSiteName } = res;
// current site name to be the fist one.
const foundIdx = siteList.findIndex((el: any) => el.name === curSiteName);
if (foundIdx !== -1) {
let curSite = siteList[foundIdx];
curSite = {
...curSite,
isCurrent: true,
isSaved: true,
};
setCurrentSite([curSite]);
siteList.splice(foundIdx, 1);
}
siteList.sort((x: any, y: any) => {
return x.name === curSiteName ? -1 : y.name === curSiteName ? 1 : 0;
});
let existingSiteList = siteList.map((si: any) => {
return {
...si,
accessKey: "",
secretKey: "",
isSaved: true,
};
});
if (existingSiteList.length) {
setExistingSites(existingSiteList);
} else {
setDefaultNewRows();
}
},
(err: any) => {
setDefaultNewRows();
},
);
const getSites = () => {
invokeSiteInfoApi("GET", `api/v1/admin/site-replication`);
};
useEffect(() => {
getSites();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
dispatch(setHelpName("add-replication-sites"));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const existingEndPointsValidity = existingSites.reduce(
(acc: string[], cv, i) => {
const epValue = existingSites[i].endpoint;
const isEpValid = isValidEndPoint(epValue);
if (isEpValid === "" && epValue !== "") {
acc.push(isEpValid);
}
return acc;
},
[],
);
const isExistingCredsValidity = existingSites
.map((site) => {
return !isEmptyValue(site.accessKey) && !isEmptyValue(site.secretKey);
})
.filter(Boolean);
const { accessKey: cAccessKey, secretKey: cSecretKey } = currentSite[0];
const isCurCredsValid =
!isEmptyValue(cAccessKey) && !isEmptyValue(cSecretKey);
const peerEndpointsValid =
existingEndPointsValidity.length === existingSites.length;
const peerCredsValid =
isExistingCredsValidity.length === existingSites.length;
let isAllFieldsValid =
isCurCredsValid && peerEndpointsValid && peerCredsValid;
const [isAdding, invokeSiteAddApi] = useApi(
(res: any) => {
if (res.success) {
dispatch(setSnackBarMessage(res.status));
resetForm();
getSites();
navigate(IAM_PAGES.SITE_REPLICATION);
} else {
dispatch(
setErrorSnackMessage({
errorMessage: "Error",
detailedError: res.status,
}),
);
}
},
(err: any) => {
dispatch(setErrorSnackMessage(err));
},
);
const resetForm = () => {
setDefaultNewRows();
setCurrentSite((prevItems) => {
return prevItems.map((item, ix) => ({
...item,
accessKey: "",
secretKey: "",
name: "",
}));
});
};
const addSiteReplication = () => {
const curSite: any[] = currentSite?.map((es, idx) => {
return {
accessKey: es.accessKey,
secretKey: es.secretKey,
name: es.name,
endpoint: es.endpoint.trim(),
};
});
const newOrExistingSitesToAdd = existingSites.reduce(
(acc: any, ns, idx) => {
if (ns.endpoint) {
acc.push({
accessKey: ns.accessKey,
secretKey: ns.secretKey,
name: ns.name || `dr-site-${idx}`,
endpoint: ns.endpoint.trim(),
});
}
return acc;
},
[],
);
const sitesToAdd = curSite.concat(newOrExistingSitesToAdd);
invokeSiteAddApi("POST", `api/v1/admin/site-replication`, sitesToAdd);
};
const renderCurrentSite = () => {
return (
<Box
sx={{
marginTop: "15px",
}}
>
<SiteTypeHeader title={"This Site"} />
<Box
withBorders
sx={{
display: "grid",
gridTemplateColumns: ".8fr 1.2fr .8fr .8fr .2fr",
padding: "15px",
gap: "10px",
maxHeight: "430px",
overflowY: "auto",
}}
>
<TableHeader />
{currentSite.map((cs, index) => {
const accessKeyError = isEmptyValue(cs.accessKey)
? "AccessKey is required"
: "";
const secretKeyError = isEmptyValue(cs.secretKey)
? "SecretKey is required"
: "";
return (
<SRSiteInputRow
key={`current-${index}`}
rowData={cs}
rowId={index}
fieldErrors={{
accessKey: accessKeyError,
secretKey: secretKeyError,
}}
onFieldChange={(e, fieldName, index) => {
const filedValue = e.target.value;
if (fieldName !== "") {
setCurrentSite((prevItems) => {
return prevItems.map((item, ix) =>
ix === index
? { ...item, [fieldName]: filedValue }
: item,
);
});
}
}}
showRowActions={false}
/>
);
})}
</Box>
</Box>
);
};
const renderPeerSites = () => {
return (
<Box
sx={{
marginTop: "25px",
}}
>
<SiteTypeHeader title={"Peer Sites"} />
<Box
withBorders
sx={{
display: "grid",
gridTemplateColumns: ".8fr 1.2fr .8fr .8fr .2fr",
padding: "15px",
gap: "10px",
maxHeight: "430px",
overflowY: "auto",
}}
>
<TableHeader />
{existingSites.map((ps, index) => {
const endPointError = isValidEndPoint(ps.endpoint);
const accessKeyError = isEmptyValue(ps.accessKey)
? "AccessKey is required"
: "";
const secretKeyError = isEmptyValue(ps.secretKey)
? "SecretKey is required"
: "";
return (
<SRSiteInputRow
key={`exiting-${index}`}
rowData={ps}
rowId={index}
fieldErrors={{
endpoint: endPointError,
accessKey: accessKeyError,
secretKey: secretKeyError,
}}
onFieldChange={(e, fieldName, index) => {
const filedValue = e.target.value;
setExistingSites((prevItems) => {
return prevItems.map((item, ix) =>
ix === index
? { ...item, [fieldName]: filedValue }
: item,
);
});
}}
canAdd={true}
canRemove={index > 0 && !ps.isSaved}
onAddClick={() => {
const newRows = [...existingSites];
//add at the next index
newRows.splice(index + 1, 0, {
name: "",
endpoint: "",
accessKey: "",
secretKey: "",
});
setExistingSites(newRows);
}}
onRemoveClick={(index) => {
setExistingSites(
existingSites.filter((_, idx) => idx !== index),
);
}}
/>
);
})}
</Box>
</Box>
);
};
return (
<Fragment>
<PageHeaderWrapper
label={
<BackLink
label={"Add Replication Site"}
onClick={() => navigate(IAM_PAGES.SITE_REPLICATION)}
/>
}
actions={<HelpMenu />}
/>
<PageLayout>
<Box
sx={{
display: "grid",
padding: "25px",
gap: "25px",
gridTemplateColumns: "1fr",
border: "1px solid #eaeaea",
}}
>
<Box>
<SectionTitle separator icon={<ClustersIcon />}>
Add Sites for Replication
</SectionTitle>
{isSiteInfoLoading || isAdding ? <ProgressBar /> : null}
<Box
sx={{
fontSize: "14px",
fontStyle: "italic",
marginTop: "10px",
marginBottom: "10px",
}}
>
Note: AccessKey and SecretKey values for every site is required
while adding or editing peer sites
</Box>
<form
noValidate
autoComplete="off"
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
return addSiteReplication();
}}
>
{renderCurrentSite()}
{renderPeerSites()}
<Grid item xs={12}>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
marginTop: "20px",
gap: "15px",
}}
>
<Button
id={"clear"}
type="button"
variant="regular"
disabled={isAdding}
onClick={resetForm}
label={"Clear"}
/>
<Button
id={"save"}
type="submit"
variant="callAction"
disabled={isAdding || !isAllFieldsValid}
label={"Save"}
/>
</Box>
</Grid>
</form>
</Box>
<HelpBox
title={""}
iconComponent={null}
help={
<Fragment>
<Box
sx={{
marginTop: "-25px",
fontSize: "16px",
fontWeight: 600,
display: "flex",
alignItems: "center",
justifyContent: "flex-start",
padding: "2px",
}}
>
<Box
sx={{
backgroundColor: "#07193E",
height: "15px",
width: "15px",
display: "flex",
alignItems: "center",
justifyContent: "center",
borderRadius: "50%",
marginRight: "18px",
padding: "3px",
paddingLeft: "2px",
"& .min-icon": {
height: "11px",
width: "11px",
fill: "#ffffff",
},
}}
>
<ClustersIcon />
</Box>
About Site Replication
</Box>
<Box
sx={{
display: "flex",
flexFlow: "column",
fontSize: "14px",
flex: "2",
"& li": {
fontSize: "14px",
display: "flex",
marginTop: "15px",
marginBottom: "15px",
width: "100%",
"&.step-text": {
fontWeight: 400,
},
},
}}
>
<Box>
The following changes are replicated to all other sites
</Box>
<ul>
<li>Creation and deletion of buckets and objects</li>
<li>
Creation and deletion of all IAM users, groups, policies
and their mappings to users or groups
</li>
<li>Creation of STS credentials</li>
<li>
Creation and deletion of service accounts (except those
owned by the root user)
</li>
<li>
<Box
style={{
display: "flex",
flexFlow: "column",
justifyContent: "flex-start",
}}
>
<div
style={{
paddingTop: "1px",
}}
>
Changes to Bucket features such as
</div>
<ul>
<li>Bucket Policies</li>
<li>Bucket Tags</li>
<li>Bucket Object-Lock configurations</li>
<li>Bucket Encryption configuration</li>
</ul>
</Box>
</li>
<li>
<Box
style={{
display: "flex",
flexFlow: "column",
justifyContent: "flex-start",
}}
>
<div
style={{
paddingTop: "1px",
}}
>
The following Bucket features will NOT be replicated
</div>
<ul>
<li>Bucket notification configuration</li>
<li>Bucket lifecycle (ILM) configuration</li>
</ul>
</Box>
</li>
</ul>
</Box>
</Fragment>
}
/>
</Box>
</PageLayout>
</Fragment>
);
};
export default AddReplicationSites;

View File

@@ -1,162 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useState } from "react";
import { Box, Button, EditIcon, Grid, InputBox, InputLabel } from "mds";
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
import useApi from "../../Common/Hooks/useApi";
import {
setErrorSnackMessage,
setSnackBarMessage,
} from "../../../../systemSlice";
import { useAppDispatch } from "../../../../store";
import { modalStyleUtils } from "../../Common/FormComponents/common/styleLibrary";
import styled from "styled-components";
import get from "lodash/get";
const SiteEndpointContainer = styled.div(({ theme }) => ({
"& .alertText": {
color: get(theme, "signalColors.danger", "#C51B3F"),
},
}));
const EditSiteEndPoint = ({
editSite = {},
onClose,
onComplete,
}: {
editSite: any;
onClose: () => void;
onComplete: () => void;
}) => {
const dispatch = useAppDispatch();
const [editEndPointName, setEditEndPointName] = useState<string>("");
const [isEditing, invokeSiteEditApi] = useApi(
(res: any) => {
if (res.success) {
dispatch(setSnackBarMessage(res.status));
} else {
dispatch(
setErrorSnackMessage({
errorMessage: "Error",
detailedError: res.status,
}),
);
}
onComplete();
},
(err: any) => {
dispatch(setErrorSnackMessage(err));
onComplete();
},
);
const updatePeerSite = () => {
invokeSiteEditApi("PUT", `api/v1/admin/site-replication`, {
endpoint: editEndPointName,
name: editSite.name,
deploymentId: editSite.deploymentID, // readonly
});
};
let isValidEndPointUrl = false;
try {
new URL(editEndPointName);
isValidEndPointUrl = true;
} catch (err) {
isValidEndPointUrl = false;
}
return (
<ModalWrapper
title={`Edit Replication Endpoint `}
modalOpen={true}
titleIcon={<EditIcon />}
onClose={onClose}
>
<SiteEndpointContainer>
<Box
sx={{
display: "flex",
flexFlow: "column",
marginBottom: "15px",
}}
>
<Box sx={{ marginBottom: "10px" }}>
<strong>Site:</strong> {" "}
{editSite.name}
</Box>
<Box sx={{ marginBottom: "10px" }}>
<strong>Current Endpoint:</strong> {" "}
{editSite.endpoint}
</Box>
</Box>
<Grid item xs={12}>
<InputLabel sx={{ marginBottom: 5 }}>New Endpoint:</InputLabel>
<InputBox
id="edit-rep-peer-endpoint"
name="edit-rep-peer-endpoint"
placeholder={"https://dr.minio-storage:9000"}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setEditEndPointName(event.target.value);
}}
label=""
value={editEndPointName}
/>
</Grid>
<Grid
item
xs={12}
sx={{
marginBottom: 15,
fontStyle: "italic",
display: "flex",
alignItems: "center",
fontSize: "12px",
marginTop: 2,
}}
>
<strong>Note:</strong>&nbsp;
<span className={"alertText"}>
Access Key and Secret Key should be same on the new site/endpoint.
</span>
</Grid>
</SiteEndpointContainer>
<Grid item xs={12} sx={modalStyleUtils.modalButtonBar}>
<Button
id={"close"}
type="button"
variant="regular"
onClick={onClose}
label={"Cancel"}
/>
<Button
id={"update"}
type="button"
variant="callAction"
disabled={isEditing || !isValidEndPointUrl}
onClick={updatePeerSite}
label={"Update"}
/>
</Grid>
</ModalWrapper>
);
};
export default EditSiteEndPoint;

View File

@@ -1,220 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useState } from "react";
import {
Box,
breakPoints,
Button,
ClustersIcon,
Grid,
Loader,
Select,
InputBox,
} from "mds";
import useApi from "../../Common/Hooks/useApi";
import { StatsResponseType } from "./SiteReplicationStatus";
import BucketEntityStatus from "./LookupStatus/BucketEntityStatus";
import PolicyEntityStatus from "./LookupStatus/PolicyEntityStatus";
import GroupEntityStatus from "./LookupStatus/GroupEntityStatus";
import UserEntityStatus from "./LookupStatus/UserEntityStatus";
import TooltipWrapper from "../../Common/TooltipWrapper/TooltipWrapper";
const EntityReplicationLookup = () => {
const [entityType, setEntityType] = useState<string>("bucket");
const [entityValue, setEntityValue] = useState<string>("");
const [stats, setStats] = useState<StatsResponseType>({});
const [statsLoaded, setStatsLoaded] = useState<boolean>(false);
const [isStatsLoading, invokeSiteStatsApi] = useApi(
(res: any) => {
setStats(res);
setStatsLoaded(true);
},
(err: any) => {
setStats({});
setStatsLoaded(true);
},
);
const {
bucketStats = {},
sites = {},
userStats = {},
policyStats = {},
groupStats = {},
} = stats || {};
const getStats = (entityType: string = "", entityValue: string = "") => {
setStatsLoaded(false);
if (entityType && entityValue) {
let url = `api/v1/admin/site-replication/status?buckets=false&entityType=${entityType}&entityValue=${entityValue}&groups=false&policies=false&users=false`;
invokeSiteStatsApi("GET", url);
}
};
return (
<Box>
<Box
sx={{
display: "grid",
alignItems: "center",
gridTemplateColumns: ".7fr .9fr 1.2fr .3fr",
[`@media (max-width: ${breakPoints.sm}px)`]: {
gridTemplateColumns: "1fr",
},
[`@media (max-width: ${breakPoints.md}px)`]: {
gridTemplateColumns: "1.2fr .7fr .7fr .3fr",
},
gap: "15px",
}}
>
<Box sx={{ width: "240px", flexGrow: "0" }}>
View Replication Status for a:
</Box>
<Box
sx={{
marginLeft: -25,
[`@media (max-width: ${breakPoints.sm}px)`]: {
marginLeft: 0,
},
}}
>
<Select
id="replicationEntityLookup"
name="replicationEntityLookup"
onChange={(value) => {
setEntityType(value);
setStatsLoaded(false);
}}
label=""
value={entityType}
options={[
{
label: "Bucket",
value: "bucket",
},
{
label: "User",
value: "user",
},
{
label: "Group",
value: "group",
},
{
label: "Policy",
value: "policy",
},
]}
disabled={false}
/>
</Box>
<Box
sx={{
flex: 2,
}}
>
<InputBox
id="replicationLookupEntityValue"
name="replicationLookupEntityValue"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setEntityValue(e.target.value);
setStatsLoaded(false);
}}
placeholder={`test-${entityType}`}
label=""
value={entityValue}
/>
</Box>
<Box
sx={{
maxWidth: "80px",
}}
>
<TooltipWrapper tooltip={"View across sites"}>
<Button
id={"view-across-sites"}
type={"button"}
onClick={() => {
getStats(entityType, entityValue);
}}
label={`View`}
icon={<ClustersIcon />}
collapseOnSmall={false}
disabled={!entityValue || !entityType}
/>
</TooltipWrapper>
</Box>
</Box>
{isStatsLoading ? (
<Grid
item
xs={12}
sx={{
display: "flex",
alignItems: "center",
justifyContent: "center",
marginTop: 45,
}}
>
<Loader style={{ width: 25, height: 25 }} />
</Grid>
) : null}
{statsLoaded ? (
<Box>
{!isStatsLoading && entityType === "bucket" && entityValue ? (
<BucketEntityStatus
bucketStats={bucketStats}
sites={sites}
lookupValue={entityValue}
/>
) : null}
{!isStatsLoading && entityType === "user" && entityValue ? (
<UserEntityStatus
userStats={userStats}
sites={sites}
lookupValue={entityValue}
/>
) : null}
{!isStatsLoading && entityType === "group" && entityValue ? (
<GroupEntityStatus
groupStats={groupStats}
sites={sites}
lookupValue={entityValue}
/>
) : null}
{!isStatsLoading && entityType === "policy" && entityValue ? (
<PolicyEntityStatus
policyStats={policyStats}
sites={sites}
lookupValue={entityValue}
/>
) : null}
</Box>
) : null}
</Box>
);
};
export default EntityReplicationLookup;

View File

@@ -1,129 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React from "react";
import { StatsResponseType } from "../SiteReplicationStatus";
import LookupStatusTable from "./LookupStatusTable";
import { EntityNotFound, isEntityNotFound, syncStatus } from "./Utils";
type BucketEntityStatusProps = Partial<StatsResponseType> & {
lookupValue?: string;
};
const BucketEntityStatus = ({
bucketStats = {},
sites = {},
lookupValue = "",
}: BucketEntityStatusProps) => {
const rowsForStatus = [
"Tags",
"Policy",
"Quota",
"Retention",
"Encryption",
"Replication",
];
const bucketSites: Record<string, any> = bucketStats[lookupValue] || {};
if (!lookupValue) return null;
const siteKeys = Object.keys(sites);
const notFound = isEntityNotFound(sites, bucketSites, "HasBucket");
const resultMatrix: any = [];
if (notFound) {
return <EntityNotFound entityType={"Bucket"} entityValue={lookupValue} />;
} else {
const row = [];
for (let sCol = 0; sCol < siteKeys.length; sCol++) {
if (sCol === 0) {
row.push("");
}
/**
* ----------------------------------
* | <blank cell> | sit-0 | site-1 |
* -----------------------------------
*/
row.push(sites[siteKeys[sCol]].name);
}
resultMatrix.push(row);
for (let fi = 0; fi < rowsForStatus.length; fi++) {
/**
* -------------------------------------------------
* | Feature Name | site-0-status | site-1-status |
* --------------------------------------------------
*/
const sfRow = [];
const feature = rowsForStatus[fi];
let sbStatus: string | boolean = "";
for (let si = 0; si < siteKeys.length; si++) {
const bucketSiteDeploymentId = sites[siteKeys[si]].deploymentID;
const rSite = bucketSites[bucketSiteDeploymentId];
if (si === 0) {
sfRow.push(feature);
}
switch (fi) {
case 0:
sbStatus = syncStatus(rSite.TagMismatch, rSite.HasTagsSet);
sfRow.push(sbStatus);
break;
case 1:
sbStatus = syncStatus(rSite.PolicyMismatch, rSite.HasPolicySet);
sfRow.push(sbStatus);
break;
case 2:
sbStatus = syncStatus(rSite.QuotaCfgMismatch, rSite.HasQuotaCfgSet);
sfRow.push(sbStatus);
break;
case 3:
sbStatus = syncStatus(
rSite.OLockConfigMismatch,
rSite.HasOLockConfigSet,
);
sfRow.push(sbStatus);
break;
case 4:
sbStatus = syncStatus(rSite.SSEConfigMismatch, rSite.HasSSECfgSet);
sfRow.push(sbStatus);
break;
case 5:
sbStatus = syncStatus(
rSite.ReplicationCfgMismatch,
rSite.HasReplicationCfg,
);
sfRow.push(sbStatus);
break;
}
}
resultMatrix.push(sfRow);
}
}
return (
<LookupStatusTable
matrixData={resultMatrix}
entityName={lookupValue}
entityType={"Bucket"}
/>
);
};
export default BucketEntityStatus;

View File

@@ -1,99 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React from "react";
import { StatsResponseType } from "../SiteReplicationStatus";
import LookupStatusTable from "./LookupStatusTable";
import { EntityNotFound, isEntityNotFound, syncStatus } from "./Utils";
type GroupEntityStatusProps = Partial<StatsResponseType> & {
lookupValue?: string;
};
const UserEntityStatus = ({
groupStats = {},
sites = {},
lookupValue = "",
}: GroupEntityStatusProps) => {
const rowsForStatus = ["Info", "Policy mapping"];
const groupSites: Record<string, any> = groupStats[lookupValue] || {};
if (!lookupValue) return null;
const siteKeys = Object.keys(sites);
const notFound = isEntityNotFound(sites, groupSites, "HasGroup");
const resultMatrix: any = [];
if (notFound) {
return <EntityNotFound entityType={"Group"} entityValue={lookupValue} />;
} else {
const row = [];
for (let sCol = 0; sCol < siteKeys.length; sCol++) {
if (sCol === 0) {
row.push("");
}
/**
* ----------------------------------
* | <blank cell> | sit-0 | site-1 |
* -----------------------------------
*/
row.push(sites[siteKeys[sCol]].name);
}
resultMatrix.push(row);
for (let fi = 0; fi < rowsForStatus.length; fi++) {
/**
* -------------------------------------------------
* | Feature Name | site-0-status | site-1-status |
* --------------------------------------------------
*/
const sfRow = [];
const feature = rowsForStatus[fi];
let sbStatus: string | boolean = "";
for (let si = 0; si < siteKeys.length; si++) {
const bucketSiteDeploymentId = sites[siteKeys[si]].deploymentID;
const rSite = groupSites[bucketSiteDeploymentId];
if (si === 0) {
sfRow.push(feature);
}
switch (fi) {
case 0:
sbStatus = syncStatus(rSite.GroupDescMismatch, rSite.HasGroup);
sfRow.push(sbStatus);
break;
case 1:
sbStatus = syncStatus(rSite.PolicyMismatch, rSite.HasPolicyMapping);
sfRow.push(sbStatus);
break;
}
}
resultMatrix.push(sfRow);
}
}
return (
<LookupStatusTable
matrixData={resultMatrix}
entityName={lookupValue}
entityType={"Group"}
/>
);
};
export default UserEntityStatus;

View File

@@ -1,142 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React from "react";
import styled from "styled-components";
import get from "lodash/get";
import { Box, CircleIcon } from "mds";
const LookupTableBase = styled.div(({ theme }) => ({
marginTop: 15,
table: {
width: "100%",
borderCollapse: "collapse",
"& .feature-cell": {
fontWeight: 600,
fontSize: 14,
paddingLeft: 15,
},
"& .status-cell": {
textAlign: "center",
},
"& .header-cell": {
textAlign: "center",
},
"& tr": {
height: 38,
"& td": {
borderBottom: `1px solid ${get(theme, "borderColor", "#E2E2E2")}`,
},
"& th": {
borderBottom: `2px solid ${get(theme, "borderColor", "#E2E2E2")}`,
},
},
"& .indicator": {
display: "flex",
alignItems: "center",
justifyContent: "center",
"& .min-icon": {
height: 15,
width: 15,
},
"&.active": {
"& .min-icon": {
fill: get(theme, "signalColors.good", "#4CCB92"),
},
},
"&.deactivated": {
"& .min-icon": {
fill: get(theme, "signalColors.danger", "#C51B3F"),
},
},
},
},
}));
const LookupStatusTable = ({
matrixData = [],
entityName = "",
entityType = "",
}: {
matrixData: any;
entityName: string;
entityType: string;
}) => {
//Assumes 1st row should be a header row.
const [header = [], ...rows] = matrixData;
const tableHeader = header.map((hC: string, hcIdx: number) => {
return (
<th className="header-cell" key={`${0}${hcIdx}`}>
{hC}
</th>
);
});
const tableRowsToRender = rows.map((r: any, rIdx: number) => {
return (
<tr key={`r-${rIdx + 1}`}>
{r.map((v: any, cIdx: number) => {
let indicator = null;
if (cIdx === 0) {
indicator = v;
} else if (v === "") {
indicator = "";
}
if (v === true) {
indicator = (
<Box className={`indicator active`}>
<CircleIcon />
</Box>
);
} else if (v === false) {
indicator = (
<Box className={`indicator deactivated`}>
<CircleIcon />
</Box>
);
}
return (
<td
key={`${rIdx + 1}${cIdx}`}
className={cIdx === 0 ? "feature-cell" : "status-cell"}
>
{indicator}
</td>
);
})}
</tr>
);
});
return (
<LookupTableBase>
<Box sx={{ marginTop: 15, marginBottom: 15 }}>
Replication status for {entityType}: <strong>{entityName}</strong>.
</Box>
<table>
<thead>
<tr>{tableHeader}</tr>
</thead>
<tbody>{tableRowsToRender}</tbody>
</table>
</LookupTableBase>
);
};
export default LookupStatusTable;

View File

@@ -1,85 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React from "react";
import { StatsResponseType } from "../SiteReplicationStatus";
import LookupStatusTable from "./LookupStatusTable";
import { EntityNotFound, isEntityNotFound, syncStatus } from "./Utils";
type PolicyEntityStatusProps = Partial<StatsResponseType> & {
lookupValue?: string;
};
const PolicyEntityStatus = ({
policyStats = {},
sites = {},
lookupValue = "",
}: PolicyEntityStatusProps) => {
const rowsForStatus = ["Policy"];
const policySites: Record<string, any> = policyStats[lookupValue] || {};
if (!lookupValue) return null;
const siteKeys = Object.keys(sites);
const notFound = isEntityNotFound(sites, policySites, "HasPolicy");
const resultMatrix: any = [];
if (notFound) {
return <EntityNotFound entityType={"Policy"} entityValue={lookupValue} />;
} else {
const row = [];
for (let sCol = 0; sCol < siteKeys.length; sCol++) {
if (sCol === 0) {
row.push("");
}
row.push(sites[siteKeys[sCol]].name);
}
resultMatrix.push(row);
for (let fi = 0; fi < rowsForStatus.length; fi++) {
const sfRow = [];
const feature = rowsForStatus[fi];
let sbStatus: string | boolean = "";
for (let si = 0; si < siteKeys.length; si++) {
const bucketSiteDeploymentId = sites[siteKeys[si]].deploymentID;
const rSite = policySites[bucketSiteDeploymentId];
if (si === 0) {
sfRow.push(feature);
}
switch (fi) {
case 0:
sbStatus = syncStatus(rSite.PolicyMismatch, rSite.HasPolicy);
sfRow.push(sbStatus);
break;
}
}
resultMatrix.push(sfRow);
}
}
return (
<LookupStatusTable
matrixData={resultMatrix}
entityName={lookupValue}
entityType={"Policy"}
/>
);
};
export default PolicyEntityStatus;

View File

@@ -1,91 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React from "react";
import { StatsResponseType } from "../SiteReplicationStatus";
import LookupStatusTable from "./LookupStatusTable";
import { EntityNotFound, isEntityNotFound, syncStatus } from "./Utils";
type PolicyEntityStatusProps = Partial<StatsResponseType> & {
lookupValue?: string;
};
const UserEntityStatus = ({
userStats = {},
sites = {},
lookupValue = "",
}: PolicyEntityStatusProps) => {
const rowsForStatus = ["Info", "Policy mapping"];
const userSites: Record<string, any> = userStats[lookupValue] || {};
if (!lookupValue) return null;
const siteKeys = Object.keys(sites);
const notFound = isEntityNotFound(sites, userSites, "HasUser");
const resultMatrix: any = [];
if (notFound) {
return <EntityNotFound entityType={"User"} entityValue={lookupValue} />;
} else {
const row = [];
for (let sCol = 0; sCol < siteKeys.length; sCol++) {
if (sCol === 0) {
row.push("");
}
row.push(sites[siteKeys[sCol]].name);
}
resultMatrix.push(row);
for (let fi = 0; fi < rowsForStatus.length; fi++) {
const sfRow = [];
const feature = rowsForStatus[fi];
let sbStatus: string | boolean = "";
for (let si = 0; si < siteKeys.length; si++) {
const bucketSiteDeploymentId = sites[siteKeys[si]].deploymentID;
const rSite = userSites[bucketSiteDeploymentId];
if (si === 0) {
sfRow.push(feature);
}
switch (fi) {
case 0:
sbStatus = syncStatus(rSite.UserInfoMismatch, rSite.HasUser);
sfRow.push(sbStatus);
break;
case 1:
sbStatus = syncStatus(rSite.PolicyMismatch, rSite.HasPolicyMapping);
sfRow.push(sbStatus);
break;
}
}
resultMatrix.push(sfRow);
}
}
return (
<LookupStatusTable
matrixData={resultMatrix}
entityName={lookupValue}
entityType={"User"}
/>
);
};
export default UserEntityStatus;

View File

@@ -1,49 +0,0 @@
import React from "react";
import { StatsResponseType } from "../SiteReplicationStatus";
import { Box } from "mds";
export function syncStatus(mismatch: boolean, set: boolean): string | boolean {
if (!set) {
return "";
}
return !mismatch;
}
export function isEntityNotFound(
sites: Partial<StatsResponseType>,
lookupList: Partial<StatsResponseType>,
lookupKey: string,
) {
const siteKeys: string[] = Object.keys(sites);
return siteKeys.find((sk: string) => {
// there is no way to find the type of this ! as it is an entry in the structure itself.
// @ts-ignore
const result: Record<string, any> = lookupList[sk] || {};
return !result[lookupKey];
});
}
export const EntityNotFound = ({
entityType,
entityValue,
}: {
entityType: string;
entityValue: string;
}) => {
return (
<Box
sx={{
marginTop: "45px",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
{entityType}:{" "}
<Box sx={{ marginLeft: "5px", marginRight: "5px", fontWeight: 600 }}>
{entityValue}
</Box>{" "}
not found.
</Box>
);
};

View File

@@ -1,147 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useState } from "react";
import {
Box,
CircleIcon,
ConfirmDeleteIcon,
DataTable,
IColumns,
ItemActions,
Tooltip,
} from "mds";
import styled from "styled-components";
import get from "lodash/get";
import { ReplicationSite } from "./SiteReplication";
import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
import EditSiteEndPoint from "./EditSiteEndPoint";
const EndpointRender = styled.div(({ theme }) => ({
display: "flex",
gap: 10,
"& .currentIndicator": {
"& .min-icon": {
width: 12,
height: 12,
fill: get(theme, "signalColors.good", "#4CCB92"),
},
},
"& .endpointName": {
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
},
}));
const ReplicationSites = ({
sites,
onDeleteSite,
onRefresh,
}: {
sites: ReplicationSite[];
onDeleteSite: (isAll: boolean, sites: string[]) => void;
onRefresh: () => void;
}) => {
const [deleteSiteKey, setIsDeleteSiteKey] = useState<string>("");
const [editSite, setEditSite] = useState<any>(null);
const replicationColumns: IColumns[] = [
{ label: "Site Name", elementKey: "name" },
{
label: "Endpoint",
elementKey: "endpoint",
renderFullObject: true,
renderFunction: (siteInfo) => (
<EndpointRender>
{siteInfo.isCurrent ? (
<Tooltip tooltip={"This site/cluster"} placement="top">
<Box className={"currentIndicator"}>
<CircleIcon />
</Box>
</Tooltip>
) : null}
<Tooltip tooltip={siteInfo.endpoint}>
<Box className={"endpointName"}>{siteInfo.endpoint}</Box>
</Tooltip>
</EndpointRender>
),
},
];
const actions: ItemActions[] = [
{
type: "edit",
onClick: (valueToSend) => setEditSite(valueToSend),
tooltip: "Edit Endpoint",
},
{
type: "delete",
onClick: (valueToSend) => setIsDeleteSiteKey(valueToSend.name),
tooltip: "Delete Site",
},
];
return (
<Fragment>
<DataTable
columns={replicationColumns}
records={sites}
itemActions={actions}
idField={"name"}
customPaperHeight={"calc(100vh - 660px)"}
sx={{ marginBottom: 20 }}
/>
{deleteSiteKey !== "" && (
<ConfirmDialog
title={`Delete Replication Site`}
confirmText={"Delete"}
isOpen={deleteSiteKey !== ""}
titleIcon={<ConfirmDeleteIcon />}
isLoading={false}
onConfirm={() => {
onDeleteSite(false, [deleteSiteKey]);
}}
onClose={() => {
setIsDeleteSiteKey("");
}}
confirmationContent={
<Fragment>
Are you sure you want to remove the replication site:{" "}
<strong>{deleteSiteKey}</strong>?
</Fragment>
}
/>
)}
{editSite !== null && (
<EditSiteEndPoint
onComplete={() => {
setEditSite(null);
onRefresh();
}}
editSite={editSite}
onClose={() => {
setEditSite(null);
}}
/>
)}
</Fragment>
);
};
export default ReplicationSites;

View File

@@ -1,172 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment } from "react";
import TooltipWrapper from "../../Common/TooltipWrapper/TooltipWrapper";
import { AddIcon, Box, Button, Grid, InputBox, RemoveIcon } from "mds";
import { SiteInputRow } from "./Types";
interface ISRSiteInputRowProps {
rowData: SiteInputRow;
rowId: number;
onFieldChange: (e: any, fieldName: string, index: number) => void;
onAddClick?: (index: number) => void;
onRemoveClick?: (index: number) => void;
canAdd?: boolean;
canRemove?: boolean;
showRowActions?: boolean;
disabledFields?: string[];
fieldErrors?: Record<string, string>;
}
const SRSiteInputRow = ({
rowData,
rowId: index,
onFieldChange,
onAddClick,
onRemoveClick,
canAdd = true,
canRemove = true,
showRowActions = true,
disabledFields = [],
fieldErrors = {},
}: ISRSiteInputRowProps) => {
const { endpoint = "", accessKey = "", secretKey = "", name = "" } = rowData;
return (
<Fragment key={`${index}`}>
<Box>
<InputBox
id={`add-rep-peer-site-${index}`}
name={`add-rep-peer-site-${index}`}
placeholder={`site-name`}
label=""
readOnly={disabledFields.includes("name")}
value={name}
onChange={(e) => {
onFieldChange(e, "name", index);
}}
data-test-id={`add-site-rep-peer-site-${index}`}
/>
</Box>
<Box>
<InputBox
id={`add-rep-peer-site-ep-${index}`}
name={`add-rep-peer-site-ep-${index}`}
placeholder={`https://dr.minio-storage:900${index}`}
label=""
readOnly={disabledFields.includes("endpoint")}
error={fieldErrors["endpoint"]}
value={endpoint}
onChange={(e) => {
onFieldChange(e, "endpoint", index);
}}
data-test-id={`add-site-rep-peer-ep-${index}`}
/>
</Box>
<Box>
<InputBox
id={`add-rep-peer-site-ac-${index}`}
name={`add-rep-peer-site-ac-${index}`}
label=""
required={true}
disabled={disabledFields.includes("accessKey")}
value={accessKey}
error={fieldErrors["accessKey"]}
onChange={(e) => {
onFieldChange(e, "accessKey", index);
}}
data-test-id={`add-rep-peer-site-ac-${index}`}
/>
</Box>
<Box>
<InputBox
id={`add-rep-peer-site-sk-${index}`}
name={`add-rep-peer-site-sk-${index}`}
label=""
required={true}
type={"password"}
value={secretKey}
error={fieldErrors["secretKey"]}
disabled={disabledFields.includes("secretKey")}
onChange={(e) => {
onFieldChange(e, "secretKey", index);
}}
data-test-id={`add-rep-peer-site-sk-${index}`}
/>
</Box>
<Grid item xs={12} sx={{ alignItems: "center", display: "flex" }}>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "center",
alignSelf: "baseline",
marginTop: "4px",
"& button": {
borderColor: "#696969",
color: "#696969",
borderRadius: "50%",
},
}}
>
{showRowActions ? (
<React.Fragment>
<TooltipWrapper tooltip={"Add a Row"}>
<Button
id={`add-row-${index}`}
variant="regular"
disabled={!canAdd}
icon={<AddIcon />}
onClick={(e) => {
e.preventDefault();
onAddClick?.(index);
}}
style={{
width: 25,
height: 25,
padding: 0,
}}
/>
</TooltipWrapper>
<TooltipWrapper tooltip={"Remove Row"}>
<Button
id={`remove-row-${index}`}
variant="regular"
disabled={!canRemove}
icon={<RemoveIcon />}
onClick={(e) => {
e.preventDefault();
onRemoveClick?.(index);
}}
style={{
width: 25,
height: 25,
padding: 0,
marginLeft: 8,
}}
/>
</TooltipWrapper>
</React.Fragment>
) : null}
</Box>
</Grid>
</Fragment>
);
};
export default SRSiteInputRow;

View File

@@ -1,311 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import {
ActionLink,
AddIcon,
Box,
Button,
ClustersIcon,
ConfirmDeleteIcon,
Grid,
HelpBox,
Loader,
PageLayout,
RecoverIcon,
SectionTitle,
TrashIcon,
} from "mds";
import { ErrorResponseHandler } from "../../../../common/types";
import { IAM_PAGES } from "../../../../common/SecureComponent/permissions";
import {
setErrorSnackMessage,
setHelpName,
setSnackBarMessage,
} from "../../../../systemSlice";
import { useAppDispatch } from "../../../../store";
import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
import useApi from "../../Common/Hooks/useApi";
import ReplicationSites from "./ReplicationSites";
import TooltipWrapper from "../../Common/TooltipWrapper/TooltipWrapper";
import PageHeaderWrapper from "../../Common/PageHeaderWrapper/PageHeaderWrapper";
import HelpMenu from "../../HelpMenu";
export type ReplicationSite = {
deploymentID: string;
endpoint: string;
name: string;
isCurrent?: boolean;
};
const SiteReplication = () => {
const dispatch = useAppDispatch();
const navigate = useNavigate();
const [sites, setSites] = useState([]);
const [deleteAll, setIsDeleteAll] = useState(false);
const [isSiteInfoLoading, invokeSiteInfoApi] = useApi(
(res: any) => {
const { sites: siteList, name: curSiteName } = res;
// current site name to be the fist one.
const foundIdx = siteList.findIndex((el: any) => el.name === curSiteName);
if (foundIdx !== -1) {
let curSite = siteList[foundIdx];
curSite = {
...curSite,
isCurrent: true,
};
siteList.splice(foundIdx, 1, curSite);
}
siteList.sort((x: any, y: any) => {
return x.name === curSiteName ? -1 : y.name === curSiteName ? 1 : 0;
});
setSites(siteList);
},
(err: any) => {
setSites([]);
},
);
const getSites = () => {
invokeSiteInfoApi("GET", `api/v1/admin/site-replication`);
};
const [isRemoving, invokeSiteRemoveApi] = useApi(
(res: any) => {
setIsDeleteAll(false);
dispatch(setSnackBarMessage(`Successfully deleted.`));
getSites();
},
(err: ErrorResponseHandler) => {
dispatch(setErrorSnackMessage(err));
},
);
const removeSites = (isAll: boolean = false, delSites: string[] = []) => {
invokeSiteRemoveApi("DELETE", `api/v1/admin/site-replication`, {
all: isAll,
sites: delSites,
});
};
useEffect(() => {
getSites();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const hasSites = sites?.length;
useEffect(() => {
dispatch(setHelpName("site-replication"));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<Fragment>
<PageHeaderWrapper label={"Site Replication"} actions={<HelpMenu />} />
<PageLayout>
<SectionTitle
separator={!!hasSites}
sx={{ marginBottom: 15 }}
actions={
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
gap: 8,
}}
>
{hasSites ? (
<Fragment>
<TooltipWrapper tooltip={"Delete All"}>
<Button
id={"delete-all"}
label={"Delete All"}
variant="secondary"
disabled={isRemoving}
icon={<TrashIcon />}
onClick={() => {
setIsDeleteAll(true);
}}
/>
</TooltipWrapper>
<TooltipWrapper tooltip={"Replication Status"}>
<Button
id={"replication-status"}
label={"Replication Status"}
variant="regular"
icon={<RecoverIcon />}
onClick={(e) => {
e.preventDefault();
navigate(IAM_PAGES.SITE_REPLICATION_STATUS);
}}
/>
</TooltipWrapper>
</Fragment>
) : null}
<TooltipWrapper tooltip={"Add Replication Sites"}>
<Button
id={"add-replication-site"}
label={"Add Sites"}
variant="callAction"
disabled={isRemoving}
icon={<AddIcon />}
onClick={() => {
navigate(IAM_PAGES.SITE_REPLICATION_ADD);
}}
/>
</TooltipWrapper>
</Box>
}
>
{hasSites ? "List of Replicated Sites" : ""}
</SectionTitle>
{hasSites ? (
<ReplicationSites
sites={sites}
onDeleteSite={removeSites}
onRefresh={getSites}
/>
) : null}
{isSiteInfoLoading ? (
<Box
sx={{
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "calc( 100vh - 450px )",
}}
>
<Loader style={{ width: 16, height: 16 }} />
</Box>
) : null}
{!hasSites && !isSiteInfoLoading ? (
<Grid container>
<Grid item xs={8}>
<HelpBox
title={"Site Replication"}
iconComponent={<ClustersIcon />}
help={
<Fragment>
This feature allows multiple independent MinIO sites (or
clusters) that are using the same external IDentity Provider
(IDP) to be configured as replicas.
<br />
<br />
To get started,{" "}
<ActionLink
isLoading={false}
label={""}
onClick={() => {
navigate(IAM_PAGES.SITE_REPLICATION_ADD);
}}
>
Add a Replication Site
</ActionLink>
.
<br />
You can learn more at our{" "}
<a
href="https://min.io/docs/minio/linux/operations/install-deploy-manage/multi-site-replication.html?ref=con"
target="_blank"
rel="noopener"
>
documentation
</a>
.
</Fragment>
}
/>
</Grid>
</Grid>
) : null}
{hasSites && !isSiteInfoLoading ? (
<HelpBox
title={"Site Replication"}
iconComponent={<ClustersIcon />}
help={
<Fragment>
This feature allows multiple independent MinIO sites (or
clusters) that are using the same external IDentity Provider
(IDP) to be configured as replicas. In this situation the set of
replica sites are referred to as peer sites or just sites.
<br />
<br />
Initially, only one of the sites added for replication may have
data. After site-replication is successfully configured, this
data is replicated to the other (initially empty) sites.
Subsequently, objects may be written to any of the sites, and
they will be replicated to all other sites.
<br />
<br />
All sites must have the same deployment credentials (i.e.
MINIO_ROOT_USER, MINIO_ROOT_PASSWORD).
<br />
<br />
All sites must be using the same external IDP(s) if any.
<br />
<br />
For SSE-S3 or SSE-KMS encryption via KMS, all sites must have
access to a central KMS deployment server.
<br />
<br />
You can learn more at our{" "}
<a
href="https://github.com/minio/minio/tree/master/docs/site-replication?ref=con"
target="_blank"
rel="noopener"
>
documentation
</a>
.
</Fragment>
}
/>
) : null}
{deleteAll ? (
<ConfirmDialog
title={`Delete All`}
confirmText={"Delete"}
isOpen={true}
titleIcon={<ConfirmDeleteIcon />}
isLoading={false}
onConfirm={() => {
const siteNames = sites.map((s: any) => s.name);
removeSites(true, siteNames);
}}
onClose={() => {
setIsDeleteAll(false);
}}
confirmationContent={
<Fragment>
Are you sure you want to remove all the replication sites?.
</Fragment>
}
/>
) : null}
</PageLayout>
</Fragment>
);
};
export default SiteReplication;

View File

@@ -1,251 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useEffect, useState } from "react";
import {
BackLink,
Box,
breakPoints,
BucketsIcon,
Button,
Grid,
GroupsIcon,
IAMPoliciesIcon,
Loader,
PageLayout,
RefreshIcon,
UsersIcon,
SectionTitle,
} from "mds";
import { useNavigate } from "react-router-dom";
import { IAM_PAGES } from "../../../../common/SecureComponent/permissions";
import { useAppDispatch } from "../../../../store";
import { setErrorSnackMessage, setHelpName } from "../../../../systemSlice";
import StatusCountCard from "../../Dashboard/BasicDashboard/StatusCountCard";
import EntityReplicationLookup from "./EntityReplicationLookup";
import TooltipWrapper from "../../Common/TooltipWrapper/TooltipWrapper";
import PageHeaderWrapper from "../../Common/PageHeaderWrapper/PageHeaderWrapper";
import HelpMenu from "../../HelpMenu";
import { api } from "api";
import { errorToHandler } from "api/errors";
import {
ApiError,
HttpResponse,
SiteReplicationStatusResponse,
} from "api/consoleApi";
export type StatsResponseType = {
maxBuckets?: number;
bucketStats?: Record<string, any>;
maxGroups?: number;
groupStats?: Record<string, any>;
maxUsers?: number;
userStats?: Record<string, any>;
maxPolicies?: number;
policyStats?: Record<string, any>;
sites?: Record<string, any>;
};
const SREntityStatus = ({
maxValue = 0,
entityStatObj = {},
entityTextPlural = "",
icon = null,
}: {
maxValue: number;
entityStatObj: Record<string, any>;
entityTextPlural: string;
icon?: React.ReactNode;
}) => {
const statEntityLen = Object.keys(entityStatObj || {})?.length;
return (
<Box
withBorders
sx={{
padding: "25px",
[`@media (min-width: ${breakPoints.sm}px)`]: {
maxWidth: "100%",
},
}}
>
<StatusCountCard
icon={icon}
onlineCount={maxValue}
offlineCount={statEntityLen}
okStatusText={"Synced"}
notOkStatusText={"Failed"}
label={entityTextPlural}
/>
</Box>
);
};
const SiteReplicationStatus = () => {
const navigate = useNavigate();
const [stats, setStats] = useState<StatsResponseType>({});
const [loading, setLoading] = useState<boolean>(false);
const {
maxBuckets = 0,
bucketStats = {},
maxGroups = 0,
groupStats = {},
maxUsers = 0,
userStats = {},
maxPolicies = 0,
policyStats = {},
} = stats || {};
const getStats = () => {
setLoading(true);
api.admin
.getSiteReplicationStatus({
buckets: true,
groups: true,
policies: true,
users: true,
})
.then((res: HttpResponse<SiteReplicationStatusResponse, ApiError>) => {
setStats(res.data);
})
.catch((res: HttpResponse<SiteReplicationStatusResponse, ApiError>) => {
setStats({});
dispatch(setErrorSnackMessage(errorToHandler(res.error)));
})
.finally(() => setLoading(false));
};
useEffect(() => {
getStats();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const dispatch = useAppDispatch();
useEffect(() => {
dispatch(setHelpName("replication_status"));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<Fragment>
<PageHeaderWrapper
label={
<BackLink
label={"Site Replication"}
onClick={() => navigate(IAM_PAGES.SITE_REPLICATION)}
/>
}
actions={<HelpMenu />}
/>
<PageLayout>
<SectionTitle
actions={
<Fragment>
<TooltipWrapper tooltip={"Refresh"}>
<Button
id={"refresh"}
onClick={() => {
getStats();
}}
label={"Refresh"}
icon={<RefreshIcon />}
variant={"regular"}
collapseOnSmall={false}
/>
</TooltipWrapper>
</Fragment>
}
separator
>
Replication status from all Sites
</SectionTitle>
{!loading ? (
<Box
sx={{
display: "grid",
marginTop: "25px",
gridTemplateColumns: "1fr 1fr 1fr 1fr",
[`@media (max-width: ${breakPoints.md}px)`]: {
gridTemplateColumns: "1fr 1fr",
},
[`@media (max-width: ${breakPoints.sm}px)`]: {
gridTemplateColumns: "1fr",
},
gap: "30px",
}}
>
<SREntityStatus
entityStatObj={bucketStats}
entityTextPlural={"Buckets"}
maxValue={maxBuckets}
icon={<BucketsIcon />}
/>
<SREntityStatus
entityStatObj={userStats}
entityTextPlural={"Users"}
maxValue={maxUsers}
icon={<UsersIcon />}
/>
<SREntityStatus
entityStatObj={groupStats}
entityTextPlural={"Groups"}
maxValue={maxGroups}
icon={<GroupsIcon />}
/>
<SREntityStatus
entityStatObj={policyStats}
entityTextPlural={"Policies"}
maxValue={maxPolicies}
icon={<IAMPoliciesIcon />}
/>
</Box>
) : (
<Grid
item
xs={12}
sx={{
display: "flex",
alignItems: "center",
justifyContent: "center",
marginTop: 45,
}}
>
<Loader style={{ width: 25, height: 25 }} />
</Grid>
)}
<Box
withBorders
sx={{
minHeight: 450,
[`@media (max-width: ${breakPoints.sm}px)`]: {
minHeight: 250,
},
marginTop: "25px",
padding: "25px",
}}
>
<EntityReplicationLookup />
</Box>
</PageLayout>
</Fragment>
);
};
export default SiteReplicationStatus;

View File

@@ -1,8 +0,0 @@
export type SiteInputRow = {
name: string;
endpoint: string;
accessKey: string;
secretKey: string;
isCurrent?: boolean;
isSaved?: boolean;
};

View File

@@ -123,16 +123,6 @@ const ConfigurationOptions = React.lazy(
);
const AddGroupScreen = React.lazy(() => import("./Groups/AddGroupScreen"));
const SiteReplication = React.lazy(
() => import("./Configurations/SiteReplication/SiteReplication"),
);
const SiteReplicationStatus = React.lazy(
() => import("./Configurations/SiteReplication/SiteReplicationStatus"),
);
const AddReplicationSites = React.lazy(
() => import("./Configurations/SiteReplication/AddReplicationSites"),
);
const KMSRoutes = React.lazy(() => import("./KMS/KMSRoutes"));
@@ -358,18 +348,6 @@ const Console = () => {
component: ListTiersConfiguration,
path: IAM_PAGES.TIERS,
},
{
component: SiteReplication,
path: IAM_PAGES.SITE_REPLICATION,
},
{
component: SiteReplicationStatus,
path: IAM_PAGES.SITE_REPLICATION_STATUS,
},
{
component: AddReplicationSites,
path: IAM_PAGES.SITE_REPLICATION_ADD,
},
{
component: Account,
path: IAM_PAGES.ACCOUNT,

View File

@@ -40,7 +40,6 @@ import {
MetricsMenuIcon,
MonitoringMenuIcon,
ObjectBrowserIcon,
RecoverIcon,
SettingsIcon,
TiersIcon,
UsersMenuIcon,
@@ -219,13 +218,6 @@ export const validRoutes = (
icon: <TiersIcon />,
id: "tiers",
},
{
group: "Administrator",
path: IAM_PAGES.SITE_REPLICATION,
name: "Site Replication",
icon: <RecoverIcon />,
id: "sitereplication",
},
{
group: "Administrator",
path: IAM_PAGES.KMS_KEYS,

View File

@@ -197,7 +197,6 @@ export const {
setModalErrorSnackMessage,
setModalSnackMessage,
globalSetDistributedSetup,
setSiteReplicationInfo,
setOverrideStyles,
setAnonymousMode,
resetSystem,

View File

@@ -1,49 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import * as roles from "../utils/roles";
import { IAM_PAGES } from "../../src/common/SecureComponent/permissions";
import { Selector } from "testcafe";
import { getMenuElement } from "../utils/elements-menu";
let testDomainUrl = "http://localhost:9090";
const screenUrl = `${testDomainUrl}${IAM_PAGES.SITE_REPLICATION}`;
const siteReplicationEl = getMenuElement("sitereplication");
export const addSitesBtn = Selector("button").withText("Add Sites");
/* Begin Local Testing config block */
// For local Testing Create users and assign policies then update here.
// Command to invoke the test locally: testcafe chrome tests/permissions/site-replication.ts
/* End Local Testing config block */
fixture("Site Replication Status for user with Admin permissions")
.page(testDomainUrl)
.beforeEach(async (t) => {
await t.useRole(roles.settings);
});
test("Site replication sidebar item exists", async (t) => {
await t.expect(siteReplicationEl.exists).ok();
});
test("Add Sites button exists", async (t) => {
const addSitesBtnExists = addSitesBtn.exists;
await t.navigateTo(screenUrl).expect(addSitesBtnExists).ok();
});
test("Add Sites button is clickable", async (t) => {
await t.navigateTo(screenUrl).click(addSitesBtn);
});

View File

@@ -1,63 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import * as roles from "../utils/roles";
import * as elements from "../utils/elements";
import { bucketDropdownOptionFor } from "../utils/elements";
import * as functions from "../utils/functions";
import { monitoringElement, watchElement } from "../utils/elements-menu";
fixture("For user with Watch permissions")
.page("http://localhost:9090")
.beforeEach(async (t) => {
await t.useRole(roles.watch);
});
test("Monitoring sidebar item exists", async (t) => {
await t.expect(monitoringElement.exists).ok();
});
test("Watch link exists in Support page", async (t) => {
await t
.expect(monitoringElement.exists)
.ok()
.click(monitoringElement)
.expect(watchElement.exists)
.ok();
});
test("Watch page can be opened", async (t) => {
await t.navigateTo("http://localhost:9090/tools/watch");
});
test
.before(async (t) => {
// Create a bucket
await functions.setUpBucket(t, "watch");
})("Start button can be clicked", async (t) => {
await t
// We need to log back in after we use the admin account to create bucket,
// using the specific role we use in this module
.useRole(roles.watch)
.navigateTo("http://localhost:9090/tools/watch")
.click(elements.bucketNameInput)
.click(bucketDropdownOptionFor("watch"))
.click(elements.startButton);
})
.after(async (t) => {
// Cleanup created bucket
await functions.cleanUpBucket(t, "watch");
});

View File

@@ -1,40 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import * as roles from "../utils/roles";
import * as elements from "../utils/elements";
import { diagnosticsElement } from "../utils/elements-menu";
fixture("For user with Diagnostics permissions").page("http://localhost:9090");
test("Diagnostics link exists in Tools page", async (t) => {
await t.useRole(roles.diagnostics).expect(diagnosticsElement.exists).ok();
});
test("Diagnostics page can be opened", async (t) => {
await t
.useRole(roles.diagnostics)
.navigateTo("http://localhost:9090/support/diagnostics");
});
test("Start Diagnostic button exists", async (t) => {
const startDiagnosticExists = elements.startDiagnosticButton.exists;
await t
.useRole(roles.diagnostics)
.navigateTo("http://localhost:9090/support/diagnostics")
.expect(startDiagnosticExists)
.ok();
});

View File

@@ -100,7 +100,7 @@ __init__() {
main() {
(yarn start &>/dev/null) &
(./console server &>/dev/null) &
(testcafe "chrome:headless" "$1" -q --skip-js-errors -c 3)
(testcafe "firefox:headless" "$1" -q --skip-js-errors -c 3)
cleanup
}

View File

@@ -14947,16 +14947,6 @@ __metadata:
languageName: node
linkType: hard
"react-use-websocket@npm:^4.8.1":
version: 4.8.1
resolution: "react-use-websocket@npm:4.8.1"
peerDependencies:
react: ">= 18.0.0"
react-dom: ">= 18.0.0"
checksum: 10c0/9106947334badc06d8af635328f1420068098130eac8f6da90e7d13cf37037cf1cf0bd528103ca3689a38097a70e10d3b577f143078254e9dd3b9aa429395116
languageName: node
linkType: hard
"react-virtual@npm:^2.8.2":
version: 2.10.4
resolution: "react-virtual@npm:2.10.4"
@@ -18194,7 +18184,6 @@ __metadata:
react-redux: "npm:^8.1.3"
react-router-dom: "npm:6.25.1"
react-scripts: "npm:5.0.1"
react-use-websocket: "npm:^4.8.1"
react-virtualized: "npm:^9.22.5"
react-window: "npm:^1.8.10"
react-window-infinite-loader: "npm:^1.0.9"