mirror of
https://github.com/OpenMaxIO/openmaxio-object-browser
synced 2026-07-01 07:41:18 -07:00
Add Sync, Bandwidth and Health Check Period to replication set (#771)
* Add Sync, Bandwidth and Health Check Period to replication set Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com> * Update Columns Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com> * Add Prefix and Tags Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com> * Last fields Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
@@ -36,31 +36,49 @@ import (
|
||||
// swagger:model bucketReplicationRule
|
||||
type BucketReplicationRule struct {
|
||||
|
||||
// bandwidth
|
||||
Bandwidth string `json:"bandwidth,omitempty"`
|
||||
|
||||
// delete marker replication
|
||||
DeleteMarkerReplication *BucketReplicationRuleMarker `json:"delete_marker_replication,omitempty"`
|
||||
DeleteMarkerReplication bool `json:"delete_marker_replication,omitempty"`
|
||||
|
||||
// deletes replication
|
||||
DeletesReplication bool `json:"deletes_replication,omitempty"`
|
||||
|
||||
// destination
|
||||
Destination *BucketReplicationDestination `json:"destination,omitempty"`
|
||||
|
||||
// health check period
|
||||
HealthCheckPeriod int64 `json:"healthCheckPeriod,omitempty"`
|
||||
|
||||
// id
|
||||
ID string `json:"id,omitempty"`
|
||||
|
||||
// metadata replication
|
||||
MetadataReplication bool `json:"metadata_replication,omitempty"`
|
||||
|
||||
// prefix
|
||||
Prefix string `json:"prefix,omitempty"`
|
||||
|
||||
// priority
|
||||
Priority int32 `json:"priority,omitempty"`
|
||||
|
||||
// status
|
||||
// Enum: [Enabled Disabled]
|
||||
Status string `json:"status,omitempty"`
|
||||
|
||||
// sync mode
|
||||
// Enum: [async sync]
|
||||
SyncMode *string `json:"syncMode,omitempty"`
|
||||
|
||||
// tags
|
||||
Tags string `json:"tags,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this bucket replication rule
|
||||
func (m *BucketReplicationRule) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateDeleteMarkerReplication(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateDestination(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -69,30 +87,16 @@ func (m *BucketReplicationRule) Validate(formats strfmt.Registry) error {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateSyncMode(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *BucketReplicationRule) validateDeleteMarkerReplication(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.DeleteMarkerReplication) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.DeleteMarkerReplication != nil {
|
||||
if err := m.DeleteMarkerReplication.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("delete_marker_replication")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *BucketReplicationRule) validateDestination(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.Destination) { // not required
|
||||
@@ -154,6 +158,49 @@ func (m *BucketReplicationRule) validateStatus(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var bucketReplicationRuleTypeSyncModePropEnum []interface{}
|
||||
|
||||
func init() {
|
||||
var res []string
|
||||
if err := json.Unmarshal([]byte(`["async","sync"]`), &res); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, v := range res {
|
||||
bucketReplicationRuleTypeSyncModePropEnum = append(bucketReplicationRuleTypeSyncModePropEnum, v)
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
// BucketReplicationRuleSyncModeAsync captures enum value "async"
|
||||
BucketReplicationRuleSyncModeAsync string = "async"
|
||||
|
||||
// BucketReplicationRuleSyncModeSync captures enum value "sync"
|
||||
BucketReplicationRuleSyncModeSync string = "sync"
|
||||
)
|
||||
|
||||
// prop value enum
|
||||
func (m *BucketReplicationRule) validateSyncModeEnum(path, location string, value string) error {
|
||||
if err := validate.EnumCase(path, location, value, bucketReplicationRuleTypeSyncModePropEnum, true); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *BucketReplicationRule) validateSyncMode(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.SyncMode) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
// value enum
|
||||
if err := m.validateSyncModeEnum("syncMode", "body", *m.SyncMode); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *BucketReplicationRule) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/validate"
|
||||
)
|
||||
|
||||
// BucketReplicationRuleMarker bucket replication rule marker
|
||||
//
|
||||
// swagger:model bucketReplicationRuleMarker
|
||||
type BucketReplicationRuleMarker struct {
|
||||
|
||||
// status
|
||||
// Enum: [Enabled Disabled]
|
||||
Status string `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this bucket replication rule marker
|
||||
func (m *BucketReplicationRuleMarker) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateStatus(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var bucketReplicationRuleMarkerTypeStatusPropEnum []interface{}
|
||||
|
||||
func init() {
|
||||
var res []string
|
||||
if err := json.Unmarshal([]byte(`["Enabled","Disabled"]`), &res); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, v := range res {
|
||||
bucketReplicationRuleMarkerTypeStatusPropEnum = append(bucketReplicationRuleMarkerTypeStatusPropEnum, v)
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
// BucketReplicationRuleMarkerStatusEnabled captures enum value "Enabled"
|
||||
BucketReplicationRuleMarkerStatusEnabled string = "Enabled"
|
||||
|
||||
// BucketReplicationRuleMarkerStatusDisabled captures enum value "Disabled"
|
||||
BucketReplicationRuleMarkerStatusDisabled string = "Disabled"
|
||||
)
|
||||
|
||||
// prop value enum
|
||||
func (m *BucketReplicationRuleMarker) validateStatusEnum(path, location string, value string) error {
|
||||
if err := validate.EnumCase(path, location, value, bucketReplicationRuleMarkerTypeStatusPropEnum, true); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *BucketReplicationRuleMarker) validateStatus(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.Status) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
// value enum
|
||||
if err := m.validateStatusEnum("status", "body", m.Status); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *BucketReplicationRuleMarker) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *BucketReplicationRuleMarker) UnmarshalBinary(b []byte) error {
|
||||
var res BucketReplicationRuleMarker
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -23,6 +23,8 @@ package models
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
@@ -39,6 +41,12 @@ type CreateRemoteBucket struct {
|
||||
// Min Length: 3
|
||||
AccessKey *string `json:"accessKey"`
|
||||
|
||||
// bandwidth
|
||||
Bandwidth int64 `json:"bandwidth,omitempty"`
|
||||
|
||||
// health check period
|
||||
HealthCheckPeriod int32 `json:"healthCheckPeriod,omitempty"`
|
||||
|
||||
// region
|
||||
Region string `json:"region,omitempty"`
|
||||
|
||||
@@ -51,6 +59,10 @@ type CreateRemoteBucket struct {
|
||||
// Required: true
|
||||
SourceBucket *string `json:"sourceBucket"`
|
||||
|
||||
// sync mode
|
||||
// Enum: [async sync]
|
||||
SyncMode *string `json:"syncMode,omitempty"`
|
||||
|
||||
// target bucket
|
||||
// Required: true
|
||||
TargetBucket *string `json:"targetBucket"`
|
||||
@@ -76,6 +88,10 @@ func (m *CreateRemoteBucket) Validate(formats strfmt.Registry) error {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateSyncMode(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateTargetBucket(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -125,6 +141,49 @@ func (m *CreateRemoteBucket) validateSourceBucket(formats strfmt.Registry) error
|
||||
return nil
|
||||
}
|
||||
|
||||
var createRemoteBucketTypeSyncModePropEnum []interface{}
|
||||
|
||||
func init() {
|
||||
var res []string
|
||||
if err := json.Unmarshal([]byte(`["async","sync"]`), &res); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, v := range res {
|
||||
createRemoteBucketTypeSyncModePropEnum = append(createRemoteBucketTypeSyncModePropEnum, v)
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
// CreateRemoteBucketSyncModeAsync captures enum value "async"
|
||||
CreateRemoteBucketSyncModeAsync string = "async"
|
||||
|
||||
// CreateRemoteBucketSyncModeSync captures enum value "sync"
|
||||
CreateRemoteBucketSyncModeSync string = "sync"
|
||||
)
|
||||
|
||||
// prop value enum
|
||||
func (m *CreateRemoteBucket) validateSyncModeEnum(path, location string, value string) error {
|
||||
if err := validate.EnumCase(path, location, value, createRemoteBucketTypeSyncModePropEnum, true); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *CreateRemoteBucket) validateSyncMode(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.SyncMode) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
// value enum
|
||||
if err := m.validateSyncModeEnum("syncMode", "body", *m.SyncMode); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *CreateRemoteBucket) validateTargetBucket(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("targetBucket", "body", m.TargetBucket); err != nil {
|
||||
|
||||
@@ -23,6 +23,7 @@ package models
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
@@ -41,19 +42,44 @@ type MultiBucketReplication struct {
|
||||
// Min Length: 3
|
||||
AccessKey *string `json:"accessKey"`
|
||||
|
||||
// bandwidth
|
||||
Bandwidth int64 `json:"bandwidth,omitempty"`
|
||||
|
||||
// buckets relation
|
||||
// Required: true
|
||||
// Min Length: 1
|
||||
BucketsRelation []*MultiBucketsRelation `json:"bucketsRelation"`
|
||||
|
||||
// health check period
|
||||
HealthCheckPeriod int32 `json:"healthCheckPeriod,omitempty"`
|
||||
|
||||
// prefix
|
||||
Prefix string `json:"prefix,omitempty"`
|
||||
|
||||
// region
|
||||
Region string `json:"region,omitempty"`
|
||||
|
||||
// replicate delete markers
|
||||
ReplicateDeleteMarkers bool `json:"replicateDeleteMarkers,omitempty"`
|
||||
|
||||
// replicate deletes
|
||||
ReplicateDeletes bool `json:"replicateDeletes,omitempty"`
|
||||
|
||||
// replicate metadata
|
||||
ReplicateMetadata bool `json:"replicateMetadata,omitempty"`
|
||||
|
||||
// secret key
|
||||
// Required: true
|
||||
// Min Length: 8
|
||||
SecretKey *string `json:"secretKey"`
|
||||
|
||||
// sync mode
|
||||
// Enum: [async sync]
|
||||
SyncMode *string `json:"syncMode,omitempty"`
|
||||
|
||||
// tags
|
||||
Tags string `json:"tags,omitempty"`
|
||||
|
||||
// target URL
|
||||
// Required: true
|
||||
TargetURL *string `json:"targetURL"`
|
||||
@@ -75,6 +101,10 @@ func (m *MultiBucketReplication) Validate(formats strfmt.Registry) error {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateSyncMode(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateTargetURL(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -136,6 +166,49 @@ func (m *MultiBucketReplication) validateSecretKey(formats strfmt.Registry) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
var multiBucketReplicationTypeSyncModePropEnum []interface{}
|
||||
|
||||
func init() {
|
||||
var res []string
|
||||
if err := json.Unmarshal([]byte(`["async","sync"]`), &res); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, v := range res {
|
||||
multiBucketReplicationTypeSyncModePropEnum = append(multiBucketReplicationTypeSyncModePropEnum, v)
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
// MultiBucketReplicationSyncModeAsync captures enum value "async"
|
||||
MultiBucketReplicationSyncModeAsync string = "async"
|
||||
|
||||
// MultiBucketReplicationSyncModeSync captures enum value "sync"
|
||||
MultiBucketReplicationSyncModeSync string = "sync"
|
||||
)
|
||||
|
||||
// prop value enum
|
||||
func (m *MultiBucketReplication) validateSyncModeEnum(path, location string, value string) error {
|
||||
if err := validate.EnumCase(path, location, value, multiBucketReplicationTypeSyncModePropEnum, true); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MultiBucketReplication) validateSyncMode(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.SyncMode) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
// value enum
|
||||
if err := m.validateSyncModeEnum("syncMode", "body", *m.SyncMode); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MultiBucketReplication) validateTargetURL(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("targetURL", "body", m.TargetURL); err != nil {
|
||||
|
||||
@@ -41,6 +41,12 @@ type RemoteBucket struct {
|
||||
// Min Length: 3
|
||||
AccessKey *string `json:"accessKey"`
|
||||
|
||||
// bandwidth
|
||||
Bandwidth int64 `json:"bandwidth,omitempty"`
|
||||
|
||||
// health check period
|
||||
HealthCheckPeriod int64 `json:"healthCheckPeriod,omitempty"`
|
||||
|
||||
// remote a r n
|
||||
// Required: true
|
||||
RemoteARN *string `json:"remoteARN"`
|
||||
@@ -60,6 +66,9 @@ type RemoteBucket struct {
|
||||
// status
|
||||
Status string `json:"status,omitempty"`
|
||||
|
||||
// sync mode
|
||||
SyncMode string `json:"syncMode,omitempty"`
|
||||
|
||||
// target bucket
|
||||
TargetBucket string `json:"targetBucket,omitempty"`
|
||||
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "/static/css/main.a19f3d53.chunk.css",
|
||||
"main.js": "/static/js/main.ad0a1441.chunk.js",
|
||||
"main.js.map": "/static/js/main.ad0a1441.chunk.js.map",
|
||||
"main.js": "/static/js/main.f0e70269.chunk.js",
|
||||
"main.js.map": "/static/js/main.f0e70269.chunk.js.map",
|
||||
"runtime-main.js": "/static/js/runtime-main.f48e99e5.js",
|
||||
"runtime-main.js.map": "/static/js/runtime-main.f48e99e5.js.map",
|
||||
"static/css/2.76b14b73.chunk.css": "/static/css/2.76b14b73.chunk.css",
|
||||
"static/js/2.1bd26e6c.chunk.js": "/static/js/2.1bd26e6c.chunk.js",
|
||||
"static/js/2.1bd26e6c.chunk.js.map": "/static/js/2.1bd26e6c.chunk.js.map",
|
||||
"static/js/2.59d83018.chunk.js": "/static/js/2.59d83018.chunk.js",
|
||||
"static/js/2.59d83018.chunk.js.map": "/static/js/2.59d83018.chunk.js.map",
|
||||
"index.html": "/index.html",
|
||||
"static/css/2.76b14b73.chunk.css.map": "/static/css/2.76b14b73.chunk.css.map",
|
||||
"static/css/main.a19f3d53.chunk.css.map": "/static/css/main.a19f3d53.chunk.css.map",
|
||||
"static/js/2.1bd26e6c.chunk.js.LICENSE.txt": "/static/js/2.1bd26e6c.chunk.js.LICENSE.txt",
|
||||
"static/js/2.59d83018.chunk.js.LICENSE.txt": "/static/js/2.59d83018.chunk.js.LICENSE.txt",
|
||||
"static/media/minio_console_logo.0837460e.svg": "/static/media/minio_console_logo.0837460e.svg",
|
||||
"static/media/minio_operator_logo.1312b7c9.svg": "/static/media/minio_operator_logo.1312b7c9.svg"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/js/runtime-main.f48e99e5.js",
|
||||
"static/css/2.76b14b73.chunk.css",
|
||||
"static/js/2.1bd26e6c.chunk.js",
|
||||
"static/js/2.59d83018.chunk.js",
|
||||
"static/css/main.a19f3d53.chunk.css",
|
||||
"static/js/main.ad0a1441.chunk.js"
|
||||
"static/js/main.f0e70269.chunk.js"
|
||||
]
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="MinIO Console"/><link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700;900&display=swap" rel="stylesheet"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="manifest" href="/manifest.json"/><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#3a4e54"/><title>MinIO Console</title><link href="/static/css/2.76b14b73.chunk.css" rel="stylesheet"><link href="/static/css/main.a19f3d53.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,l,i=r[0],a=r[1],p=r[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var a=t[i];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var i=this["webpackJsonpportal-ui"]=this["webpackJsonpportal-ui"]||[],a=i.push.bind(i);i.push=r,i=i.slice();for(var p=0;p<i.length;p++)r(i[p]);var f=a;t()}([])</script><script src="/static/js/2.1bd26e6c.chunk.js"></script><script src="/static/js/main.ad0a1441.chunk.js"></script></body></html>
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="MinIO Console"/><link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700;900&display=swap" rel="stylesheet"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="manifest" href="/manifest.json"/><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#3a4e54"/><title>MinIO Console</title><link href="/static/css/2.76b14b73.chunk.css" rel="stylesheet"><link href="/static/css/main.a19f3d53.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,l,i=r[0],a=r[1],p=r[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var a=t[i];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var i=this["webpackJsonpportal-ui"]=this["webpackJsonpportal-ui"]||[],a=i.push.bind(i);i.push=r,i=i.slice();for(var p=0;p<i.length;p++)r(i[p]);var f=a;t()}([])</script><script src="/static/js/2.59d83018.chunk.js"></script><script src="/static/js/main.f0e70269.chunk.js"></script></body></html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
portal-ui/build/static/js/main.f0e70269.chunk.js
Normal file
2
portal-ui/build/static/js/main.f0e70269.chunk.js
Normal file
File diff suppressed because one or more lines are too long
1
portal-ui/build/static/js/main.f0e70269.chunk.js.map
Normal file
1
portal-ui/build/static/js/main.f0e70269.chunk.js.map
Normal file
File diff suppressed because one or more lines are too long
@@ -26,6 +26,10 @@ import { setModalErrorSnackMessage } from "../../../../actions";
|
||||
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
|
||||
import api from "../../../../common/api";
|
||||
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
|
||||
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
|
||||
import { getBytes, k8sfactorForDropdown } from "../../../../common/utils";
|
||||
import QueryMultiSelector from "../../Common/FormComponents/QueryMultiSelector/QueryMultiSelector";
|
||||
|
||||
interface IReplicationModal {
|
||||
open: boolean;
|
||||
@@ -48,6 +52,11 @@ const styles = (theme: Theme) =>
|
||||
buttonContainer: {
|
||||
textAlign: "right",
|
||||
},
|
||||
multiContainer: {
|
||||
display: "flex",
|
||||
alignItems: "center" as const,
|
||||
justifyContent: "flex-start" as const,
|
||||
},
|
||||
...modalBasic,
|
||||
});
|
||||
|
||||
@@ -58,12 +67,23 @@ const AddReplicationModal = ({
|
||||
bucketName,
|
||||
setModalErrorSnackMessage,
|
||||
}: IReplicationModal) => {
|
||||
const [addLoading, setAddLoading] = useState(false);
|
||||
const [accessKey, setAccessKey] = useState("");
|
||||
const [secretKey, setSecretKey] = useState("");
|
||||
const [targetURL, setTargetURL] = useState("");
|
||||
const [targetBucket, setTargetBucket] = useState("");
|
||||
const [region, setRegion] = useState("");
|
||||
const [addLoading, setAddLoading] = useState<boolean>(false);
|
||||
const [accessKey, setAccessKey] = useState<string>("");
|
||||
const [secretKey, setSecretKey] = useState<string>("");
|
||||
const [targetURL, setTargetURL] = useState<string>("");
|
||||
const [targetStorageClass, setTargetStorageClass] = useState<string>("");
|
||||
const [prefix, setPrefix] = useState<string>("");
|
||||
const [targetBucket, setTargetBucket] = useState<string>("");
|
||||
const [region, setRegion] = useState<string>("");
|
||||
const [useTLS, setUseTLS] = useState<boolean>(true);
|
||||
const [repDeleteMarker, setRepDeleteMarker] = useState<boolean>(true);
|
||||
const [repDelete, setRepDelete] = useState<boolean>(true);
|
||||
const [repMetadata, setRepMetadata] = useState<boolean>(true);
|
||||
const [tags, setTags] = useState<string>("");
|
||||
const [replicationMode, setReplicationMode] = useState<string>("async");
|
||||
const [bandwidthScalar, setBandwidthScalar] = useState<string>("100");
|
||||
const [bandwidthUnit, setBandwidthUnit] = useState<string>("Gi");
|
||||
const [healthCheck, setHealthCheck] = useState<string>("60");
|
||||
|
||||
const addRecord = () => {
|
||||
const replicate = [
|
||||
@@ -73,12 +93,27 @@ const AddReplicationModal = ({
|
||||
},
|
||||
];
|
||||
|
||||
const hc = parseInt(healthCheck);
|
||||
|
||||
const endURL = `${useTLS ? "https://" : "http://"}${targetURL}`;
|
||||
|
||||
const remoteBucketsInfo = {
|
||||
accessKey: accessKey,
|
||||
secretKey: secretKey,
|
||||
targetURL: targetURL,
|
||||
targetURL: endURL,
|
||||
region: region,
|
||||
bucketsRelation: replicate,
|
||||
syncMode: replicationMode,
|
||||
bandwidth:
|
||||
replicationMode === "async"
|
||||
? parseInt(getBytes(bandwidthScalar, bandwidthUnit, true))
|
||||
: 0,
|
||||
healthCheckPeriod: hc,
|
||||
prefix: prefix,
|
||||
tags: tags,
|
||||
replicateDeleteMarkers: repDeleteMarker,
|
||||
replicateDeletes: repDelete,
|
||||
replicateMetadata: repMetadata,
|
||||
};
|
||||
|
||||
api
|
||||
@@ -129,6 +164,30 @@ const AddReplicationModal = ({
|
||||
>
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.formScrollable}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="targetURL"
|
||||
name="targetURL"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setTargetURL(e.target.value);
|
||||
}}
|
||||
placeholder="play.min.io"
|
||||
label="Target URL"
|
||||
value={targetURL}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<FormSwitchWrapper
|
||||
checked={useTLS}
|
||||
id="useTLS"
|
||||
name="useTLS"
|
||||
label="Use TLS"
|
||||
onChange={(e) => {
|
||||
setUseTLS(e.target.checked);
|
||||
}}
|
||||
value="yes"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="accessKey"
|
||||
@@ -151,18 +210,6 @@ const AddReplicationModal = ({
|
||||
value={secretKey}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="targetURL"
|
||||
name="targetURL"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setTargetURL(e.target.value);
|
||||
}}
|
||||
placeholder="https://play.min.io:9000"
|
||||
label="Target URL"
|
||||
value={targetURL}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="targetBucket"
|
||||
@@ -185,6 +232,146 @@ const AddReplicationModal = ({
|
||||
value={region}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<SelectWrapper
|
||||
id="replication_mode"
|
||||
name="replication_mode"
|
||||
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
|
||||
setReplicationMode(e.target.value as string);
|
||||
}}
|
||||
label="Replication Mode"
|
||||
value={replicationMode}
|
||||
options={[
|
||||
{ label: "Asynchronous", value: "async" },
|
||||
{ label: "Synchronous", value: "sync" },
|
||||
]}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
{replicationMode === "async" && (
|
||||
<Grid item xs={12}>
|
||||
<div className={classes.multiContainer}>
|
||||
<div>
|
||||
<InputBoxWrapper
|
||||
type="number"
|
||||
id="bandwidth_scalar"
|
||||
name="bandwidth_scalar"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setBandwidthScalar(e.target.value as string);
|
||||
}}
|
||||
label="Bandwidth"
|
||||
value={bandwidthScalar}
|
||||
min="0"
|
||||
/>
|
||||
</div>
|
||||
<div className={classes.sizeFactorContainer}>
|
||||
<SelectWrapper
|
||||
label={"Unit"}
|
||||
id="bandwidth_unit"
|
||||
name="bandwidth_unit"
|
||||
value={bandwidthUnit}
|
||||
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
|
||||
setBandwidthUnit(e.target.value as string);
|
||||
}}
|
||||
options={k8sfactorForDropdown()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Grid>
|
||||
)}
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="healthCheck"
|
||||
name="healthCheck"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setHealthCheck(e.target.value as string);
|
||||
}}
|
||||
label="Health Check Duration"
|
||||
value={healthCheck}
|
||||
/>
|
||||
</Grid>
|
||||
<h3>Object Filters</h3>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="prefix"
|
||||
name="prefix"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setPrefix(e.target.value);
|
||||
}}
|
||||
placeholder="prefix"
|
||||
label="Prefix"
|
||||
value={prefix}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<QueryMultiSelector
|
||||
name="tags"
|
||||
label="Tags"
|
||||
elements={""}
|
||||
onChange={(vl: string) => {
|
||||
setTags(vl);
|
||||
}}
|
||||
keyPlaceholder="Tag Key"
|
||||
valuePlaceholder="Tag Value"
|
||||
withBorder
|
||||
/>
|
||||
</Grid>
|
||||
<h3>Storage Configuration</h3>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="storageClass"
|
||||
name="storageClass"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setTargetStorageClass(e.target.value);
|
||||
}}
|
||||
placeholder="STANDARD_IA,REDUCED_REDUNDANCY etc"
|
||||
label="Storage Class"
|
||||
value={targetStorageClass}
|
||||
/>
|
||||
</Grid>
|
||||
<h3>Replication Options</h3>
|
||||
<Grid item xs={12}>
|
||||
<FormSwitchWrapper
|
||||
checked={repDeleteMarker}
|
||||
id="deleteMarker"
|
||||
name="deleteMarker"
|
||||
label="Delete Marker"
|
||||
onChange={(e) => {
|
||||
console.log(e);
|
||||
console.log(e.target.checked);
|
||||
setRepDeleteMarker(e.target.checked);
|
||||
}}
|
||||
value={repDeleteMarker}
|
||||
description={"Replicate soft deletes"}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<FormSwitchWrapper
|
||||
checked={repDelete}
|
||||
id="repDelete"
|
||||
name="repDelete"
|
||||
label="Deletes"
|
||||
onChange={(e) => {
|
||||
setRepDelete(e.target.checked);
|
||||
}}
|
||||
value={repDelete}
|
||||
description={"Replicate versioned deletes"}
|
||||
/>
|
||||
</Grid>
|
||||
{/*TODO: This will be enabled later on when we update the dependency on mc*/}
|
||||
{/*<Grid item xs={12}>*/}
|
||||
{/* <FormSwitchWrapper*/}
|
||||
{/* checked={repMetadata}*/}
|
||||
{/* id="repMetadata"*/}
|
||||
{/* name="repMeta"*/}
|
||||
{/* label="Replicate Metadata"*/}
|
||||
{/* onChange={(e) => {*/}
|
||||
{/* setRepMetadata(e.target.checked);*/}
|
||||
{/* }}*/}
|
||||
{/* value={repMetadata}*/}
|
||||
{/* description={"Replicate object metadata"}*/}
|
||||
{/* />*/}
|
||||
{/*</Grid>*/}
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
<Button
|
||||
|
||||
@@ -208,11 +208,11 @@ const BucketDetails = ({
|
||||
}
|
||||
const actions = res.permissions ? res.permissions : [];
|
||||
|
||||
let canGetReplication = actions.find(
|
||||
let canGetReplicationVal = actions.find(
|
||||
(s) => s.id === "GetReplicationConfiguration"
|
||||
);
|
||||
|
||||
if (canGetReplication && canGetReplication.can) {
|
||||
if (canGetReplicationVal && canGetReplicationVal.can) {
|
||||
setCanGetReplication(true);
|
||||
} else {
|
||||
setCanGetReplication(false);
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import React, { useEffect, useState, Fragment } from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import { Button, TextField } from "@material-ui/core";
|
||||
import { Button, IconButton, TextField } from "@material-ui/core";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import InputAdornment from "@material-ui/core/InputAdornment";
|
||||
import SearchIcon from "@material-ui/icons/Search";
|
||||
@@ -31,7 +31,6 @@ import {
|
||||
BucketReplication,
|
||||
BucketReplicationDestination,
|
||||
BucketReplicationRule,
|
||||
BucketReplicationRuleDeleteMarker,
|
||||
HasPermissionResponse,
|
||||
} from "../types";
|
||||
import api from "../../../../common/api";
|
||||
@@ -39,6 +38,7 @@ import TableWrapper from "../../Common/TableWrapper/TableWrapper";
|
||||
import AddReplicationModal from "./AddReplicationModal";
|
||||
import DeleteReplicationRule from "./DeleteReplicationRule";
|
||||
import { AppState } from "../../../../store";
|
||||
import RefreshIcon from "@material-ui/icons/Refresh";
|
||||
|
||||
interface IBucketReplicationProps {
|
||||
classes: any;
|
||||
@@ -63,7 +63,9 @@ const BucketReplicationPanel = ({
|
||||
}: IBucketReplicationProps) => {
|
||||
const [canPutReplication, setCanPutReplication] = useState<boolean>(false);
|
||||
const [loadingReplication, setLoadingReplication] = useState<boolean>(true);
|
||||
const [replicationRules, setReplicationRules] = useState<any[]>([]);
|
||||
const [replicationRules, setReplicationRules] = useState<
|
||||
BucketReplicationRule[]
|
||||
>([]);
|
||||
const [loadingPerms, setLoadingPerms] = useState<boolean>(true);
|
||||
const [canGetReplication, setCanGetReplication] = useState<boolean>(false);
|
||||
const [deleteReplicationModal, setDeleteReplicationModal] =
|
||||
@@ -147,7 +149,7 @@ const BucketReplicationPanel = ({
|
||||
|
||||
const closeAddReplication = () => {
|
||||
setOpenReplicationOpen(false);
|
||||
//loadAllBucketData();
|
||||
setLoadingReplication(true);
|
||||
};
|
||||
|
||||
const setOpenReplicationOpen = (open = false) => {
|
||||
@@ -171,15 +173,15 @@ const BucketReplicationPanel = ({
|
||||
return <Fragment>{events.bucket.replace("arn:aws:s3:::", "")}</Fragment>;
|
||||
};
|
||||
|
||||
const ruleDelDisplay = (events: BucketReplicationRuleDeleteMarker) => {
|
||||
return null;
|
||||
const tagDisplay = (events: BucketReplicationRule) => {
|
||||
return <Fragment>{events && events.tags !== "" ? "Yes" : "No"}</Fragment>;
|
||||
};
|
||||
|
||||
const replicationTableActions: any = [
|
||||
{
|
||||
type: "delete",
|
||||
onClick: confirmDeleteReplication,
|
||||
disableButtonFunction: () => replicationRules.length <= 1,
|
||||
disableButtonFunction: () => replicationRules.length > 1,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -220,6 +222,16 @@ const BucketReplicationPanel = ({
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<IconButton
|
||||
color="primary"
|
||||
aria-label="Refresh Replication Rules"
|
||||
component="span"
|
||||
onClick={() => {
|
||||
setLoadingReplication(true);
|
||||
}}
|
||||
>
|
||||
<RefreshIcon />
|
||||
</IconButton>
|
||||
{canPutReplication && (
|
||||
<Button
|
||||
variant="contained"
|
||||
@@ -241,7 +253,6 @@ const BucketReplicationPanel = ({
|
||||
<TableWrapper
|
||||
itemActions={replicationTableActions}
|
||||
columns={[
|
||||
{ label: "ID", elementKey: "id" },
|
||||
{
|
||||
label: "Priority",
|
||||
elementKey: "priority",
|
||||
@@ -252,9 +263,13 @@ const BucketReplicationPanel = ({
|
||||
renderFunction: ruleDestDisplay,
|
||||
},
|
||||
{
|
||||
label: "Delete Marker Replication",
|
||||
elementKey: "delete_marker_replication",
|
||||
renderFunction: ruleDelDisplay,
|
||||
label: "Prefix",
|
||||
elementKey: "prefix",
|
||||
},
|
||||
{
|
||||
label: "Tags",
|
||||
elementKey: "tags",
|
||||
renderFunction: tagDisplay,
|
||||
},
|
||||
{ label: "Status", elementKey: "status" },
|
||||
]}
|
||||
|
||||
@@ -33,7 +33,10 @@ import {
|
||||
} from "../types";
|
||||
import { niceBytes } from "../../../../common/utils";
|
||||
import { BucketList } from "../../Watch/types";
|
||||
import { hrClass } from "../../Common/FormComponents/common/styleLibrary";
|
||||
import {
|
||||
buttonsStyles,
|
||||
hrClass,
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
import api from "../../../../common/api";
|
||||
import SetAccessPolicy from "./SetAccessPolicy";
|
||||
import SetRetentionConfig from "./SetRetentionConfig";
|
||||
@@ -69,6 +72,7 @@ const styles = (theme: Theme) =>
|
||||
padding: "15px",
|
||||
},
|
||||
...hrClass,
|
||||
...buttonsStyles,
|
||||
});
|
||||
|
||||
const BucketSummary = ({
|
||||
|
||||
@@ -36,6 +36,7 @@ import GenericWizard from "../../Common/GenericWizard/GenericWizard";
|
||||
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
|
||||
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
|
||||
import { SelectorTypes } from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector";
|
||||
import { getBytes, k8sfactorForDropdown } from "../../../../common/utils";
|
||||
|
||||
interface IBulkReplicationModal {
|
||||
open: boolean;
|
||||
@@ -93,6 +94,10 @@ const AddBulkReplicationModal = ({
|
||||
const [targetURL, setTargetURL] = useState<string>("");
|
||||
const [region, setRegion] = useState<string>("");
|
||||
const [useTLS, setUseTLS] = useState<boolean>(true);
|
||||
const [replicationMode, setReplicationMode] = useState<string>("async");
|
||||
const [bandwidthScalar, setBandwidthScalar] = useState<string>("100");
|
||||
const [bandwidthUnit, setBandwidthUnit] = useState<string>("Gi");
|
||||
const [healthCheck, setHealthCheck] = useState<string>("60");
|
||||
const [relationBuckets, setRelationBuckets] = useState<string[]>([]);
|
||||
const [remoteBucketsOpts, setRemoteBucketOpts] = useState<string[]>([]);
|
||||
const [responseItem, setResponseItem] = useState<BulkReplicationItem[]>([]);
|
||||
@@ -131,12 +136,20 @@ const AddBulkReplicationModal = ({
|
||||
});
|
||||
|
||||
const endURL = `${useTLS ? "https://" : "http://"}${targetURL}`;
|
||||
const hc = parseInt(healthCheck);
|
||||
|
||||
const remoteBucketsInfo = {
|
||||
accessKey: accessKey,
|
||||
secretKey: secretKey,
|
||||
targetURL: endURL,
|
||||
region: region,
|
||||
bucketsRelation: replicate,
|
||||
syncMode: replicationMode,
|
||||
bandwidth:
|
||||
replicationMode === "async"
|
||||
? parseInt(getBytes(bandwidthScalar, bandwidthUnit, true))
|
||||
: 0,
|
||||
healthCheckPeriod: hc,
|
||||
};
|
||||
|
||||
api
|
||||
@@ -386,6 +399,67 @@ const AddBulkReplicationModal = ({
|
||||
value={region}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<SelectWrapper
|
||||
id="replication_mode"
|
||||
name="replication_mode"
|
||||
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
|
||||
setReplicationMode(e.target.value as string);
|
||||
}}
|
||||
label="Replication Mode"
|
||||
value={replicationMode}
|
||||
options={[
|
||||
{ label: "Asynchronous", value: "async" },
|
||||
{ label: "Synchronous", value: "sync" },
|
||||
]}
|
||||
/>
|
||||
</Grid>
|
||||
{replicationMode === "async" && (
|
||||
<Grid item xs={12}>
|
||||
<div className={classes.multiContainer}>
|
||||
<div>
|
||||
<InputBoxWrapper
|
||||
type="number"
|
||||
id="bandwidth_scalar"
|
||||
name="bandwidth_scalar"
|
||||
onChange={(
|
||||
e: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
setBandwidthScalar(e.target.value as string);
|
||||
}}
|
||||
label="Bandwidth"
|
||||
value={bandwidthScalar}
|
||||
min="0"
|
||||
/>
|
||||
</div>
|
||||
<div className={classes.sizeFactorContainer}>
|
||||
<SelectWrapper
|
||||
label={"Unit"}
|
||||
id="bandwidth_unit"
|
||||
name="bandwidth_unit"
|
||||
value={bandwidthUnit}
|
||||
onChange={(
|
||||
e: React.ChangeEvent<{ value: unknown }>
|
||||
) => {
|
||||
setBandwidthUnit(e.target.value as string);
|
||||
}}
|
||||
options={k8sfactorForDropdown()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Grid>
|
||||
)}
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="healthCheck"
|
||||
name="healthCheck"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setHealthCheck(e.target.value as string);
|
||||
}}
|
||||
label="Health Check Duration"
|
||||
value={healthCheck}
|
||||
/>
|
||||
</Grid>
|
||||
</Fragment>
|
||||
),
|
||||
buttons: [
|
||||
|
||||
@@ -73,8 +73,13 @@ export interface BucketReplicationRule {
|
||||
id: string;
|
||||
status: string;
|
||||
priority: number;
|
||||
delete_marker_replication: BucketReplicationRuleDeleteMarker;
|
||||
delete_marker_replication: boolean;
|
||||
deletes_replication: boolean;
|
||||
metadata_replication: boolean;
|
||||
prefix?: string;
|
||||
tags?: string;
|
||||
Destination: BucketReplicationDestination;
|
||||
syncMode: string;
|
||||
}
|
||||
|
||||
export interface BucketReplication {
|
||||
|
||||
@@ -116,7 +116,7 @@ const QueryMultiSelector = ({
|
||||
// Use effect to send new values to onChange
|
||||
useEffect(() => {
|
||||
const refScroll = bottomList.current;
|
||||
if (refScroll) {
|
||||
if (refScroll && currentKeys.length > 1) {
|
||||
refScroll.scrollIntoView(false);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
|
||||
@@ -187,14 +187,20 @@ func listRemoteBuckets(ctx context.Context, client MinioAdmin) ([]*models.Remote
|
||||
}
|
||||
for _, bucket := range buckets {
|
||||
remoteBucket := &models.RemoteBucket{
|
||||
AccessKey: swag.String(bucket.Credentials.AccessKey),
|
||||
RemoteARN: swag.String(bucket.Arn),
|
||||
SecretKey: bucket.Credentials.SecretKey,
|
||||
Service: "replication",
|
||||
SourceBucket: swag.String(bucket.SourceBucket),
|
||||
Status: "",
|
||||
TargetBucket: bucket.TargetBucket,
|
||||
TargetURL: bucket.Endpoint,
|
||||
AccessKey: swag.String(bucket.Credentials.AccessKey),
|
||||
RemoteARN: swag.String(bucket.Arn),
|
||||
SecretKey: bucket.Credentials.SecretKey,
|
||||
Service: "replication",
|
||||
SourceBucket: swag.String(bucket.SourceBucket),
|
||||
Status: "",
|
||||
TargetBucket: bucket.TargetBucket,
|
||||
TargetURL: bucket.Endpoint,
|
||||
SyncMode: "async",
|
||||
Bandwidth: bucket.BandwidthLimit,
|
||||
HealthCheckPeriod: int64(bucket.HealthCheckDuration.Seconds()),
|
||||
}
|
||||
if bucket.ReplicationSync {
|
||||
remoteBucket.SyncMode = "sync"
|
||||
}
|
||||
remoteBuckets = append(remoteBuckets, remoteBucket)
|
||||
}
|
||||
@@ -244,21 +250,28 @@ func addRemoteBucket(ctx context.Context, client MinioAdmin, params models.Creat
|
||||
}
|
||||
creds := &auth.Credentials{AccessKey: accessKey, SecretKey: secretKey}
|
||||
remoteBucket := &madmin.BucketTarget{
|
||||
TargetBucket: *params.TargetBucket,
|
||||
Secure: secure,
|
||||
Credentials: creds,
|
||||
Endpoint: host,
|
||||
Path: "",
|
||||
API: "s3v4",
|
||||
Type: "replication",
|
||||
Region: params.Region,
|
||||
TargetBucket: *params.TargetBucket,
|
||||
Secure: secure,
|
||||
Credentials: creds,
|
||||
Endpoint: host,
|
||||
Path: "",
|
||||
API: "s3v4",
|
||||
Type: "replication",
|
||||
Region: params.Region,
|
||||
ReplicationSync: *params.SyncMode == "sync",
|
||||
}
|
||||
if *params.SyncMode == "async" {
|
||||
remoteBucket.BandwidthLimit = params.Bandwidth
|
||||
}
|
||||
if params.HealthCheckPeriod > 0 {
|
||||
remoteBucket.HealthCheckDuration = time.Duration(params.HealthCheckPeriod) * time.Second
|
||||
}
|
||||
bucketARN, err := client.addRemoteBucket(ctx, *params.SourceBucket, remoteBucket)
|
||||
|
||||
return bucketARN, err
|
||||
}
|
||||
|
||||
func addBucketReplicationItem(ctx context.Context, session *models.Principal, minClient minioClient, bucketName, arn, destinationBucket string) error {
|
||||
func addBucketReplicationItem(ctx context.Context, session *models.Principal, minClient minioClient, bucketName, prefix, arn, destinationBucket string, repDelMark, repDels, repMeta bool, tags string) error {
|
||||
// we will tolerate this call failing
|
||||
cfg, err := minClient.getBucketReplication(ctx, bucketName)
|
||||
if err != nil {
|
||||
@@ -274,7 +287,7 @@ func addBucketReplicationItem(ctx context.Context, session *models.Principal, mi
|
||||
}
|
||||
maxPrio++
|
||||
|
||||
s3Client, err := newS3BucketClient(session, bucketName, "")
|
||||
s3Client, err := newS3BucketClient(session, bucketName, prefix)
|
||||
if err != nil {
|
||||
log.Println("error creating S3Client:", err)
|
||||
return err
|
||||
@@ -283,12 +296,32 @@ func addBucketReplicationItem(ctx context.Context, session *models.Principal, mi
|
||||
// defining the client to be used
|
||||
mcClient := mcClient{client: s3Client}
|
||||
|
||||
repDelMarkStatus := "disable"
|
||||
if repDelMark {
|
||||
repDelMarkStatus = "enable"
|
||||
}
|
||||
|
||||
repDelsStatus := "disable"
|
||||
if repDels {
|
||||
repDelsStatus = "enable"
|
||||
}
|
||||
|
||||
repMetaStatus := "disable"
|
||||
if repMeta {
|
||||
repMetaStatus = "enable"
|
||||
}
|
||||
log.Println("repMetaStatus is not yet implemented", repMetaStatus)
|
||||
|
||||
opts := replication.Options{
|
||||
RoleArn: arn,
|
||||
Priority: fmt.Sprintf("%d", maxPrio),
|
||||
RuleStatus: "enable",
|
||||
DestBucket: destinationBucket,
|
||||
Op: replication.AddOption,
|
||||
RoleArn: arn,
|
||||
Priority: fmt.Sprintf("%d", maxPrio),
|
||||
RuleStatus: "enable",
|
||||
DestBucket: destinationBucket,
|
||||
Op: replication.AddOption,
|
||||
TagString: tags,
|
||||
ReplicateDeleteMarkers: repDelMarkStatus,
|
||||
ReplicateDeletes: repDelsStatus,
|
||||
//ReplicaSync: repMetaStatus,
|
||||
}
|
||||
|
||||
err2 := mcClient.setReplication(ctx, &cfg, opts)
|
||||
@@ -318,13 +351,26 @@ func setMultiBucketReplication(ctx context.Context, session *models.Principal, c
|
||||
TargetBucket: &targetBucket,
|
||||
Region: params.Body.Region,
|
||||
TargetURL: params.Body.TargetURL,
|
||||
SyncMode: params.Body.SyncMode,
|
||||
Bandwidth: params.Body.Bandwidth,
|
||||
}
|
||||
|
||||
// We add the remote bucket reference & store the arn or errors returned
|
||||
arn, err := addRemoteBucket(ctx, client, createRemoteBucketParams)
|
||||
|
||||
if err == nil {
|
||||
err = addBucketReplicationItem(ctx, session, minClient, sourceBucket, arn, targetBucket)
|
||||
err = addBucketReplicationItem(
|
||||
ctx,
|
||||
session,
|
||||
minClient,
|
||||
sourceBucket,
|
||||
params.Body.Prefix,
|
||||
arn,
|
||||
targetBucket,
|
||||
params.Body.ReplicateDeleteMarkers,
|
||||
params.Body.ReplicateDeletes,
|
||||
params.Body.ReplicateMetadata,
|
||||
params.Body.Tags)
|
||||
}
|
||||
|
||||
var errorReturn = ""
|
||||
|
||||
@@ -4286,15 +4286,30 @@ func init() {
|
||||
"bucketReplicationRule": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"bandwidth": {
|
||||
"type": "string"
|
||||
},
|
||||
"delete_marker_replication": {
|
||||
"$ref": "#/definitions/bucketReplicationRuleMarker"
|
||||
"type": "boolean"
|
||||
},
|
||||
"deletes_replication": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"destination": {
|
||||
"$ref": "#/definitions/bucketReplicationDestination"
|
||||
},
|
||||
"healthCheckPeriod": {
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata_replication": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"prefix": {
|
||||
"type": "string"
|
||||
},
|
||||
"priority": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
@@ -4305,18 +4320,17 @@ func init() {
|
||||
"Enabled",
|
||||
"Disabled"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"bucketReplicationRuleMarker": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
},
|
||||
"syncMode": {
|
||||
"type": "string",
|
||||
"default": "async",
|
||||
"enum": [
|
||||
"Enabled",
|
||||
"Disabled"
|
||||
"async",
|
||||
"sync"
|
||||
]
|
||||
},
|
||||
"tags": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -4413,6 +4427,14 @@ func init() {
|
||||
"type": "string",
|
||||
"minLength": 3
|
||||
},
|
||||
"bandwidth": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"healthCheckPeriod": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"region": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -4423,6 +4445,14 @@ func init() {
|
||||
"sourceBucket": {
|
||||
"type": "string"
|
||||
},
|
||||
"syncMode": {
|
||||
"type": "string",
|
||||
"default": "async",
|
||||
"enum": [
|
||||
"async",
|
||||
"sync"
|
||||
]
|
||||
},
|
||||
"targetBucket": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -5372,6 +5402,10 @@ func init() {
|
||||
"type": "string",
|
||||
"minLength": 3
|
||||
},
|
||||
"bandwidth": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"bucketsRelation": {
|
||||
"type": "array",
|
||||
"minLength": 1,
|
||||
@@ -5379,13 +5413,40 @@ func init() {
|
||||
"$ref": "#/definitions/multiBucketsRelation"
|
||||
}
|
||||
},
|
||||
"healthCheckPeriod": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"prefix": {
|
||||
"type": "string"
|
||||
},
|
||||
"region": {
|
||||
"type": "string"
|
||||
},
|
||||
"replicateDeleteMarkers": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"replicateDeletes": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"replicateMetadata": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"secretKey": {
|
||||
"type": "string",
|
||||
"minLength": 8
|
||||
},
|
||||
"syncMode": {
|
||||
"type": "string",
|
||||
"default": "async",
|
||||
"enum": [
|
||||
"async",
|
||||
"sync"
|
||||
]
|
||||
},
|
||||
"tags": {
|
||||
"type": "string"
|
||||
},
|
||||
"targetURL": {
|
||||
"type": "string"
|
||||
}
|
||||
@@ -6196,6 +6257,13 @@ func init() {
|
||||
"type": "string",
|
||||
"minLength": 3
|
||||
},
|
||||
"bandwidth": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"healthCheckPeriod": {
|
||||
"type": "integer"
|
||||
},
|
||||
"remoteARN": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -6215,6 +6283,9 @@ func init() {
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"syncMode": {
|
||||
"type": "string"
|
||||
},
|
||||
"targetBucket": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -11983,15 +12054,30 @@ func init() {
|
||||
"bucketReplicationRule": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"bandwidth": {
|
||||
"type": "string"
|
||||
},
|
||||
"delete_marker_replication": {
|
||||
"$ref": "#/definitions/bucketReplicationRuleMarker"
|
||||
"type": "boolean"
|
||||
},
|
||||
"deletes_replication": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"destination": {
|
||||
"$ref": "#/definitions/bucketReplicationDestination"
|
||||
},
|
||||
"healthCheckPeriod": {
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata_replication": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"prefix": {
|
||||
"type": "string"
|
||||
},
|
||||
"priority": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
@@ -12002,18 +12088,17 @@ func init() {
|
||||
"Enabled",
|
||||
"Disabled"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"bucketReplicationRuleMarker": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
},
|
||||
"syncMode": {
|
||||
"type": "string",
|
||||
"default": "async",
|
||||
"enum": [
|
||||
"Enabled",
|
||||
"Disabled"
|
||||
"async",
|
||||
"sync"
|
||||
]
|
||||
},
|
||||
"tags": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -12110,6 +12195,14 @@ func init() {
|
||||
"type": "string",
|
||||
"minLength": 3
|
||||
},
|
||||
"bandwidth": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"healthCheckPeriod": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"region": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -12120,6 +12213,14 @@ func init() {
|
||||
"sourceBucket": {
|
||||
"type": "string"
|
||||
},
|
||||
"syncMode": {
|
||||
"type": "string",
|
||||
"default": "async",
|
||||
"enum": [
|
||||
"async",
|
||||
"sync"
|
||||
]
|
||||
},
|
||||
"targetBucket": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -13057,6 +13158,10 @@ func init() {
|
||||
"type": "string",
|
||||
"minLength": 3
|
||||
},
|
||||
"bandwidth": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"bucketsRelation": {
|
||||
"type": "array",
|
||||
"minLength": 1,
|
||||
@@ -13064,13 +13169,40 @@ func init() {
|
||||
"$ref": "#/definitions/multiBucketsRelation"
|
||||
}
|
||||
},
|
||||
"healthCheckPeriod": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"prefix": {
|
||||
"type": "string"
|
||||
},
|
||||
"region": {
|
||||
"type": "string"
|
||||
},
|
||||
"replicateDeleteMarkers": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"replicateDeletes": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"replicateMetadata": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"secretKey": {
|
||||
"type": "string",
|
||||
"minLength": 8
|
||||
},
|
||||
"syncMode": {
|
||||
"type": "string",
|
||||
"default": "async",
|
||||
"enum": [
|
||||
"async",
|
||||
"sync"
|
||||
]
|
||||
},
|
||||
"tags": {
|
||||
"type": "string"
|
||||
},
|
||||
"targetURL": {
|
||||
"type": "string"
|
||||
}
|
||||
@@ -13746,6 +13878,13 @@ func init() {
|
||||
"type": "string",
|
||||
"minLength": 3
|
||||
},
|
||||
"bandwidth": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"healthCheckPeriod": {
|
||||
"type": "integer"
|
||||
},
|
||||
"remoteARN": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -13765,6 +13904,9 @@ func init() {
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"syncMode": {
|
||||
"type": "string"
|
||||
},
|
||||
"targetBucket": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -212,9 +212,22 @@ func getBucketReplicationdResponse(session *models.Principal, bucketName string)
|
||||
var rules []*models.BucketReplicationRule
|
||||
|
||||
for _, rule := range res.Rules {
|
||||
|
||||
repDelMarkerStatus := false
|
||||
if rule.DeleteMarkerReplication.Status == "enable" {
|
||||
repDelMarkerStatus = true
|
||||
}
|
||||
repDelStatus := false
|
||||
if rule.DeleteReplication.Status == "enable" {
|
||||
repDelMarkerStatus = true
|
||||
}
|
||||
|
||||
rules = append(rules, &models.BucketReplicationRule{
|
||||
DeleteMarkerReplication: &models.BucketReplicationRuleMarker{Status: string(rule.DeleteMarkerReplication.Status)},
|
||||
DeleteMarkerReplication: repDelMarkerStatus,
|
||||
DeletesReplication: repDelStatus,
|
||||
Destination: &models.BucketReplicationDestination{Bucket: rule.Destination.Bucket},
|
||||
Tags: rule.Tags(),
|
||||
Prefix: rule.Prefix(),
|
||||
ID: rule.ID,
|
||||
Priority: int32(rule.Priority),
|
||||
Status: string(rule.Status),
|
||||
|
||||
69
swagger.yml
69
swagger.yml
@@ -3020,14 +3020,6 @@ definitions:
|
||||
$ref: "#/definitions/notificationConfig"
|
||||
ignoreExisting:
|
||||
type: boolean
|
||||
bucketReplicationRuleMarker:
|
||||
type: object
|
||||
properties:
|
||||
status:
|
||||
type: string
|
||||
enum:
|
||||
- Enabled
|
||||
- Disabled
|
||||
bucketReplicationDestination:
|
||||
type: object
|
||||
properties:
|
||||
@@ -3046,8 +3038,26 @@ definitions:
|
||||
priority:
|
||||
type: integer
|
||||
format: int32
|
||||
syncMode:
|
||||
type: string
|
||||
enum:
|
||||
- async
|
||||
- sync
|
||||
default: async
|
||||
bandwidth:
|
||||
type: string
|
||||
healthCheckPeriod:
|
||||
type: integer
|
||||
delete_marker_replication:
|
||||
$ref: "#/definitions/bucketReplicationRuleMarker"
|
||||
type: boolean
|
||||
deletes_replication:
|
||||
type: boolean
|
||||
metadata_replication:
|
||||
type: boolean
|
||||
prefix:
|
||||
type: string
|
||||
tags:
|
||||
type: string
|
||||
destination:
|
||||
$ref: "#/definitions/bucketReplicationDestination"
|
||||
|
||||
@@ -3103,6 +3113,28 @@ definitions:
|
||||
type: string
|
||||
region:
|
||||
type: string
|
||||
syncMode:
|
||||
type: string
|
||||
enum:
|
||||
- async
|
||||
- sync
|
||||
default: async
|
||||
bandwidth:
|
||||
type: integer
|
||||
format: int64
|
||||
healthCheckPeriod:
|
||||
type: integer
|
||||
format: int32
|
||||
prefix:
|
||||
type: string
|
||||
tags:
|
||||
type: string
|
||||
replicateDeleteMarkers:
|
||||
type: boolean
|
||||
replicateDeletes:
|
||||
type: boolean
|
||||
replicateMetadata:
|
||||
type: boolean
|
||||
bucketsRelation:
|
||||
type: array
|
||||
minLength: 1
|
||||
@@ -3511,6 +3543,13 @@ definitions:
|
||||
service:
|
||||
type: string
|
||||
enum: [ replication ]
|
||||
syncMode:
|
||||
type: string
|
||||
bandwidth:
|
||||
type: integer
|
||||
format: int64
|
||||
healthCheckPeriod:
|
||||
type: integer
|
||||
createRemoteBucket:
|
||||
required:
|
||||
- accessKey
|
||||
@@ -3533,6 +3572,18 @@ definitions:
|
||||
type: string
|
||||
region:
|
||||
type: string
|
||||
syncMode:
|
||||
type: string
|
||||
enum:
|
||||
- async
|
||||
- sync
|
||||
default: async
|
||||
bandwidth:
|
||||
type: integer
|
||||
format: int64
|
||||
healthCheckPeriod:
|
||||
type: integer
|
||||
format: int32
|
||||
listRemoteBucketsResponse:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
Reference in New Issue
Block a user