Compare commits
57 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
63350e5492 | ||
|
|
255c128b67 | ||
|
|
06f333395e | ||
|
|
3cd024ea2c | ||
|
|
9c0a407db6 | ||
|
|
dc3c619f3f | ||
|
|
5000aafba6 | ||
|
|
b9f2a39d50 | ||
|
|
df321191f4 | ||
|
|
547eb41e96 | ||
|
|
afbb83e081 | ||
|
|
b599968570 | ||
|
|
24cc60f34e | ||
|
|
f967058409 | ||
|
|
078e09ba76 | ||
|
|
d6f97841d4 | ||
|
|
619ac124b3 | ||
|
|
a2180e123d | ||
|
|
0325bb7e2d | ||
|
|
fce361e5bd | ||
|
|
ed6d6e8b9d | ||
|
|
406709f66b | ||
|
|
3ac45a2211 | ||
|
|
716f886780 | ||
|
|
4ef498f0c3 | ||
|
|
5e764e61ba | ||
|
|
1466632fd6 | ||
|
|
0c43e5c3f4 | ||
|
|
7e9d581277 | ||
|
|
c928972137 | ||
|
|
78884e3806 | ||
|
|
f6ac7e047e | ||
|
|
e1fdf3fb28 | ||
|
|
e4510cbc18 | ||
|
|
2c14142e19 | ||
|
|
1caa3f2ce8 | ||
|
|
6501a4b13f | ||
|
|
2f51621e69 | ||
|
|
7e6e64c729 | ||
|
|
9007c7dd14 | ||
|
|
850fd3e371 | ||
|
|
6d8f1c439e | ||
|
|
7166717688 | ||
|
|
f91346dc5b | ||
|
|
dccdfb5533 | ||
|
|
4f065bdedf | ||
|
|
4a02c5848b | ||
|
|
e16a926ef8 | ||
|
|
78f4978a9a | ||
|
|
42d617caf9 | ||
|
|
28eb8784a9 | ||
|
|
fcf5d5c9f7 | ||
|
|
a42f1ff4ee | ||
|
|
98f897ed5b | ||
|
|
7afd608faa | ||
|
|
8313a62f17 | ||
|
|
459e2bf61c |
6
.github/workflows/go.yml
vendored
@@ -3,10 +3,10 @@ name: Go
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- master
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.13.x, 1.14.x]
|
||||
go-version: [1.15.x]
|
||||
os: [ubuntu-latest]
|
||||
steps:
|
||||
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
|
||||
|
||||
@@ -12,6 +12,10 @@ before:
|
||||
hooks:
|
||||
# you may remove this if you don't use vgo
|
||||
- go mod tidy
|
||||
- docker build -f Dockerfile.assets -t consoleassets .
|
||||
- docker create --name extract consoleassets
|
||||
- docker cp extract:/app/bindata_assetfs.go ./portal-ui/
|
||||
- docker rm extract
|
||||
|
||||
builds:
|
||||
-
|
||||
|
||||
29
Dockerfile
@@ -1,4 +1,25 @@
|
||||
FROM golang:1.13
|
||||
FROM golang:1.15 as binlayer
|
||||
|
||||
RUN go get github.com/go-bindata/go-bindata/... && go get github.com/elazarl/go-bindata-assetfs/...
|
||||
|
||||
FROM node:10 as uilayer
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=binlayer /go/bin/go-bindata-assetfs /bin/
|
||||
COPY --from=binlayer /go/bin/go-bindata /bin/
|
||||
|
||||
COPY ./portal-ui/package.json ./
|
||||
COPY ./portal-ui/yarn.lock ./
|
||||
RUN yarn install
|
||||
|
||||
COPY ./portal-ui .
|
||||
|
||||
RUN yarn install && make build-static
|
||||
|
||||
USER node
|
||||
|
||||
FROM golang:1.15 as golayer
|
||||
|
||||
RUN apt-get update -y && apt-get install -y ca-certificates
|
||||
|
||||
@@ -12,6 +33,8 @@ RUN go mod download
|
||||
ADD . /go/src/github.com/minio/console/
|
||||
WORKDIR /go/src/github.com/minio/console/
|
||||
|
||||
COPY --from=uilayer /app/bindata_assetfs.go /go/src/github.com/minio/console/portal-ui/
|
||||
|
||||
ENV CGO_ENABLED=0
|
||||
|
||||
RUN go build -ldflags "-w -s" -a -o console ./cmd/console
|
||||
@@ -20,7 +43,7 @@ FROM scratch
|
||||
MAINTAINER MinIO Development "dev@min.io"
|
||||
EXPOSE 9090
|
||||
|
||||
COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
||||
COPY --from=0 /go/src/github.com/minio/console/console .
|
||||
COPY --from=golayer /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
||||
COPY --from=golayer /go/src/github.com/minio/console/console .
|
||||
|
||||
ENTRYPOINT ["/console"]
|
||||
|
||||
20
Dockerfile.assets
Normal file
@@ -0,0 +1,20 @@
|
||||
FROM golang:1.15 as binlayer
|
||||
|
||||
RUN go get github.com/go-bindata/go-bindata/... && go get github.com/elazarl/go-bindata-assetfs/...
|
||||
|
||||
FROM node:10 as uilayer
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=binlayer /go/bin/go-bindata-assetfs /bin/
|
||||
COPY --from=binlayer /go/bin/go-bindata /bin/
|
||||
|
||||
COPY ./portal-ui/package.json ./
|
||||
COPY ./portal-ui/yarn.lock ./
|
||||
RUN yarn install
|
||||
|
||||
COPY ./portal-ui .
|
||||
|
||||
RUN yarn install && make build-static
|
||||
|
||||
USER node
|
||||
38
README.md
@@ -101,8 +101,6 @@ Additionally, you can create policies to limit the privileges for `console` user
|
||||
To run the server:
|
||||
|
||||
```
|
||||
export CONSOLE_HMAC_JWT_SECRET=YOURJWTSIGNINGSECRET
|
||||
|
||||
#required to encrypt jwet payload
|
||||
export CONSOLE_PBKDF_PASSPHRASE=SECRET
|
||||
|
||||
@@ -115,11 +113,41 @@ export CONSOLE_MINIO_SERVER=http://localhost:9000
|
||||
./console server
|
||||
```
|
||||
|
||||
## Connect Console to a Minio using TLS and a self-signed certificate
|
||||
## Run Console with TLS enable
|
||||
|
||||
Copy your `public.crt` and `private.key` to `~/.console/certs`, then:
|
||||
|
||||
```bash
|
||||
./console server
|
||||
```
|
||||
|
||||
Additionally, `Console` has support for multiple certificates, clients can request them using `SNI`. It expects the following structure:
|
||||
|
||||
```bash
|
||||
certs/
|
||||
│
|
||||
├─ public.crt
|
||||
├─ private.key
|
||||
│
|
||||
├─ example.com/
|
||||
│ │
|
||||
│ ├─ public.crt
|
||||
│ └─ private.key
|
||||
└─ foobar.org/
|
||||
│
|
||||
├─ public.crt
|
||||
└─ private.key
|
||||
...
|
||||
|
||||
```
|
||||
...
|
||||
export CONSOLE_MINIO_SERVER_TLS_ROOT_CAS=<certificate_file_name>
|
||||
|
||||
Therefore, we read all filenames in the cert directory and check
|
||||
for each directory whether it contains a public.crt and private.key.
|
||||
|
||||
## Connect Console to a Minio using TLS and a self-signed certificate
|
||||
|
||||
Copy the MinIO `ca.crt` under `~/.console/certs/CAs`, then:
|
||||
```
|
||||
export CONSOLE_MINIO_SERVER=https://localhost:9000
|
||||
./console server
|
||||
```
|
||||
|
||||
@@ -76,21 +76,19 @@ func newApp(name string) *cli.App {
|
||||
|
||||
findClosestCommands := func(command string) []string {
|
||||
var closestCommands []string
|
||||
for _, value := range commandsTree.PrefixMatch(command) {
|
||||
closestCommands = append(closestCommands, value.(string))
|
||||
}
|
||||
closestCommands = append(closestCommands, commandsTree.PrefixMatch(command)...)
|
||||
|
||||
sort.Strings(closestCommands)
|
||||
// Suggest other close commands - allow missed, wrongly added and
|
||||
// even transposed characters
|
||||
for _, value := range commandsTree.Walk(commandsTree.Root()) {
|
||||
if sort.SearchStrings(closestCommands, value.(string)) < len(closestCommands) {
|
||||
if sort.SearchStrings(closestCommands, value) < len(closestCommands) {
|
||||
continue
|
||||
}
|
||||
// 2 is arbitrary and represents the max
|
||||
// allowed number of typed errors
|
||||
if words.DamerauLevenshteinDistance(command, value.(string)) < 2 {
|
||||
closestCommands = append(closestCommands, value.(string))
|
||||
if words.DamerauLevenshteinDistance(command, value) < 2 {
|
||||
closestCommands = append(closestCommands, value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,12 +20,16 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/go-openapi/loads"
|
||||
"github.com/jessevdk/go-flags"
|
||||
"github.com/minio/cli"
|
||||
"github.com/minio/console/pkg/certs"
|
||||
"github.com/minio/console/restapi"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
"github.com/minio/minio/cmd/logger"
|
||||
certsx "github.com/minio/minio/pkg/certs"
|
||||
)
|
||||
|
||||
// starts the server
|
||||
@@ -56,14 +60,9 @@ var serverCmd = cli.Command{
|
||||
Usage: "HTTPS server port",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "tls-certificate",
|
||||
Value: "",
|
||||
Usage: "filename of public cert",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "tls-key",
|
||||
Value: "",
|
||||
Usage: "filename of private key",
|
||||
Name: "certs-dir",
|
||||
Value: certs.GlobalCertsCADir.Get(),
|
||||
Usage: "path to certs directory",
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -82,7 +81,9 @@ func startServer(ctx *cli.Context) error {
|
||||
parser := flags.NewParser(server, flags.Default)
|
||||
parser.ShortDescription = "MinIO Console Server"
|
||||
parser.LongDescription = swaggerSpec.Spec().Info.Description
|
||||
|
||||
server.ConfigureFlags()
|
||||
|
||||
for _, optsGroup := range api.CommandLineOptionsGroups {
|
||||
_, err := parser.AddGroup(optsGroup.ShortDescription, optsGroup.LongDescription, optsGroup.Options)
|
||||
if err != nil {
|
||||
@@ -106,12 +107,19 @@ func startServer(ctx *cli.Context) error {
|
||||
restapi.Hostname = ctx.String("host")
|
||||
restapi.Port = fmt.Sprintf("%v", ctx.Int("port"))
|
||||
|
||||
tlsCertificatePath := ctx.String("tls-certificate")
|
||||
tlsCertificateKeyPath := ctx.String("tls-key")
|
||||
// Set all certs and CAs directories.
|
||||
certs.GlobalCertsDir, _ = certs.NewConfigDirFromCtx(ctx, "certs-dir", certs.DefaultCertsDir.Get)
|
||||
certs.GlobalCertsCADir = &certs.ConfigDir{Path: filepath.Join(certs.GlobalCertsDir.Get(), certs.CertsCADir)}
|
||||
logger.FatalIf(certs.MkdirAllIgnorePerm(certs.GlobalCertsCADir.Get()), "Unable to create certs CA directory at %s", certs.GlobalCertsCADir.Get())
|
||||
|
||||
if tlsCertificatePath != "" && tlsCertificateKeyPath != "" {
|
||||
server.TLSCertificate = flags.Filename(tlsCertificatePath)
|
||||
server.TLSCertificateKey = flags.Filename(tlsCertificateKeyPath)
|
||||
// load all CAs from ~/.console/certs/CAs
|
||||
restapi.GlobalRootCAs, err = certsx.GetRootCAs(certs.GlobalCertsCADir.Get())
|
||||
logger.FatalIf(err, "Failed to read root CAs (%v)", err)
|
||||
// load all certs from ~/.console/certs
|
||||
restapi.GlobalPublicCerts, restapi.GlobalTLSCertsManager, err = certs.GetTLSConfig()
|
||||
logger.FatalIf(err, "Unable to load the TLS configuration")
|
||||
|
||||
if len(restapi.GlobalPublicCerts) > 0 && restapi.GlobalRootCAs != nil {
|
||||
// If TLS certificates are provided enforce the HTTPS schema, meaning console will redirect
|
||||
// plain HTTP connections to HTTPS server
|
||||
server.EnabledListeners = []string{"http", "https"}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
`Console` will authenticate against `Kubernetes`using bearer tokens via HTTP `Authorization` header. The user will provide this token once
|
||||
in the login form, Console will validate it against Kubernetes (list apis) and if valid will generate and return a new Console sessions
|
||||
with encrypted claims (the user Service account token will be inside the JWT in the data field)
|
||||
with encrypted claims (the user Service account token will be inside the session encrypted token
|
||||
|
||||
# Kubernetes
|
||||
|
||||
|
||||
15
go.mod
@@ -1,6 +1,6 @@
|
||||
module github.com/minio/console
|
||||
|
||||
go 1.13
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible
|
||||
@@ -16,16 +16,17 @@ require (
|
||||
github.com/jessevdk/go-flags v1.4.0
|
||||
github.com/minio/cli v1.22.0
|
||||
github.com/minio/kes v0.11.0
|
||||
github.com/minio/mc v0.0.0-20200808005614-7e52c104bee1
|
||||
github.com/minio/minio v0.0.0-20200808024306-2a9819aff876
|
||||
github.com/minio/minio-go/v7 v7.0.5-0.20200807085956-d7db33ea7618
|
||||
github.com/minio/operator v0.0.0-20200922064400-af3315add727
|
||||
github.com/minio/mc v0.0.0-20201001165056-7f2df96e4821
|
||||
github.com/minio/minio v0.0.0-20200927172404-27d9bd04e544
|
||||
github.com/minio/minio-go/v7 v7.0.6-0.20200923173112-bc846cb9b089
|
||||
github.com/minio/operator v0.0.0-20201022162018-527e5c32132b
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
|
||||
github.com/secure-io/sio-go v0.3.1
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/unrolled/secure v1.0.7
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
|
||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||
gopkg.in/yaml.v2 v2.3.0
|
||||
k8s.io/api v0.18.6
|
||||
|
||||
85
go.sum
@@ -14,6 +14,7 @@ cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0 h1:EpMNVUorLiZIELdMZbCYX/ByTFCdoYopYAGxaGVz9ms=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
@@ -30,6 +31,7 @@ cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjp
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0 h1:86K1Gel7BQ9/WmNWn7dTKMvTLFzwtBe5FNqYbi9X35g=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
code.gitea.io/sdk/gitea v0.12.0/go.mod h1:z3uwDV/b9Ls47NGukYM9XhnHtqPh/J+t40lsUrR6JDY=
|
||||
contrib.go.opencensus.io/exporter/aws v0.0.0-20181029163544-2befc13012d0/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA=
|
||||
@@ -43,6 +45,7 @@ git.apache.org/thrift.git v0.13.0/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqbl
|
||||
github.com/Azure/azure-amqp-common-go/v2 v2.1.0/go.mod h1:R8rea+gJRuJR6QxTir/XuEd+YuKoUiazDC/N96FiDEU=
|
||||
github.com/Azure/azure-pipeline-go v0.2.1 h1:OLBdZJ3yvOn2MezlWvbrBMTEUQC72zAftRZOMdj5HYo=
|
||||
github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4=
|
||||
github.com/Azure/azure-pipeline-go v0.2.2 h1:6oiIS9yaG6XCCzhgAgKFfIWyo4LLCiDhZot6ltoThhY=
|
||||
github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc=
|
||||
github.com/Azure/azure-sdk-for-go v29.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v30.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
@@ -52,13 +55,17 @@ github.com/Azure/azure-sdk-for-go v42.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9mo
|
||||
github.com/Azure/azure-service-bus-go v0.9.1/go.mod h1:yzBx6/BUGfjfeqbRZny9AQIbIe3AcV9WZbAdpkoXOa0=
|
||||
github.com/Azure/azure-storage-blob-go v0.8.0 h1:53qhf0Oxa0nOjgbDeeYPUeyiNmafAFEY95rZLK0Tj6o=
|
||||
github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0=
|
||||
github.com/Azure/azure-storage-blob-go v0.10.0 h1:evCwGreYo3XLeBV4vSxLbLiYb6e0SzsJiXQVRGsRXxs=
|
||||
github.com/Azure/azure-storage-blob-go v0.10.0/go.mod h1:ep1edmW+kNQx4UfWM9heESNmQdijykocJ0YOxmMX8SE=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-autorest v12.0.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest v14.1.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
|
||||
github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0=
|
||||
github.com/Azure/go-autorest/autorest v0.10.2 h1:NuSF3gXetiHyUbVdneJMEVyPUYAe5wh+aN08JYAf1tI=
|
||||
github.com/Azure/go-autorest/autorest v0.10.2/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.5.0 h1:q2gDruN08/guU9vAjuPWff0+QIrpH6ediguzdAzXAUU=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
|
||||
@@ -67,10 +74,13 @@ github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMl
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.3/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.1 h1:xjPqigMQe2+0DAJ5A6MLUPp5D2r2Io8qHCuCMMI/yJU=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.1/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg=
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM=
|
||||
github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw=
|
||||
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
|
||||
github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
@@ -80,8 +90,10 @@ github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocm
|
||||
github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA=
|
||||
github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8=
|
||||
github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI=
|
||||
github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=
|
||||
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
@@ -145,6 +157,7 @@ github.com/aws/aws-sdk-go v1.20.21/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpi
|
||||
github.com/aws/aws-sdk-go v1.25.11/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.26.3/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.27.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.29.11/go.mod h1:1KvfttTE3SPKMpo8g2c6jL3ZKfXtFvKscTgahTma5Xg=
|
||||
github.com/aws/aws-sdk-go v1.31.6/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
||||
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I=
|
||||
github.com/bcicen/jstream v0.0.0-20190220045926-16c1f8af81c2 h1:M+TYzBcNIRyzPRg66ndEqUMd7oWDmhvdQmaPC6EZNwM=
|
||||
@@ -169,6 +182,7 @@ github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e/go.mod h1:9IOqJGCPMS
|
||||
github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
@@ -520,9 +534,11 @@ github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/wire v0.3.0/go.mod h1:i1DMg/Lu8Sz5yYl25iOdmc5CT5qusaa+zmRWs16741s=
|
||||
github.com/google/wire v0.4.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU=
|
||||
github.com/googleapis/gax-go v2.0.2+incompatible h1:silFMLAnr330+NRuag/VjIGF7TLp/LBrV2CJKFLWEww=
|
||||
github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4 h1:hU4mGcQI4DaAYW+IbTun+2qEZVFxK0ySjQLTbS0VQKc=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.1.0 h1:rVsPeBmXbYv4If/cumu1AzZPwV58q433hvONV1UEZoI=
|
||||
@@ -530,6 +546,7 @@ github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTV
|
||||
github.com/googleapis/gnostic v0.2.2 h1:DcFegQ7+ECdmkJMfVwWlC+89I4esJ7p8nkGt9ainGDk=
|
||||
github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/gookit/color v1.2.4/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg=
|
||||
github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o=
|
||||
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
@@ -541,6 +558,8 @@ github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.7.5-0.20200711200521-98cb6bf42e08 h1:kPna6oIGlRXWmg/jkKfxbpvsl+0DHYnw1qQwN+6+gyA=
|
||||
github.com/gorilla/mux v1.7.5-0.20200711200521-98cb6bf42e08/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/rpc v1.2.0 h1:WvvdC2lNeT1SP32zrIce5l0ECBfbAlmrmSBsuc57wfk=
|
||||
github.com/gorilla/rpc v1.2.0/go.mod h1:V4h9r+4sF5HnzqbwIez0fKSpANP0zlYd3qR7p36jkTQ=
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
@@ -585,6 +604,7 @@ github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es
|
||||
github.com/hashicorp/go-retryablehttp v0.5.4 h1:1BZvpawXoJCWX6pNtow9+rpEj+3itIlutiqnntI6jOE=
|
||||
github.com/hashicorp/go-retryablehttp v0.5.4/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
|
||||
github.com/hashicorp/go-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
|
||||
github.com/hashicorp/go-retryablehttp v0.6.6 h1:HJunrbHTDDbBb/ay4kxa1n+dLmttUlnP3V9oNE4hmsM=
|
||||
github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
|
||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||
github.com/hashicorp/go-rootcerts v1.0.1 h1:DMo4fmknnz0E0evoNYnV48RjWndOsmd6OW+09R3cEP8=
|
||||
@@ -711,6 +731,8 @@ github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.7.0 h1:h93mCPfUSkaul3Ka/VG8uZdmW1uMHDGxzu0NWHuJmHY=
|
||||
github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
|
||||
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
@@ -734,6 +756,8 @@ github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaa
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw=
|
||||
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
||||
github.com/mattn/go-ieproxy v0.0.1 h1:qiyop7gCflfhwCzGyeT0gro3sF9AIg9HU98JORTkqfI=
|
||||
@@ -748,6 +772,8 @@ github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHX
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.2 h1:UnlwIPBGaTZfPQ6T1IGzPI0EkYAQmT9fAEJ/poFC63o=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
|
||||
@@ -765,32 +791,30 @@ github.com/minio/highwayhash v1.0.0 h1:iMSDhgUILCr0TNm8LWlSjF8N0ZIj2qbO8WHp6Q/J2
|
||||
github.com/minio/highwayhash v1.0.0/go.mod h1:xQboMTeM9nY9v/LlAOxFctujiv5+Aq2hR5dxBpaMbdc=
|
||||
github.com/minio/kes v0.11.0 h1:8ma6OCVSxKT50b1uYXLJro3m7PmZtCLxBaTddQexI5k=
|
||||
github.com/minio/kes v0.11.0/go.mod h1:mTF1Bv8YVEtQqF/B7Felp4tLee44Pp+dgI0rhCvgNg8=
|
||||
github.com/minio/mc v0.0.0-20200808005614-7e52c104bee1 h1:OrcFWsUIzKoXeIXVReZ7AryDtbPBLtkjDDOBnuU9RWY=
|
||||
github.com/minio/mc v0.0.0-20200808005614-7e52c104bee1/go.mod h1:OGP9+cwQ174WKwZTgJOIFstVv19CH0wdSDZSG6NyTuE=
|
||||
github.com/minio/mc v0.0.0-20201001165056-7f2df96e4821 h1:+09Ta2rY29df6U4bfSC85t7jxlNuYpUfl7lIVgTiDEA=
|
||||
github.com/minio/mc v0.0.0-20201001165056-7f2df96e4821/go.mod h1:+OeGPfw7qpvO1x2Td65ejwAuFT0Cxzx0GFTJSDlPMZQ=
|
||||
github.com/minio/md5-simd v1.1.0 h1:QPfiOqlZH+Cj9teu0t9b1nTBfPbyTl16Of5MeuShdK4=
|
||||
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
|
||||
github.com/minio/minio v0.0.0-20200723003940-b9be841fd222 h1:+XFGpEsqmA033nDX8LtjyPZy01Shivf6E2OL67WoGiE=
|
||||
github.com/minio/minio v0.0.0-20200723003940-b9be841fd222/go.mod h1:Eu2KC2p+vW03rnYY/6R/D+QduPB7/j4kBaVA/EDLjWM=
|
||||
github.com/minio/minio v0.0.0-20200807001021-adcaa6f9de88 h1:v2mCqNx6N02jcYHWjMPHdTN9+ogxEN9L+cCQJ+8j2AU=
|
||||
github.com/minio/minio v0.0.0-20200807001021-adcaa6f9de88/go.mod h1:r+PkhkMRxudvboO0Wa7F7nMiDfI8Rz1HZSza0uIhtMU=
|
||||
github.com/minio/minio v0.0.0-20200808024306-2a9819aff876 h1:e5114Mb8Evzt1QsA8b6PrXZ1KqBLts0CokpKeU1DV2U=
|
||||
github.com/minio/minio v0.0.0-20200808024306-2a9819aff876/go.mod h1:r+PkhkMRxudvboO0Wa7F7nMiDfI8Rz1HZSza0uIhtMU=
|
||||
github.com/minio/minio v0.0.0-20200927172404-27d9bd04e544 h1:G6M9uXdFShowoLG3rMkdCtHsx37ZYB1vc+7bu22r85I=
|
||||
github.com/minio/minio v0.0.0-20200927172404-27d9bd04e544/go.mod h1:5uolst3SWpgvDNF+KJwfViU+j9WH7dB5i2YCi0nMNVo=
|
||||
github.com/minio/minio-go/v7 v7.0.1/go.mod h1:dJ80Mv2HeGkYLH1sqS/ksz07ON6csH3S6JUMSQ2zAns=
|
||||
github.com/minio/minio-go/v7 v7.0.2 h1:P/7wFd4KrRBHVo7AKdcqO+9ReoS+XpMjfRFoE5quH0E=
|
||||
github.com/minio/minio-go/v7 v7.0.2/go.mod h1:dJ80Mv2HeGkYLH1sqS/ksz07ON6csH3S6JUMSQ2zAns=
|
||||
github.com/minio/minio-go/v7 v7.0.3/go.mod h1:TA0CQCjJZHM5SJj9IjqR0NmpmQJ6bCbXifAJ3mUU6Hw=
|
||||
github.com/minio/minio-go/v7 v7.0.5-0.20200807085956-d7db33ea7618 h1:8iTb0TFs6kDGAUnhI/s2QCZOYcSTtYmY9dF+Cbc0WJo=
|
||||
github.com/minio/minio-go/v7 v7.0.5-0.20200807085956-d7db33ea7618/go.mod h1:CSt2ETZNs+bIIhWTse0mcZKZWMGrFU7Er7RR0TmkDYk=
|
||||
github.com/minio/operator v0.0.0-20200921211523-69f9eef5b7b5 h1:yQ7WHA2wbTTGHz0Z4xXSRxfUTm5fafM0ajvlZlQ2Zl4=
|
||||
github.com/minio/operator v0.0.0-20200921211523-69f9eef5b7b5/go.mod h1:6lavbNo2YuJWeQR5bZYsEWdbpRCO2KrTyfQ0PtC/AN4=
|
||||
github.com/minio/operator v0.0.0-20200922064400-af3315add727 h1:MN8Knn7yxrd76Y3uL38DZh4RhihTZTck5u51NoEar/c=
|
||||
github.com/minio/operator v0.0.0-20200922064400-af3315add727/go.mod h1:6lavbNo2YuJWeQR5bZYsEWdbpRCO2KrTyfQ0PtC/AN4=
|
||||
github.com/minio/minio-go/v7 v7.0.5-0.20200811211821-14ed05478889/go.mod h1:CSt2ETZNs+bIIhWTse0mcZKZWMGrFU7Er7RR0TmkDYk=
|
||||
github.com/minio/minio-go/v7 v7.0.6-0.20200923173112-bc846cb9b089 h1:9DDs/Gc3fNHOQxQmwIFWs7YDLMTBh59r2XQ6RqEUA1I=
|
||||
github.com/minio/minio-go/v7 v7.0.6-0.20200923173112-bc846cb9b089/go.mod h1:CSt2ETZNs+bIIhWTse0mcZKZWMGrFU7Er7RR0TmkDYk=
|
||||
github.com/minio/operator v0.0.0-20201022162018-527e5c32132b h1:ggfD6V3nodTzhHJHCYIT1F897gscrz+hHsan0a2Wtqw=
|
||||
github.com/minio/operator v0.0.0-20201022162018-527e5c32132b/go.mod h1:At+++4/6W5BEXK11tN5DKIvkJKhYBZybbb5zmxb0LQI=
|
||||
github.com/minio/selfupdate v0.3.1 h1:BWEFSNnrZVMUWXbXIgLDNDjbejkmpAmZvy/nCz1HlEs=
|
||||
github.com/minio/selfupdate v0.3.1/go.mod h1:b8ThJzzH7u2MkF6PcIra7KaXO9Khf6alWPvMSyTDCFM=
|
||||
github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU=
|
||||
github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
|
||||
github.com/minio/simdjson-go v0.1.5-0.20200303142138-b17fe061ea37 h1:pDeao6M5AEd8hwTtGmE0pVKomlL56JFRa5SiXDZAuJE=
|
||||
github.com/minio/simdjson-go v0.1.5-0.20200303142138-b17fe061ea37/go.mod h1:oKURrZZEBtqObgJrSjN1Ln2n9MJj2icuBTkeJzZnvSI=
|
||||
github.com/minio/simdjson-go v0.1.5 h1:6T5mHh7r3kUvgwhmFWQAjoPV5Yt5oD/VPjAI9ViH1kM=
|
||||
github.com/minio/simdjson-go v0.1.5/go.mod h1:oKURrZZEBtqObgJrSjN1Ln2n9MJj2icuBTkeJzZnvSI=
|
||||
github.com/minio/sio v0.2.0 h1:NCRCFLx0r5pRbXf65LVNjxbCGZgNQvNFQkgX3XF4BoA=
|
||||
github.com/minio/sio v0.2.0/go.mod h1:nKM5GIWSrqbOZp0uhyj6M1iA0X6xQzSGtYSaTKSCut0=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
@@ -813,6 +837,7 @@ github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
|
||||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/mmcloughlin/avo v0.0.0-20200523190732-4439b6b2c061 h1:UCU8+cLbbvyxi0sQ9fSeoEhZgvrrD9HKMtX6Gmc1vk8=
|
||||
github.com/mmcloughlin/avo v0.0.0-20200523190732-4439b6b2c061/go.mod h1:wqKykBG2QzQDJEzvRkcS8x6MiSJkF52hXZsXcjaB3ls=
|
||||
github.com/mmcloughlin/avo v0.0.0-20200803215136-443f81d77104/go.mod h1:wqKykBG2QzQDJEzvRkcS8x6MiSJkF52hXZsXcjaB3ls=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@@ -857,6 +882,7 @@ github.com/nsqio/go-nsq v1.0.7/go.mod h1:XP5zaUs3pqf+Q71EqUJs3HYfBIqfK6G83WQMdNN
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/olivere/elastic/v7 v7.0.12/go.mod h1:14rWX28Pnh3qCKYRVnSGXWLf9MbLonYS/4FDCY3LAPo=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
@@ -876,6 +902,7 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
|
||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
@@ -988,12 +1015,15 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykE
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8=
|
||||
github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
|
||||
github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w=
|
||||
github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
|
||||
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs=
|
||||
github.com/smartystreets/gunit v1.1.3/go.mod h1:EH5qMBab2UclzXUcpR8b93eHsIlp9u+pDQIRp5DZNzQ=
|
||||
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE=
|
||||
@@ -1059,6 +1089,7 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tommy-muehle/go-mnd v1.1.1/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig=
|
||||
github.com/tommy-muehle/go-mnd v1.3.1-0.20200224220436-e6f9a994e8fa/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig=
|
||||
github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q=
|
||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
@@ -1079,6 +1110,8 @@ github.com/vdemeester/k8s-pkg-credentialprovider v1.17.4/go.mod h1:inCTmtUdr5KJb
|
||||
github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
|
||||
github.com/willf/bitset v1.1.10 h1:NotGKqX0KwQ72NUzqrjZq5ipPNDQex9lo3WpaS8L2sc=
|
||||
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE=
|
||||
github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
|
||||
github.com/willf/bloom v2.0.3+incompatible h1:QDacWdqcAUI1MPOwIQZRy9kOR7yxfyEmxX8Wdm2/JPA=
|
||||
github.com/willf/bloom v2.0.3+incompatible/go.mod h1:MmAltL9pDMNTrvUkxdg0k0q5I0suxmuwp3KbyrZLOZ8=
|
||||
github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
|
||||
@@ -1095,6 +1128,7 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
|
||||
@@ -1114,6 +1148,7 @@ go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
@@ -1158,8 +1193,8 @@ golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 h1:DZhuSZLsGlFL4CmhA8BcRA0mnthyA/nZ00AqCUo7vHg=
|
||||
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de h1:ikNHVSjEfnvz6sxdSPCaPt572qowuyMDMJLLm3Db3ig=
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@@ -1240,6 +1275,9 @@ golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA=
|
||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -1318,8 +1356,8 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200806125547-5acd03effb82 h1:6cBnXxYO+CiRVrChvCosSv7magqTPbyAgz1M8iOv5wM=
|
||||
golang.org/x/sys v0.0.0-20200806125547-5acd03effb82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200915084602-288bc346aa39 h1:356XA7ITklAU2//sYkjFeco+dH1bCRD8XCJ9FIEsvo4=
|
||||
golang.org/x/sys v0.0.0-20200915084602-288bc346aa39/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -1409,14 +1447,18 @@ golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roY
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200502202811-ed308ab3e770/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200724172932-b5fc9d354d99 h1:OHn441rq5CeM5r1xJ0OmY7lfdTvnedi6k+vQiI7G9b8=
|
||||
golang.org/x/tools v0.0.0-20200724172932-b5fc9d354d99/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d h1:szSOL78iTCl0LF1AMjhSWJj8tIM0KixlUUnBtYXsmd8=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200814172026-c4923e618c08 h1:sfBQLM20fzeXhOixVQirwEbuW4PGStP773EXQpsBB6E=
|
||||
golang.org/x/tools v0.0.0-20200814172026-c4923e618c08/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200929223013-bf155c11ec6f h1:7+Nz9MyPqt2qMCTvNiRy1G0zYfkB7UCa+ayT6uVvbyI=
|
||||
golang.org/x/tools v0.0.0-20200929223013-bf155c11ec6f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
|
||||
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
|
||||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
|
||||
@@ -1437,6 +1479,7 @@ google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.25.0 h1:LodzhlzZEUfhXzNUMIfVlf9Gr6Ua5MMtoFWh7+f47qA=
|
||||
google.golang.org/api v0.25.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@@ -1518,6 +1561,8 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8X
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25 h1:Ev7yu1/f6+d+b3pi5vPdRPc6nNtP1umSfcWiEfRqv6I=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
@@ -1547,6 +1592,8 @@ gopkg.in/ldap.v3 v3.0.3/go.mod h1:oxD7NyBuxchC+SgJDE1Q5Od05eGt29SDQVBmV+HYbzw=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/olivere/elastic.v5 v5.0.80 h1:AKjfcq3ZIAAqO4m8h/vJ3GP6nY8n9ft5mgf54fEqC60=
|
||||
gopkg.in/olivere/elastic.v5 v5.0.80/go.mod h1:uhHoB4o3bvX5sorxBU29rPcmBQdV2Qfg0FBrx5D6pV0=
|
||||
gopkg.in/olivere/elastic.v5 v5.0.86 h1:xFy6qRCGAmo5Wjx96srho9BitLhZl2fcnpuidPwduXM=
|
||||
gopkg.in/olivere/elastic.v5 v5.0.86/go.mod h1:M3WNlsF+WhYn7api4D87NIflwTV/c0iVs8cqfWhK+68=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/square/go-jose.v2 v2.3.1 h1:SK5KegNXmKmqE342YYN2qPHEnUYeoMiXXl1poUlI+o4=
|
||||
|
||||
@@ -15,7 +15,7 @@ spec:
|
||||
serviceAccountName: console-sa
|
||||
containers:
|
||||
- name: console
|
||||
image: minio/console:v0.3.26
|
||||
image: minio/console:v0.4.4
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
args:
|
||||
- server
|
||||
|
||||
@@ -15,7 +15,7 @@ spec:
|
||||
serviceAccountName: console-sa
|
||||
containers:
|
||||
- name: console
|
||||
image: minio/console:v0.3.26
|
||||
image: minio/console:v0.4.4
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
env:
|
||||
- name: CONSOLE_OPERATOR_MODE
|
||||
|
||||
63
models/add_bucket_replication.go
Normal file
@@ -0,0 +1,63 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 (
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// AddBucketReplication add bucket replication
|
||||
//
|
||||
// swagger:model addBucketReplication
|
||||
type AddBucketReplication struct {
|
||||
|
||||
// arn
|
||||
Arn string `json:"arn,omitempty"`
|
||||
|
||||
// destination bucket
|
||||
DestinationBucket string `json:"destination_bucket,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this add bucket replication
|
||||
func (m *AddBucketReplication) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *AddBucketReplication) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *AddBucketReplication) UnmarshalBinary(b []byte) error {
|
||||
var res AddBucketReplication
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
63
models/bucket_encryption_info.go
Normal file
@@ -0,0 +1,63 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 (
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// BucketEncryptionInfo bucket encryption info
|
||||
//
|
||||
// swagger:model bucketEncryptionInfo
|
||||
type BucketEncryptionInfo struct {
|
||||
|
||||
// algorithm
|
||||
Algorithm string `json:"algorithm,omitempty"`
|
||||
|
||||
// kms master key ID
|
||||
KmsMasterKeyID string `json:"kmsMasterKeyID,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this bucket encryption info
|
||||
func (m *BucketEncryptionInfo) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *BucketEncryptionInfo) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *BucketEncryptionInfo) UnmarshalBinary(b []byte) error {
|
||||
var res BucketEncryptionInfo
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
89
models/bucket_encryption_request.go
Normal file
@@ -0,0 +1,89 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 (
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// BucketEncryptionRequest bucket encryption request
|
||||
//
|
||||
// swagger:model bucketEncryptionRequest
|
||||
type BucketEncryptionRequest struct {
|
||||
|
||||
// enc type
|
||||
EncType BucketEncryptionType `json:"encType,omitempty"`
|
||||
|
||||
// kms key ID
|
||||
KmsKeyID string `json:"kmsKeyID,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this bucket encryption request
|
||||
func (m *BucketEncryptionRequest) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateEncType(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *BucketEncryptionRequest) validateEncType(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.EncType) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := m.EncType.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("encType")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *BucketEncryptionRequest) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *BucketEncryptionRequest) UnmarshalBinary(b []byte) error {
|
||||
var res BucketEncryptionRequest
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
80
models/bucket_encryption_type.go
Normal file
@@ -0,0 +1,80 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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/validate"
|
||||
)
|
||||
|
||||
// BucketEncryptionType bucket encryption type
|
||||
//
|
||||
// swagger:model bucketEncryptionType
|
||||
type BucketEncryptionType string
|
||||
|
||||
const (
|
||||
|
||||
// BucketEncryptionTypeSseS3 captures enum value "sse-s3"
|
||||
BucketEncryptionTypeSseS3 BucketEncryptionType = "sse-s3"
|
||||
|
||||
// BucketEncryptionTypeSseKms captures enum value "sse-kms"
|
||||
BucketEncryptionTypeSseKms BucketEncryptionType = "sse-kms"
|
||||
)
|
||||
|
||||
// for schema
|
||||
var bucketEncryptionTypeEnum []interface{}
|
||||
|
||||
func init() {
|
||||
var res []BucketEncryptionType
|
||||
if err := json.Unmarshal([]byte(`["sse-s3","sse-kms"]`), &res); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, v := range res {
|
||||
bucketEncryptionTypeEnum = append(bucketEncryptionTypeEnum, v)
|
||||
}
|
||||
}
|
||||
|
||||
func (m BucketEncryptionType) validateBucketEncryptionTypeEnum(path, location string, value BucketEncryptionType) error {
|
||||
if err := validate.EnumCase(path, location, value, bucketEncryptionTypeEnum, true); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate validates this bucket encryption type
|
||||
func (m BucketEncryptionType) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
// value enum
|
||||
if err := m.validateBucketEncryptionTypeEnum("", "body", m); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
99
models/bucket_object.go
Normal file
@@ -0,0 +1,99 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 (
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// BucketObject bucket object
|
||||
//
|
||||
// swagger:model bucketObject
|
||||
type BucketObject struct {
|
||||
|
||||
// content type
|
||||
ContentType string `json:"content_type,omitempty"`
|
||||
|
||||
// expiration
|
||||
Expiration string `json:"expiration,omitempty"`
|
||||
|
||||
// expiration rule id
|
||||
ExpirationRuleID string `json:"expiration_rule_id,omitempty"`
|
||||
|
||||
// is delete marker
|
||||
IsDeleteMarker bool `json:"is_delete_marker,omitempty"`
|
||||
|
||||
// is latest
|
||||
IsLatest bool `json:"is_latest,omitempty"`
|
||||
|
||||
// last modified
|
||||
LastModified string `json:"last_modified,omitempty"`
|
||||
|
||||
// legal hold status
|
||||
LegalHoldStatus string `json:"legal_hold_status,omitempty"`
|
||||
|
||||
// name
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// retention mode
|
||||
RetentionMode string `json:"retention_mode,omitempty"`
|
||||
|
||||
// retention until date
|
||||
RetentionUntilDate string `json:"retention_until_date,omitempty"`
|
||||
|
||||
// size
|
||||
Size int64 `json:"size,omitempty"`
|
||||
|
||||
// tags
|
||||
Tags map[string]string `json:"tags,omitempty"`
|
||||
|
||||
// user tags
|
||||
UserTags map[string]string `json:"user_tags,omitempty"`
|
||||
|
||||
// version id
|
||||
VersionID string `json:"version_id,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this bucket object
|
||||
func (m *BucketObject) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *BucketObject) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *BucketObject) UnmarshalBinary(b []byte) error {
|
||||
var res BucketObject
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
60
models/bucket_replication_destination.go
Normal file
@@ -0,0 +1,60 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 (
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// BucketReplicationDestination bucket replication destination
|
||||
//
|
||||
// swagger:model bucketReplicationDestination
|
||||
type BucketReplicationDestination struct {
|
||||
|
||||
// bucket
|
||||
Bucket string `json:"bucket,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this bucket replication destination
|
||||
func (m *BucketReplicationDestination) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *BucketReplicationDestination) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *BucketReplicationDestination) UnmarshalBinary(b []byte) error {
|
||||
var res BucketReplicationDestination
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
97
models/bucket_replication_response.go
Normal file
@@ -0,0 +1,97 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 (
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// BucketReplicationResponse bucket replication response
|
||||
//
|
||||
// swagger:model bucketReplicationResponse
|
||||
type BucketReplicationResponse struct {
|
||||
|
||||
// rules
|
||||
Rules []*BucketReplicationRule `json:"rules"`
|
||||
}
|
||||
|
||||
// Validate validates this bucket replication response
|
||||
func (m *BucketReplicationResponse) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateRules(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *BucketReplicationResponse) validateRules(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.Rules) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.Rules); i++ {
|
||||
if swag.IsZero(m.Rules[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.Rules[i] != nil {
|
||||
if err := m.Rules[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("rules" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *BucketReplicationResponse) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *BucketReplicationResponse) UnmarshalBinary(b []byte) error {
|
||||
var res BucketReplicationResponse
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
173
models/bucket_replication_rule.go
Normal file
@@ -0,0 +1,173 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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"
|
||||
)
|
||||
|
||||
// BucketReplicationRule bucket replication rule
|
||||
//
|
||||
// swagger:model bucketReplicationRule
|
||||
type BucketReplicationRule struct {
|
||||
|
||||
// delete marker replication
|
||||
DeleteMarkerReplication *BucketReplicationRuleMarker `json:"delete_marker_replication,omitempty"`
|
||||
|
||||
// destination
|
||||
Destination *BucketReplicationDestination `json:"destination,omitempty"`
|
||||
|
||||
// id
|
||||
ID string `json:"id,omitempty"`
|
||||
|
||||
// priority
|
||||
Priority int32 `json:"priority,omitempty"`
|
||||
|
||||
// status
|
||||
// Enum: [Enabled Disabled]
|
||||
Status string `json:"status,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)
|
||||
}
|
||||
|
||||
if err := m.validateStatus(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
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.Destination != nil {
|
||||
if err := m.Destination.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("destination")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var bucketReplicationRuleTypeStatusPropEnum []interface{}
|
||||
|
||||
func init() {
|
||||
var res []string
|
||||
if err := json.Unmarshal([]byte(`["Enabled","Disabled"]`), &res); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, v := range res {
|
||||
bucketReplicationRuleTypeStatusPropEnum = append(bucketReplicationRuleTypeStatusPropEnum, v)
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
// BucketReplicationRuleStatusEnabled captures enum value "Enabled"
|
||||
BucketReplicationRuleStatusEnabled string = "Enabled"
|
||||
|
||||
// BucketReplicationRuleStatusDisabled captures enum value "Disabled"
|
||||
BucketReplicationRuleStatusDisabled string = "Disabled"
|
||||
)
|
||||
|
||||
// prop value enum
|
||||
func (m *BucketReplicationRule) validateStatusEnum(path, location string, value string) error {
|
||||
if err := validate.EnumCase(path, location, value, bucketReplicationRuleTypeStatusPropEnum, true); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *BucketReplicationRule) 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 *BucketReplicationRule) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *BucketReplicationRule) UnmarshalBinary(b []byte) error {
|
||||
var res BucketReplicationRule
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
117
models/bucket_replication_rule_marker.go
Normal file
@@ -0,0 +1,117 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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
|
||||
}
|
||||
60
models/bucket_versioning_response.go
Normal file
@@ -0,0 +1,60 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 (
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// BucketVersioningResponse bucket versioning response
|
||||
//
|
||||
// swagger:model bucketVersioningResponse
|
||||
type BucketVersioningResponse struct {
|
||||
|
||||
// is versioned
|
||||
IsVersioned bool `json:"is_versioned,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this bucket versioning response
|
||||
func (m *BucketVersioningResponse) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *BucketVersioningResponse) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *BucketVersioningResponse) UnmarshalBinary(b []byte) error {
|
||||
var res BucketVersioningResponse
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
162
models/create_remote_bucket.go
Normal file
@@ -0,0 +1,162 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 (
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/validate"
|
||||
)
|
||||
|
||||
// CreateRemoteBucket create remote bucket
|
||||
//
|
||||
// swagger:model createRemoteBucket
|
||||
type CreateRemoteBucket struct {
|
||||
|
||||
// access key
|
||||
// Required: true
|
||||
// Min Length: 3
|
||||
AccessKey *string `json:"accessKey"`
|
||||
|
||||
// region
|
||||
Region string `json:"region,omitempty"`
|
||||
|
||||
// secret key
|
||||
// Required: true
|
||||
// Min Length: 8
|
||||
SecretKey *string `json:"secretKey"`
|
||||
|
||||
// source bucket
|
||||
// Required: true
|
||||
SourceBucket *string `json:"sourceBucket"`
|
||||
|
||||
// target bucket
|
||||
// Required: true
|
||||
TargetBucket *string `json:"targetBucket"`
|
||||
|
||||
// target URL
|
||||
// Required: true
|
||||
TargetURL *string `json:"targetURL"`
|
||||
}
|
||||
|
||||
// Validate validates this create remote bucket
|
||||
func (m *CreateRemoteBucket) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateAccessKey(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateSecretKey(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateSourceBucket(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateTargetBucket(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateTargetURL(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *CreateRemoteBucket) validateAccessKey(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("accessKey", "body", m.AccessKey); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validate.MinLength("accessKey", "body", string(*m.AccessKey), 3); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *CreateRemoteBucket) validateSecretKey(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("secretKey", "body", m.SecretKey); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validate.MinLength("secretKey", "body", string(*m.SecretKey), 8); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *CreateRemoteBucket) validateSourceBucket(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("sourceBucket", "body", m.SourceBucket); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *CreateRemoteBucket) validateTargetBucket(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("targetBucket", "body", m.TargetBucket); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *CreateRemoteBucket) validateTargetURL(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("targetURL", "body", m.TargetURL); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *CreateRemoteBucket) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *CreateRemoteBucket) UnmarshalBinary(b []byte) error {
|
||||
var res CreateRemoteBucket
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -93,9 +93,6 @@ type CreateTenantRequest struct {
|
||||
// secret key
|
||||
SecretKey string `json:"secret_key,omitempty"`
|
||||
|
||||
// service name
|
||||
ServiceName string `json:"service_name,omitempty"`
|
||||
|
||||
// tls
|
||||
TLS *TLSConfiguration `json:"tls,omitempty"`
|
||||
|
||||
|
||||
100
models/list_objects_response.go
Normal file
@@ -0,0 +1,100 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 (
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// ListObjectsResponse list objects response
|
||||
//
|
||||
// swagger:model listObjectsResponse
|
||||
type ListObjectsResponse struct {
|
||||
|
||||
// list of resulting objects
|
||||
Objects []*BucketObject `json:"objects"`
|
||||
|
||||
// number of objects
|
||||
Total int64 `json:"total,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this list objects response
|
||||
func (m *ListObjectsResponse) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateObjects(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ListObjectsResponse) validateObjects(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.Objects) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.Objects); i++ {
|
||||
if swag.IsZero(m.Objects[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.Objects[i] != nil {
|
||||
if err := m.Objects[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("objects" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *ListObjectsResponse) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *ListObjectsResponse) UnmarshalBinary(b []byte) error {
|
||||
var res ListObjectsResponse
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
100
models/list_remote_buckets_response.go
Normal file
@@ -0,0 +1,100 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 (
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// ListRemoteBucketsResponse list remote buckets response
|
||||
//
|
||||
// swagger:model listRemoteBucketsResponse
|
||||
type ListRemoteBucketsResponse struct {
|
||||
|
||||
// list of remote buckets
|
||||
Buckets []*RemoteBucket `json:"buckets"`
|
||||
|
||||
// number of remote buckets accessible to user
|
||||
Total int64 `json:"total,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this list remote buckets response
|
||||
func (m *ListRemoteBucketsResponse) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateBuckets(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ListRemoteBucketsResponse) validateBuckets(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.Buckets) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.Buckets); i++ {
|
||||
if swag.IsZero(m.Buckets[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.Buckets[i] != nil {
|
||||
if err := m.Buckets[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("buckets" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *ListRemoteBucketsResponse) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *ListRemoteBucketsResponse) UnmarshalBinary(b []byte) error {
|
||||
var res ListRemoteBucketsResponse
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -37,6 +37,12 @@ type MakeBucketRequest struct {
|
||||
// name
|
||||
// Required: true
|
||||
Name *string `json:"name"`
|
||||
|
||||
// quota
|
||||
Quota *SetBucketQuota `json:"quota,omitempty"`
|
||||
|
||||
// versioning
|
||||
Versioning bool `json:"versioning,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this make bucket request
|
||||
@@ -47,6 +53,10 @@ func (m *MakeBucketRequest) Validate(formats strfmt.Registry) error {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateQuota(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
@@ -62,6 +72,24 @@ func (m *MakeBucketRequest) validateName(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MakeBucketRequest) validateQuota(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.Quota) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.Quota != nil {
|
||||
if err := m.Quota.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("quota")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *MakeBucketRequest) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 (
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// MetadataConfiguration metadata configuration
|
||||
//
|
||||
// swagger:model metadataConfiguration
|
||||
type MetadataConfiguration struct {
|
||||
|
||||
// console
|
||||
Console *MetadataFields `json:"console,omitempty"`
|
||||
|
||||
// kes
|
||||
Kes *MetadataFields `json:"kes,omitempty"`
|
||||
|
||||
// minio
|
||||
Minio *MetadataFields `json:"minio,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this metadata configuration
|
||||
func (m *MetadataConfiguration) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateConsole(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateKes(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateMinio(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MetadataConfiguration) validateConsole(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.Console) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.Console != nil {
|
||||
if err := m.Console.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("console")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MetadataConfiguration) validateKes(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.Kes) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.Kes != nil {
|
||||
if err := m.Kes.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("kes")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MetadataConfiguration) validateMinio(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.Minio) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.Minio != nil {
|
||||
if err := m.Minio.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("minio")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *MetadataConfiguration) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *MetadataConfiguration) UnmarshalBinary(b []byte) error {
|
||||
var res MetadataConfiguration
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
80
models/object_legal_hold_status.go
Normal file
@@ -0,0 +1,80 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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/validate"
|
||||
)
|
||||
|
||||
// ObjectLegalHoldStatus object legal hold status
|
||||
//
|
||||
// swagger:model objectLegalHoldStatus
|
||||
type ObjectLegalHoldStatus string
|
||||
|
||||
const (
|
||||
|
||||
// ObjectLegalHoldStatusEnabled captures enum value "enabled"
|
||||
ObjectLegalHoldStatusEnabled ObjectLegalHoldStatus = "enabled"
|
||||
|
||||
// ObjectLegalHoldStatusDisabled captures enum value "disabled"
|
||||
ObjectLegalHoldStatusDisabled ObjectLegalHoldStatus = "disabled"
|
||||
)
|
||||
|
||||
// for schema
|
||||
var objectLegalHoldStatusEnum []interface{}
|
||||
|
||||
func init() {
|
||||
var res []ObjectLegalHoldStatus
|
||||
if err := json.Unmarshal([]byte(`["enabled","disabled"]`), &res); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, v := range res {
|
||||
objectLegalHoldStatusEnum = append(objectLegalHoldStatusEnum, v)
|
||||
}
|
||||
}
|
||||
|
||||
func (m ObjectLegalHoldStatus) validateObjectLegalHoldStatusEnum(path, location string, value ObjectLegalHoldStatus) error {
|
||||
if err := validate.EnumCase(path, location, value, objectLegalHoldStatusEnum, true); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate validates this object legal hold status
|
||||
func (m ObjectLegalHoldStatus) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
// value enum
|
||||
if err := m.validateObjectLegalHoldStatusEnum("", "body", m); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
80
models/object_retention_mode.go
Normal file
@@ -0,0 +1,80 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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/validate"
|
||||
)
|
||||
|
||||
// ObjectRetentionMode object retention mode
|
||||
//
|
||||
// swagger:model objectRetentionMode
|
||||
type ObjectRetentionMode string
|
||||
|
||||
const (
|
||||
|
||||
// ObjectRetentionModeGovernance captures enum value "governance"
|
||||
ObjectRetentionModeGovernance ObjectRetentionMode = "governance"
|
||||
|
||||
// ObjectRetentionModeCompliance captures enum value "compliance"
|
||||
ObjectRetentionModeCompliance ObjectRetentionMode = "compliance"
|
||||
)
|
||||
|
||||
// for schema
|
||||
var objectRetentionModeEnum []interface{}
|
||||
|
||||
func init() {
|
||||
var res []ObjectRetentionMode
|
||||
if err := json.Unmarshal([]byte(`["governance","compliance"]`), &res); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, v := range res {
|
||||
objectRetentionModeEnum = append(objectRetentionModeEnum, v)
|
||||
}
|
||||
}
|
||||
|
||||
func (m ObjectRetentionMode) validateObjectRetentionModeEnum(path, location string, value ObjectRetentionMode) error {
|
||||
if err := validate.EnumCase(path, location, value, objectRetentionModeEnum, true); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate validates this object retention mode
|
||||
func (m ObjectRetentionMode) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
// value enum
|
||||
if err := m.validateObjectRetentionModeEnum("", "body", m); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
83
models/put_object_legal_hold_request.go
Normal file
@@ -0,0 +1,83 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 (
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// PutObjectLegalHoldRequest put object legal hold request
|
||||
//
|
||||
// swagger:model putObjectLegalHoldRequest
|
||||
type PutObjectLegalHoldRequest struct {
|
||||
|
||||
// status
|
||||
// Required: true
|
||||
Status ObjectLegalHoldStatus `json:"status"`
|
||||
}
|
||||
|
||||
// Validate validates this put object legal hold request
|
||||
func (m *PutObjectLegalHoldRequest) 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
|
||||
}
|
||||
|
||||
func (m *PutObjectLegalHoldRequest) validateStatus(formats strfmt.Registry) error {
|
||||
|
||||
if err := m.Status.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("status")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *PutObjectLegalHoldRequest) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *PutObjectLegalHoldRequest) UnmarshalBinary(b []byte) error {
|
||||
var res PutObjectLegalHoldRequest
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
104
models/put_object_retention_request.go
Normal file
@@ -0,0 +1,104 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 (
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/validate"
|
||||
)
|
||||
|
||||
// PutObjectRetentionRequest put object retention request
|
||||
//
|
||||
// swagger:model putObjectRetentionRequest
|
||||
type PutObjectRetentionRequest struct {
|
||||
|
||||
// expires
|
||||
// Required: true
|
||||
Expires *string `json:"expires"`
|
||||
|
||||
// governance bypass
|
||||
GovernanceBypass bool `json:"governance_bypass,omitempty"`
|
||||
|
||||
// mode
|
||||
// Required: true
|
||||
Mode ObjectRetentionMode `json:"mode"`
|
||||
}
|
||||
|
||||
// Validate validates this put object retention request
|
||||
func (m *PutObjectRetentionRequest) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateExpires(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateMode(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *PutObjectRetentionRequest) validateExpires(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("expires", "body", m.Expires); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *PutObjectRetentionRequest) validateMode(formats strfmt.Registry) error {
|
||||
|
||||
if err := m.Mode.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("mode")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *PutObjectRetentionRequest) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *PutObjectRetentionRequest) UnmarshalBinary(b []byte) error {
|
||||
var res PutObjectRetentionRequest
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
60
models/put_object_tags_request.go
Normal file
@@ -0,0 +1,60 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 (
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// PutObjectTagsRequest put object tags request
|
||||
//
|
||||
// swagger:model putObjectTagsRequest
|
||||
type PutObjectTagsRequest struct {
|
||||
|
||||
// tags
|
||||
Tags map[string]string `json:"tags,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this put object tags request
|
||||
func (m *PutObjectTagsRequest) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *PutObjectTagsRequest) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *PutObjectTagsRequest) UnmarshalBinary(b []byte) error {
|
||||
var res PutObjectTagsRequest
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
200
models/remote_bucket.go
Normal file
@@ -0,0 +1,200 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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"
|
||||
)
|
||||
|
||||
// RemoteBucket remote bucket
|
||||
//
|
||||
// swagger:model remoteBucket
|
||||
type RemoteBucket struct {
|
||||
|
||||
// access key
|
||||
// Required: true
|
||||
// Min Length: 3
|
||||
AccessKey *string `json:"accessKey"`
|
||||
|
||||
// remote a r n
|
||||
// Required: true
|
||||
RemoteARN *string `json:"remoteARN"`
|
||||
|
||||
// secret key
|
||||
// Min Length: 8
|
||||
SecretKey string `json:"secretKey,omitempty"`
|
||||
|
||||
// service
|
||||
// Enum: [replication]
|
||||
Service string `json:"service,omitempty"`
|
||||
|
||||
// source bucket
|
||||
// Required: true
|
||||
SourceBucket *string `json:"sourceBucket"`
|
||||
|
||||
// status
|
||||
Status string `json:"status,omitempty"`
|
||||
|
||||
// target bucket
|
||||
TargetBucket string `json:"targetBucket,omitempty"`
|
||||
|
||||
// target URL
|
||||
TargetURL string `json:"targetURL,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this remote bucket
|
||||
func (m *RemoteBucket) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateAccessKey(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateRemoteARN(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateSecretKey(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateService(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateSourceBucket(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *RemoteBucket) validateAccessKey(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("accessKey", "body", m.AccessKey); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validate.MinLength("accessKey", "body", string(*m.AccessKey), 3); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *RemoteBucket) validateRemoteARN(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("remoteARN", "body", m.RemoteARN); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *RemoteBucket) validateSecretKey(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.SecretKey) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := validate.MinLength("secretKey", "body", string(m.SecretKey), 8); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var remoteBucketTypeServicePropEnum []interface{}
|
||||
|
||||
func init() {
|
||||
var res []string
|
||||
if err := json.Unmarshal([]byte(`["replication"]`), &res); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, v := range res {
|
||||
remoteBucketTypeServicePropEnum = append(remoteBucketTypeServicePropEnum, v)
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
// RemoteBucketServiceReplication captures enum value "replication"
|
||||
RemoteBucketServiceReplication string = "replication"
|
||||
)
|
||||
|
||||
// prop value enum
|
||||
func (m *RemoteBucket) validateServiceEnum(path, location string, value string) error {
|
||||
if err := validate.EnumCase(path, location, value, remoteBucketTypeServicePropEnum, true); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *RemoteBucket) validateService(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.Service) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
// value enum
|
||||
if err := m.validateServiceEnum("service", "body", m.Service); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *RemoteBucket) validateSourceBucket(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("sourceBucket", "body", m.SourceBucket); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *RemoteBucket) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *RemoteBucket) UnmarshalBinary(b []byte) error {
|
||||
var res RemoteBucket
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
137
models/set_bucket_quota.go
Normal file
@@ -0,0 +1,137 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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"
|
||||
)
|
||||
|
||||
// SetBucketQuota set bucket quota
|
||||
//
|
||||
// swagger:model setBucketQuota
|
||||
type SetBucketQuota struct {
|
||||
|
||||
// amount
|
||||
Amount int64 `json:"amount,omitempty"`
|
||||
|
||||
// enabled
|
||||
// Required: true
|
||||
Enabled *bool `json:"enabled"`
|
||||
|
||||
// quota type
|
||||
// Enum: [fifo hard]
|
||||
QuotaType string `json:"quota_type,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this set bucket quota
|
||||
func (m *SetBucketQuota) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateEnabled(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateQuotaType(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *SetBucketQuota) validateEnabled(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("enabled", "body", m.Enabled); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var setBucketQuotaTypeQuotaTypePropEnum []interface{}
|
||||
|
||||
func init() {
|
||||
var res []string
|
||||
if err := json.Unmarshal([]byte(`["fifo","hard"]`), &res); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, v := range res {
|
||||
setBucketQuotaTypeQuotaTypePropEnum = append(setBucketQuotaTypeQuotaTypePropEnum, v)
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
// SetBucketQuotaQuotaTypeFifo captures enum value "fifo"
|
||||
SetBucketQuotaQuotaTypeFifo string = "fifo"
|
||||
|
||||
// SetBucketQuotaQuotaTypeHard captures enum value "hard"
|
||||
SetBucketQuotaQuotaTypeHard string = "hard"
|
||||
)
|
||||
|
||||
// prop value enum
|
||||
func (m *SetBucketQuota) validateQuotaTypeEnum(path, location string, value string) error {
|
||||
if err := validate.EnumCase(path, location, value, setBucketQuotaTypeQuotaTypePropEnum, true); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *SetBucketQuota) validateQuotaType(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.QuotaType) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
// value enum
|
||||
if err := m.validateQuotaTypeEnum("quota_type", "body", m.QuotaType); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *SetBucketQuota) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *SetBucketQuota) UnmarshalBinary(b []byte) error {
|
||||
var res SetBucketQuota
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
60
models/set_bucket_versioning.go
Normal file
@@ -0,0 +1,60 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 (
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// SetBucketVersioning set bucket versioning
|
||||
//
|
||||
// swagger:model setBucketVersioning
|
||||
type SetBucketVersioning struct {
|
||||
|
||||
// versioning
|
||||
Versioning bool `json:"versioning,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this set bucket versioning
|
||||
func (m *SetBucketVersioning) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *SetBucketVersioning) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *SetBucketVersioning) UnmarshalBinary(b []byte) error {
|
||||
var res SetBucketVersioning
|
||||
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 (
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
@@ -37,7 +39,7 @@ type TLSConfiguration struct {
|
||||
Console *KeyPairConfiguration `json:"console,omitempty"`
|
||||
|
||||
// minio
|
||||
Minio *KeyPairConfiguration `json:"minio,omitempty"`
|
||||
Minio []*KeyPairConfiguration `json:"minio"`
|
||||
}
|
||||
|
||||
// Validate validates this tls configuration
|
||||
@@ -82,13 +84,20 @@ func (m *TLSConfiguration) validateMinio(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.Minio != nil {
|
||||
if err := m.Minio.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("minio")
|
||||
}
|
||||
return err
|
||||
for i := 0; i < len(m.Minio); i++ {
|
||||
if swag.IsZero(m.Minio[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.Minio[i] != nil {
|
||||
if err := m.Minio[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("minio" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
3
package-lock.json
generated
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"lockfileVersion": 1
|
||||
}
|
||||
@@ -22,22 +22,26 @@ import (
|
||||
|
||||
// endpoints definition
|
||||
var (
|
||||
configuration = "/configurations-list"
|
||||
users = "/users"
|
||||
groups = "/groups"
|
||||
iamPolicies = "/policies"
|
||||
dashboard = "/dashboard"
|
||||
profiling = "/profiling"
|
||||
trace = "/trace"
|
||||
logs = "/logs"
|
||||
watch = "/watch"
|
||||
notifications = "/notification-endpoints"
|
||||
buckets = "/buckets"
|
||||
bucketsDetail = "/buckets/:bucketName"
|
||||
serviceAccounts = "/service-accounts"
|
||||
tenants = "/tenants"
|
||||
tenantsDetail = "/namespaces/:tenantNamespace/tenants/:tenantName"
|
||||
heal = "/heal"
|
||||
configuration = "/configurations-list"
|
||||
users = "/users"
|
||||
groups = "/groups"
|
||||
iamPolicies = "/policies"
|
||||
dashboard = "/dashboard"
|
||||
profiling = "/profiling"
|
||||
watch = "/watch"
|
||||
notifications = "/notification-endpoints"
|
||||
buckets = "/buckets"
|
||||
bucketsDetail = "/buckets/:bucketName"
|
||||
serviceAccounts = "/service-accounts"
|
||||
tenants = "/tenants"
|
||||
tenantsDetail = "/namespaces/:tenantNamespace/tenants/:tenantName"
|
||||
heal = "/heal"
|
||||
remoteBuckets = "/remote-buckets"
|
||||
replication = "/replication"
|
||||
objectBrowser = "/object-browser/:bucket/*"
|
||||
objectBrowserBucket = "/object-browser/:bucket"
|
||||
mainObjectBrowser = "/object-browser"
|
||||
license = "/license"
|
||||
)
|
||||
|
||||
type ConfigurationActionSet struct {
|
||||
@@ -55,16 +59,6 @@ var configurationActionSet = ConfigurationActionSet{
|
||||
),
|
||||
}
|
||||
|
||||
// logsActionSet contains the list of admin actions required for this endpoint to work
|
||||
var logsActionSet = ConfigurationActionSet{
|
||||
actionTypes: iampolicy.NewActionSet(
|
||||
iampolicy.AllAdminActions,
|
||||
),
|
||||
actions: iampolicy.NewActionSet(
|
||||
iampolicy.ConsoleLogAdminAction,
|
||||
),
|
||||
}
|
||||
|
||||
// dashboardActionSet contains the list of admin actions required for this endpoint to work
|
||||
var dashboardActionSet = ConfigurationActionSet{
|
||||
actionTypes: iampolicy.NewActionSet(
|
||||
@@ -113,16 +107,6 @@ var profilingActionSet = ConfigurationActionSet{
|
||||
),
|
||||
}
|
||||
|
||||
// traceActionSet contains the list of admin actions required for this endpoint to work
|
||||
var traceActionSet = ConfigurationActionSet{
|
||||
actionTypes: iampolicy.NewActionSet(
|
||||
iampolicy.AllAdminActions,
|
||||
),
|
||||
actions: iampolicy.NewActionSet(
|
||||
iampolicy.TraceAdminAction,
|
||||
),
|
||||
}
|
||||
|
||||
// usersActionSet contains the list of admin actions required for this endpoint to work
|
||||
var usersActionSet = ConfigurationActionSet{
|
||||
actionTypes: iampolicy.NewActionSet(
|
||||
@@ -208,22 +192,56 @@ var healActionSet = ConfigurationActionSet{
|
||||
),
|
||||
}
|
||||
|
||||
var remoteBucketsActionSet = ConfigurationActionSet{
|
||||
actionTypes: iampolicy.NewActionSet(
|
||||
iampolicy.AllAdminActions,
|
||||
),
|
||||
actions: iampolicy.NewActionSet(
|
||||
iampolicy.ConfigUpdateAdminAction,
|
||||
),
|
||||
}
|
||||
|
||||
var replicationActionSet = ConfigurationActionSet{
|
||||
actionTypes: iampolicy.NewActionSet(
|
||||
iampolicy.AllAdminActions,
|
||||
),
|
||||
actions: iampolicy.NewActionSet(
|
||||
iampolicy.ConfigUpdateAdminAction,
|
||||
),
|
||||
}
|
||||
|
||||
// objectBrowserActionSet no actions needed for this module to work
|
||||
var objectBrowserActionSet = ConfigurationActionSet{
|
||||
actionTypes: iampolicy.NewActionSet(),
|
||||
actions: iampolicy.NewActionSet(),
|
||||
}
|
||||
|
||||
// licenseActionSet no actions needed for this module to work
|
||||
var licenseActionSet = ConfigurationActionSet{
|
||||
actionTypes: iampolicy.NewActionSet(),
|
||||
actions: iampolicy.NewActionSet(),
|
||||
}
|
||||
|
||||
// endpointRules contains the mapping between endpoints and ActionSets, additional rules can be added here
|
||||
var endpointRules = map[string]ConfigurationActionSet{
|
||||
configuration: configurationActionSet,
|
||||
users: usersActionSet,
|
||||
groups: groupsActionSet,
|
||||
iamPolicies: iamPoliciesActionSet,
|
||||
dashboard: dashboardActionSet,
|
||||
profiling: profilingActionSet,
|
||||
trace: traceActionSet,
|
||||
logs: logsActionSet,
|
||||
watch: watchActionSet,
|
||||
notifications: notificationsActionSet,
|
||||
buckets: bucketsActionSet,
|
||||
bucketsDetail: bucketsActionSet,
|
||||
serviceAccounts: serviceAccountsActionSet,
|
||||
heal: healActionSet,
|
||||
configuration: configurationActionSet,
|
||||
users: usersActionSet,
|
||||
groups: groupsActionSet,
|
||||
iamPolicies: iamPoliciesActionSet,
|
||||
dashboard: dashboardActionSet,
|
||||
profiling: profilingActionSet,
|
||||
watch: watchActionSet,
|
||||
notifications: notificationsActionSet,
|
||||
buckets: bucketsActionSet,
|
||||
bucketsDetail: bucketsActionSet,
|
||||
serviceAccounts: serviceAccountsActionSet,
|
||||
heal: healActionSet,
|
||||
remoteBuckets: remoteBucketsActionSet,
|
||||
replication: replicationActionSet,
|
||||
objectBrowser: objectBrowserActionSet,
|
||||
mainObjectBrowser: objectBrowserActionSet,
|
||||
objectBrowserBucket: objectBrowserActionSet,
|
||||
license: licenseActionSet,
|
||||
}
|
||||
|
||||
// operatorRules contains the mapping between endpoints and ActionSets for operator only mode
|
||||
|
||||
@@ -50,7 +50,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
|
||||
args: args{
|
||||
[]string{"admin:ServerInfo"},
|
||||
},
|
||||
want: 2,
|
||||
want: 6,
|
||||
},
|
||||
{
|
||||
name: "policies endpoint",
|
||||
@@ -63,7 +63,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
|
||||
"admin:ListUserPolicies",
|
||||
},
|
||||
},
|
||||
want: 2,
|
||||
want: 6,
|
||||
},
|
||||
{
|
||||
name: "all admin endpoints",
|
||||
@@ -72,7 +72,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
|
||||
"admin:*",
|
||||
},
|
||||
},
|
||||
want: 11,
|
||||
want: 15,
|
||||
},
|
||||
{
|
||||
name: "all s3 endpoints",
|
||||
@@ -81,7 +81,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
|
||||
"s3:*",
|
||||
},
|
||||
},
|
||||
want: 4,
|
||||
want: 8,
|
||||
},
|
||||
{
|
||||
name: "all admin and s3 endpoints",
|
||||
@@ -91,7 +91,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
|
||||
"s3:*",
|
||||
},
|
||||
},
|
||||
want: 14,
|
||||
want: 18,
|
||||
},
|
||||
{
|
||||
name: "no endpoints",
|
||||
|
||||
@@ -23,10 +23,9 @@ import (
|
||||
"github.com/minio/minio/pkg/env"
|
||||
)
|
||||
|
||||
// ConsoleSTSAndJWTDurationSeconds returns the default session duration for the STS requested tokens and the generated JWTs.
|
||||
// Ideally both values should match so jwt and Minio sts sessions expires at the same time.
|
||||
func GetConsoleSTSAndJWTDurationInSeconds() int {
|
||||
duration, err := strconv.Atoi(env.Get(ConsoleSTSAndJWTDurationSeconds, "3600"))
|
||||
// ConsoleSTSDurationSeconds returns the default session duration for the STS requested tokens.
|
||||
func GetConsoleSTSDurationInSeconds() int {
|
||||
duration, err := strconv.Atoi(env.Get(ConsoleSTSDurationSeconds, "3600"))
|
||||
if err != nil {
|
||||
duration = 3600
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
package token
|
||||
|
||||
const (
|
||||
ConsoleSTSAndJWTDurationSeconds = "CONSOLE_STS_AND_JWT_DURATION_SECONDS"
|
||||
ConsolePBKDFPassphrase = "CONSOLE_PBKDF_PASSPHRASE"
|
||||
ConsolePBKDFSalt = "CONSOLE_PBKDF_SALT"
|
||||
ConsoleSTSDurationSeconds = "CONSOLE_STS_DURATION_SECONDS"
|
||||
ConsolePBKDFPassphrase = "CONSOLE_PBKDF_PASSPHRASE"
|
||||
ConsolePBKDFSalt = "CONSOLE_PBKDF_SALT"
|
||||
)
|
||||
|
||||
@@ -60,17 +60,17 @@ func TestJWTAuthenticate(t *testing.T) {
|
||||
funcAssert.Equal(claims.SecretAccessKey, creds.SecretAccessKey)
|
||||
funcAssert.Equal(claims.SessionToken, creds.SessionToken)
|
||||
}
|
||||
// Test-2 : SessionTokenAuthenticate() return an error because of a tampered jwt
|
||||
// Test-2 : SessionTokenAuthenticate() return an error because of a tampered token
|
||||
if _, err := SessionTokenAuthenticate(badToken); err != nil {
|
||||
funcAssert.Equal("session token internal data is malformed", err.Error())
|
||||
}
|
||||
// Test-3 : SessionTokenAuthenticate() return an error because of an empty jwt
|
||||
// Test-3 : SessionTokenAuthenticate() return an error because of an empty token
|
||||
if _, err := SessionTokenAuthenticate(""); err != nil {
|
||||
funcAssert.Equal("session token missing", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsJWTValid(t *testing.T) {
|
||||
func TestSessionTokenValid(t *testing.T) {
|
||||
funcAssert := assert.New(t)
|
||||
// Test-1 : SessionTokenAuthenticate() provided token is valid
|
||||
funcAssert.Equal(true, IsSessionTokenValid(goodToken))
|
||||
|
||||
222
pkg/certs/certs.go
Normal file
@@ -0,0 +1,222 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 certs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/minio/cli"
|
||||
"github.com/minio/minio/cmd/config"
|
||||
"github.com/minio/minio/cmd/logger"
|
||||
"github.com/minio/minio/pkg/certs"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
)
|
||||
|
||||
type GetCertificateFunc = certs.GetCertificateFunc
|
||||
|
||||
// ConfigDir - points to a user set directory.
|
||||
type ConfigDir struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
// Get - returns current directory.
|
||||
func (dir *ConfigDir) Get() string {
|
||||
return dir.Path
|
||||
}
|
||||
|
||||
func getDefaultConfigDir() string {
|
||||
homeDir, err := homedir.Dir()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return filepath.Join(homeDir, DefaultConsoleConfigDir)
|
||||
}
|
||||
|
||||
func getDefaultCertsDir() string {
|
||||
return filepath.Join(getDefaultConfigDir(), CertsDir)
|
||||
}
|
||||
|
||||
func getDefaultCertsCADir() string {
|
||||
return filepath.Join(getDefaultCertsDir(), CertsCADir)
|
||||
}
|
||||
|
||||
// isFile - returns whether given Path is a file or not.
|
||||
func isFile(path string) bool {
|
||||
if fi, err := os.Stat(path); err == nil {
|
||||
return fi.Mode().IsRegular()
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
var (
|
||||
// DefaultCertsDir certs directory.
|
||||
DefaultCertsDir = &ConfigDir{Path: getDefaultCertsDir()}
|
||||
// DefaultCertsCADir CA directory.
|
||||
DefaultCertsCADir = &ConfigDir{Path: getDefaultCertsCADir()}
|
||||
// GlobalCertsDir points to current certs directory set by user with --certs-dir
|
||||
GlobalCertsDir = DefaultCertsDir
|
||||
// GlobalCertsCADir points to relative Path to certs directory and is <value-of-certs-dir>/CAs
|
||||
GlobalCertsCADir = DefaultCertsCADir
|
||||
)
|
||||
|
||||
// MkdirAllIgnorePerm attempts to create all directories, ignores any permission denied errors.
|
||||
func MkdirAllIgnorePerm(path string) error {
|
||||
err := os.MkdirAll(path, 0700)
|
||||
if err != nil {
|
||||
// It is possible in kubernetes like deployments this directory
|
||||
// is already mounted and is not writable, ignore any write errors.
|
||||
if os.IsPermission(err) {
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func NewConfigDirFromCtx(ctx *cli.Context, option string, getDefaultDir func() string) (*ConfigDir, bool) {
|
||||
var dir string
|
||||
var dirSet bool
|
||||
|
||||
switch {
|
||||
case ctx.IsSet(option):
|
||||
dir = ctx.String(option)
|
||||
dirSet = true
|
||||
case ctx.GlobalIsSet(option):
|
||||
dir = ctx.GlobalString(option)
|
||||
dirSet = true
|
||||
// cli package does not expose parent's option option. Below code is workaround.
|
||||
if dir == "" || dir == getDefaultDir() {
|
||||
dirSet = false // Unset to false since GlobalIsSet() true is a false positive.
|
||||
if ctx.Parent().GlobalIsSet(option) {
|
||||
dir = ctx.Parent().GlobalString(option)
|
||||
dirSet = true
|
||||
}
|
||||
}
|
||||
default:
|
||||
// Neither local nor global option is provided. In this case, try to use
|
||||
// default directory.
|
||||
dir = getDefaultDir()
|
||||
if dir == "" {
|
||||
logger.FatalIf(errors.New("invalid arguments specified"), "%s option must be provided", option)
|
||||
}
|
||||
}
|
||||
|
||||
if dir == "" {
|
||||
logger.FatalIf(errors.New("empty directory"), "%s directory cannot be empty", option)
|
||||
}
|
||||
|
||||
// Disallow relative paths, figure out absolute paths.
|
||||
dirAbs, err := filepath.Abs(dir)
|
||||
logger.FatalIf(err, "Unable to fetch absolute path for %s=%s", option, dir)
|
||||
logger.FatalIf(MkdirAllIgnorePerm(dirAbs), "Unable to create directory specified %s=%s", option, dir)
|
||||
|
||||
return &ConfigDir{Path: dirAbs}, dirSet
|
||||
}
|
||||
|
||||
func getPublicCertFile() string {
|
||||
return filepath.Join(GlobalCertsDir.Get(), PublicCertFile)
|
||||
}
|
||||
|
||||
func getPrivateKeyFile() string {
|
||||
return filepath.Join(GlobalCertsDir.Get(), PrivateKeyFile)
|
||||
}
|
||||
|
||||
func GetTLSConfig() (x509Certs []*x509.Certificate, manager *certs.Manager, err error) {
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
if !(isFile(getPublicCertFile()) && isFile(getPrivateKeyFile())) {
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
if x509Certs, err = config.ParsePublicCertFile(getPublicCertFile()); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
manager, err = certs.NewManager(ctx, getPublicCertFile(), getPrivateKeyFile(), config.LoadX509KeyPair)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
//Console has support for multiple certificates. It expects the following structure:
|
||||
// certs/
|
||||
// │
|
||||
// ├─ public.crt
|
||||
// ├─ private.key
|
||||
// │
|
||||
// ├─ example.com/
|
||||
// │ │
|
||||
// │ ├─ public.crt
|
||||
// │ └─ private.key
|
||||
// └─ foobar.org/
|
||||
// │
|
||||
// ├─ public.crt
|
||||
// └─ private.key
|
||||
// ...
|
||||
//
|
||||
//Therefore, we read all filenames in the cert directory and check
|
||||
//for each directory whether it contains a public.crt and private.key.
|
||||
// If so, we try to add it to certificate manager.
|
||||
root, err := os.Open(GlobalCertsDir.Get())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer root.Close()
|
||||
|
||||
files, err := root.Readdir(-1)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
for _, file := range files {
|
||||
// Ignore all
|
||||
// - regular files
|
||||
// - "CAs" directory
|
||||
// - any directory which starts with ".."
|
||||
if file.Mode().IsRegular() || file.Name() == "CAs" || strings.HasPrefix(file.Name(), "..") {
|
||||
continue
|
||||
}
|
||||
if file.Mode()&os.ModeSymlink == os.ModeSymlink {
|
||||
file, err = os.Stat(filepath.Join(root.Name(), file.Name()))
|
||||
if err != nil {
|
||||
// not accessible ignore
|
||||
continue
|
||||
}
|
||||
if !file.IsDir() {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
certFile = filepath.Join(root.Name(), file.Name(), PublicCertFile)
|
||||
keyFile = filepath.Join(root.Name(), file.Name(), PrivateKeyFile)
|
||||
)
|
||||
if !isFile(certFile) || !isFile(keyFile) {
|
||||
continue
|
||||
}
|
||||
if err = manager.AddCertificate(certFile, keyFile); err != nil {
|
||||
err = fmt.Errorf("unable to load TLS certificate '%s,%s': %w", certFile, keyFile, err)
|
||||
logger.LogIf(ctx, err, logger.Application)
|
||||
}
|
||||
}
|
||||
return x509Certs, manager, nil
|
||||
}
|
||||
34
pkg/certs/const.go
Normal file
@@ -0,0 +1,34 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 certs
|
||||
|
||||
const (
|
||||
// Default minio configuration directory where below configuration files/directories are stored.
|
||||
DefaultConsoleConfigDir = ".console"
|
||||
|
||||
// Directory contains below files/directories for HTTPS configuration.
|
||||
CertsDir = "certs"
|
||||
|
||||
// Directory contains all CA certificates other than system defaults for HTTPS.
|
||||
CertsCADir = "CAs"
|
||||
|
||||
// Public certificate file for HTTPS.
|
||||
PublicCertFile = "public.crt"
|
||||
|
||||
// Private key file for HTTPS.
|
||||
PrivateKeyFile = "private.key"
|
||||
)
|
||||
15
policies/mcsTestUserAddOnly.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "consoleTestUserAddOnly",
|
||||
"Statement": [
|
||||
{
|
||||
"Action": [
|
||||
"admin:CreateUser"
|
||||
],
|
||||
"Effect": "Allow",
|
||||
"Resource": [
|
||||
"arn:aws:s3:::*"
|
||||
]
|
||||
}
|
||||
],
|
||||
"version": "2012-10-17"
|
||||
}
|
||||
10
portal-ui/config-overrides.js
Normal file
@@ -0,0 +1,10 @@
|
||||
const rewireReactHotLoader = require('react-app-rewire-hot-loader');
|
||||
|
||||
/* config-overrides.js */
|
||||
module.exports = function override(config, env) {
|
||||
if (env === 'development') {
|
||||
config.resolve.alias['react-dom'] = '@hot-loader/react-dom';
|
||||
}
|
||||
config = rewireReactHotLoader(config, env);
|
||||
return config;
|
||||
};
|
||||
@@ -5,6 +5,7 @@
|
||||
"dependencies": {
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.7.4",
|
||||
"@babel/plugin-transform-react-jsx-development": "^7.9.0",
|
||||
"@hot-loader/react-dom": "^16.9.0",
|
||||
"@material-ui/core": "^4.9.12",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@types/history": "^4.7.3",
|
||||
@@ -27,25 +28,29 @@
|
||||
"local-storage-fallback": "^4.1.1",
|
||||
"lodash": "^4.17.19",
|
||||
"moment": "^2.24.0",
|
||||
"npm": "^6.14.4",
|
||||
"react": "^16.13.1",
|
||||
"react-app-rewire-hot-loader": "^2.0.1",
|
||||
"react-app-rewired": "^2.1.6",
|
||||
"react-async-hook": "^3.6.1",
|
||||
"react-chartjs-2": "^2.9.0",
|
||||
"react-codemirror2": "^7.1.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"react-hot-loader": "^4.13.0",
|
||||
"react-moment": "^0.9.7",
|
||||
"react-redux": "^7.1.3",
|
||||
"react-router-dom": "^5.1.2",
|
||||
"react-scripts": "3.4.1",
|
||||
"react-scripts": "3.4.4",
|
||||
"recharts": "^1.8.5",
|
||||
"redux": "^4.0.4",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"superagent": "^5.1.0",
|
||||
"typeface-roboto": "^0.0.75",
|
||||
"typescript": "3.6.4",
|
||||
"use-debounce": "^5.0.1",
|
||||
"websocket": "^1.0.31"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "PORT=5000 react-scripts start",
|
||||
"start": "PORT=5000 react-app-rewired start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
|
||||
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 7.8 KiB |
67
portal-ui/public/images/BG_IllustrationDarker.svg
Normal file
@@ -0,0 +1,67 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 368.999 192.934">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1{opacity:0.35;}.cls-12,.cls-15,.cls-16,.cls-17,.cls-2,.cls-5,.cls-6,.cls-7,.cls-8{opacity:0.5;}.cls-10,.cls-11,.cls-12,.cls-13,.cls-14,.cls-15,.cls-16,.cls-17,.cls-3,.cls-4,.cls-5,.cls-6,.cls-7,.cls-9{fill:none;stroke:#707070;stroke-miterlimit:10;}.cls-4{stroke-width:1px;}.cls-10,.cls-11,.cls-5,.cls-9{stroke-width:1.2px;}.cls-5{stroke-dasharray:2.619
|
||||
2.182;}.cls-12,.cls-15,.cls-16,.cls-17,.cls-5,.cls-6,.cls-7,.cls-8{isolation:isolate;}.cls-6{stroke-width:1.6px;stroke-dasharray:2.144
|
||||
1.786;}.cls-7{stroke-width:1.6px;stroke-dasharray:2.23 1.858;}.cls-10{stroke-dasharray:2.646
|
||||
2.204;}.cls-11{stroke-dasharray:2.585 2.154;}.cls-12{stroke-width:1.8px;stroke-dasharray:2.484
|
||||
2.07;}.cls-13{stroke-dasharray:2.984 2.487;}.cls-14{stroke-dasharray:2.773
|
||||
2.311;}.cls-16{stroke-width:1.8px;}.cls-17{stroke-width:1.8px;}
|
||||
</style>
|
||||
</defs>
|
||||
<title>BG_Illustration</title>
|
||||
<g id="Layer_2" data-name="Layer 2">
|
||||
<g id="Layer_1-2" data-name="Layer 1">
|
||||
<g id="BG_Illustration" data-name="BG Illustration" class="cls-1">
|
||||
<g id="Group_118" data-name="Group 118" class="cls-2">
|
||||
<path id="Path_56" data-name="Path 56" class="cls-3"
|
||||
d="M211.5,140.678l-52.726,29.078L79.687,126.139V29.652L132.411.571,211.5,44.188Z"/>
|
||||
<path id="Path_58" data-name="Path 58" class="cls-3"
|
||||
d="M158.776,169.756V73.271L211.5,44.193,158.776,73.271,79.688,29.654"/>
|
||||
<path id="Path_59" data-name="Path 59" class="cls-4" d="M84.681,41l69.1,38.11v79.3l-69.1-38.11Z"/>
|
||||
<line id="Line_37" data-name="Line 37" class="cls-4" x1="106.25" y1="52.782" x2="106.25"
|
||||
y2="132.086"/>
|
||||
<line id="Line_38" data-name="Line 38" class="cls-4" x1="153.783" y1="92.327" x2="106.25"
|
||||
y2="65.999"/>
|
||||
<line id="Line_39" data-name="Line 39" class="cls-4" x1="153.783" y1="105.545" x2="106.25"
|
||||
y2="79.217"/>
|
||||
<line id="Line_40" data-name="Line 40" class="cls-4" x1="153.783" y1="118.762" x2="106.25"
|
||||
y2="92.434"/>
|
||||
<line id="Line_41" data-name="Line 41" class="cls-4" x1="153.783" y1="131.979" x2="106.25"
|
||||
y2="105.651"/>
|
||||
<line id="Line_42" data-name="Line 42" class="cls-4" x1="153.783" y1="145.197" x2="106.25"
|
||||
y2="118.869"/>
|
||||
<path id="Path_60" data-name="Path 60" class="cls-4"
|
||||
d="M166.723,151.031l38.8-22.487V62.916L166.723,85.4Z"/>
|
||||
</g>
|
||||
<path id="Path_62" data-name="Path 62" class="cls-5" d="M117.106,148.062l-76.18,43.33"/>
|
||||
<path id="Path_63" data-name="Path 63" class="cls-6" d="M271.394,167.271l-44.483,25.3"/>
|
||||
<path id="Path_64" data-name="Path 64" class="cls-7" d="M190.722,155.708l61.951,36.031"/>
|
||||
<path id="Path_65" data-name="Path 65" class="cls-5" d="M237.7,36.385l28.182,17.229"/>
|
||||
<g id="Path_66" data-name="Path 66" class="cls-8">
|
||||
<line class="cls-9" x1="362.563" y1="69.327" x2="361.42" y2="68.688"/>
|
||||
<line class="cls-10" x1="359.496" y1="67.613" x2="305.418" y2="37.39"/>
|
||||
<polyline class="cls-9" points="304.456 36.852 303.313 36.213 302.158 36.83"/>
|
||||
<line class="cls-11" x1="300.258" y1="37.844" x2="213.418" y2="84.213"/>
|
||||
<line class="cls-9" x1="212.468" y1="84.72" x2="211.313" y2="85.337"/>
|
||||
</g>
|
||||
<path id="Path_67" data-name="Path 67" class="cls-12"
|
||||
d="M79.648,192.571,31.786,166.344h-.868l-23.579,14.2"/>
|
||||
<g id="Path_68" data-name="Path 68" class="cls-8">
|
||||
<line class="cls-3" x1="22.871" y1="84.641" x2="24.156" y2="83.867"/>
|
||||
<line class="cls-13" x1="26.286" y1="82.584" x2="48.654" y2="69.113"/>
|
||||
<polyline class="cls-3" points="49.719 68.471 51.004 67.698 52.307 68.441"/>
|
||||
<line class="cls-14" x1="54.315" y1="69.585" x2="75.395" y2="81.606"/>
|
||||
<line class="cls-3" x1="76.399" y1="82.178" x2="77.702" y2="82.921"/>
|
||||
</g>
|
||||
<circle id="Ellipse_11" data-name="Ellipse 11" class="cls-15" cx="4.092" cy="183.59" r="3.592"/>
|
||||
<circle id="Ellipse_12" data-name="Ellipse 12" class="cls-15" cx="274.986" cy="165.477" r="3.592"/>
|
||||
<ellipse id="Ellipse_13" data-name="Ellipse 13" class="cls-16" cx="364.957" cy="71.922" rx="3.592"
|
||||
ry="2.904"/>
|
||||
<circle id="Ellipse_14" data-name="Ellipse 14" class="cls-15" cx="19.279" cy="87.681" r="3.592"/>
|
||||
<ellipse id="Ellipse_15" data-name="Ellipse 15" class="cls-17" cx="234.106" cy="32.58" rx="3.592"
|
||||
ry="2.649"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.1 KiB |
6
portal-ui/public/images/ob_bucket_clear.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="11.174" height="11" viewBox="0 0 11.174 11">
|
||||
<defs>
|
||||
<style>.a{fill:none;stroke:#081c42;stroke-linecap:round;}</style>
|
||||
</defs>
|
||||
<path class="a" d="M8.392,10H1.608L0,0H10Z" transform="translate(0.587 0.5)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 279 B |
6
portal-ui/public/images/ob_bucket_filled.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="11.174" height="11" viewBox="0 0 11.174 11">
|
||||
<defs>
|
||||
<style>.a{fill:#081c42;stroke:#081c42;stroke-linecap:round;}</style>
|
||||
</defs>
|
||||
<path class="a" d="M8.392,10H1.608L0,0H10Z" transform="translate(0.587 0.5)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 282 B |
10
portal-ui/public/images/ob_file_clear.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="11.442" height="15.302" viewBox="0 0 11.442 15.302">
|
||||
<defs>
|
||||
<style>.a,.b{fill:none;stroke:#081c42;}.b{stroke-linejoin:round;}</style>
|
||||
</defs>
|
||||
<g transform="translate(0.5 0.5)">
|
||||
<path class="a" d="M-12060-11667.842v14.261h10.442v-10.591l-3.671-3.67Z"
|
||||
transform="translate(12059.999 11667.883)"/>
|
||||
<path class="b" d="M-12051.353-11664.255v-3.639l3.528,3.639Z" transform="translate(12058.188 11667.894)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 515 B |
10
portal-ui/public/images/ob_file_filled.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="11.442" height="15.302" viewBox="0 0 11.442 15.302">
|
||||
<defs>
|
||||
<style>.a,.b{fill:#081c42;stroke:#081c42;}.b{stroke-linejoin:round;fill:#fff}</style>
|
||||
</defs>
|
||||
<g transform="translate(0.5 0.5)">
|
||||
<path class="a" d="M-12060-11667.842v14.261h10.442v-10.591l-3.671-3.67Z"
|
||||
transform="translate(12059.999 11667.883)"/>
|
||||
<path class="b" d="M-12051.353-11664.255v-3.639l3.528,3.639Z" transform="translate(12058.188 11667.894)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 527 B |
10
portal-ui/public/images/ob_folder_clear.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="15.999" height="13.999" viewBox="0 0 15.999 13.999">
|
||||
<defs>
|
||||
<style>.a{fill:none;stroke-linecap:square;}.b,.c{stroke:none;}.c{fill:#081c42;}</style>
|
||||
</defs>
|
||||
<g class="a" transform="translate(-0.001 0.001)">
|
||||
<path class="b" d="M0,14V0H8.572V2.411H16V14Z"/>
|
||||
<path class="c"
|
||||
d="M 15.00020027160645 12.99860000610352 L 15.00020027160645 3.411099910736084 L 8.571599960327148 3.411099910736084 L 7.571600437164307 3.411099910736084 L 7.571600437164307 2.411099910736084 L 7.571600437164307 0.9990998506546021 L 1.000900268554688 0.9990998506546021 L 1.000900268554688 2.411099910736084 L 1.000900268554688 12.99860000610352 L 15.00020027160645 12.99860000610352 M 16.00020027160645 13.99860000610352 L 0.0009002700680866838 13.99860000610352 L 0.0009002700680866838 2.411099910736084 L 0.0009002700680866838 -0.0009001312428154051 L 8.571599960327148 -0.0009001312428154051 L 8.571599960327148 2.411099910736084 L 16.00020027160645 2.411099910736084 L 16.00020027160645 13.99860000610352 Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
10
portal-ui/public/images/ob_folder_filled.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="15.999" height="13.999" viewBox="0 0 15.999 13.999">
|
||||
<defs>
|
||||
<style>.a{fill:none;stroke-linecap:square;}.b,.c{stroke:none;fill:#081c42}.c{fill:#081c42;}</style>
|
||||
</defs>
|
||||
<g class="a" transform="translate(-0.001 0.001)">
|
||||
<path class="b" d="M0,14V0H8.572V2.411H16V14Z"/>
|
||||
<path class="c"
|
||||
d="M 15.00020027160645 12.99860000610352 L 15.00020027160645 3.411099910736084 L 8.571599960327148 3.411099910736084 L 7.571600437164307 3.411099910736084 L 7.571600437164307 2.411099910736084 L 7.571600437164307 0.9990998506546021 L 1.000900268554688 0.9990998506546021 L 1.000900268554688 2.411099910736084 L 1.000900268554688 12.99860000610352 L 15.00020027160645 12.99860000610352 M 16.00020027160645 13.99860000610352 L 0.0009002700680866838 13.99860000610352 L 0.0009002700680866838 2.411099910736084 L 0.0009002700680866838 -0.0009001312428154051 L 8.571599960327148 -0.0009001312428154051 L 8.571599960327148 2.411099910736084 L 16.00020027160645 2.411099910736084 L 16.00020027160645 13.99860000610352 Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 301 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 47 KiB |
@@ -19,12 +19,28 @@ import { Redirect, Route, Router, Switch } from "react-router-dom";
|
||||
import history from "./history";
|
||||
import Login from "./screens/LoginPage/LoginPage";
|
||||
import Console from "./screens/Console/Console";
|
||||
import NotFoundPage from "./screens/NotFoundPage";
|
||||
import storage from "local-storage-fallback";
|
||||
import { connect } from "react-redux";
|
||||
import { AppState } from "./store";
|
||||
import { userLoggedIn } from "./actions";
|
||||
import LoginCallback from "./screens/LoginPage/LoginCallback";
|
||||
import { hot } from "react-hot-loader/root";
|
||||
|
||||
interface ProtectedRouteProps {
|
||||
loggedIn: boolean;
|
||||
component: any;
|
||||
}
|
||||
|
||||
export class ProtectedRoute extends React.Component<ProtectedRouteProps> {
|
||||
render() {
|
||||
const Component = this.props.component;
|
||||
return this.props.loggedIn ? (
|
||||
<Component />
|
||||
) : (
|
||||
<Redirect to={{ pathname: "/login" }} />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const isLoggedIn = () => {
|
||||
return (
|
||||
@@ -46,33 +62,18 @@ interface RoutesProps {
|
||||
}
|
||||
|
||||
class Routes extends React.Component<RoutesProps> {
|
||||
componentDidMount(): void {
|
||||
if (isLoggedIn()) {
|
||||
this.props.userLoggedIn(true);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const loggedIn = isLoggedIn();
|
||||
return (
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
<Route exact path="/oauth_callback" component={LoginCallback} />
|
||||
<Route exact path="/login" component={Login} />
|
||||
{this.props.loggedIn ? (
|
||||
<Switch>
|
||||
<Route path="/*" component={Console} />
|
||||
<Route component={NotFoundPage} />
|
||||
</Switch>
|
||||
) : (
|
||||
<Switch>
|
||||
<Route exact path="/" component={Login} />
|
||||
<Redirect to="/" />
|
||||
</Switch>
|
||||
)}
|
||||
<ProtectedRoute component={Console} loggedIn={loggedIn} />
|
||||
</Switch>
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default connector(Routes);
|
||||
export default hot(connector(Routes));
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import storage from "local-storage-fallback";
|
||||
import { ICapacity, IStorageType, IZoneModel } from "./types";
|
||||
import { ICapacity, IZoneModel } from "./types";
|
||||
|
||||
const minStReq = 1073741824; // Minimal Space required for MinIO
|
||||
const minMemReq = 2147483648; // Minimal Memory required for MinIO in bytes
|
||||
|
||||
34
portal-ui/src/icons/AddIcon.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 { SvgIcon } from "@material-ui/core";
|
||||
class AddIcon extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<SvgIcon viewBox="0 0 12 12">
|
||||
<path
|
||||
fill="#081c42"
|
||||
className="a"
|
||||
d="M-13160.269,1885.114h-3.235v-4.381h-4.382V1877.5h4.382v-4.381h3.235v4.381h4.383v3.238h-4.383v4.38Z"
|
||||
transform="translate(13167.886 -1873.114)"
|
||||
/>
|
||||
</SvgIcon>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default AddIcon;
|
||||
75
portal-ui/src/icons/AllBucketsIcon.tsx
Normal file
@@ -0,0 +1,75 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 { SvgIcon } from "@material-ui/core";
|
||||
class AllBucketsIcon extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<SvgIcon viewBox="0 0 15.834 17.375">
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="a"
|
||||
y1="0.5"
|
||||
x2="1"
|
||||
y2="0.5"
|
||||
gradientUnits="objectBoundingBox"
|
||||
>
|
||||
<stop offset="0.044" stopColor="#362585" />
|
||||
<stop offset="0.301" stopColor="#281b6f" />
|
||||
<stop offset="1" stopColor="#1e1560" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g transform="translate(0 0.375)">
|
||||
<circle
|
||||
style={{ opacity: 0.1, fill: "url(#a)" }}
|
||||
cx="6.625"
|
||||
cy="6.625"
|
||||
r="6.625"
|
||||
transform="translate(0 3.75)"
|
||||
/>
|
||||
<g transform="translate(3.092)">
|
||||
<ellipse
|
||||
style={{
|
||||
fill: "none",
|
||||
stroke: "#707070",
|
||||
strokeMiterlimit: 10,
|
||||
strokeWidth: "0.75px",
|
||||
}}
|
||||
cx="6.183"
|
||||
cy="1.244"
|
||||
rx="6.183"
|
||||
ry="1.244"
|
||||
transform="translate(0)"
|
||||
/>
|
||||
<path
|
||||
style={{
|
||||
fill: "none",
|
||||
stroke: "#707070",
|
||||
strokeMiterlimit: 10,
|
||||
strokeWidth: "0.75px",
|
||||
}}
|
||||
d="M-3722.174,1225.225l-1.687,10.292a.858.858,0,0,1-.578.669,12.182,12.182,0,0,1-3.918.647,12.187,12.187,0,0,1-3.894-.639.878.878,0,0,1-.6-.678q-.843-5.145-1.687-10.291"
|
||||
transform="translate(3734.541 -1223.981)"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</SvgIcon>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default AllBucketsIcon;
|
||||
37
portal-ui/src/icons/ConsoleIcon.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 { SvgIcon } from "@material-ui/core";
|
||||
class ConsoleIcon extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<SvgIcon>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10">
|
||||
<g transform="translate(-518 -361)">
|
||||
<path
|
||||
d="M-126,0V10h10V0Zm1.5,8.5V2.95h7V8.5Z"
|
||||
transform="translate(644 361)"
|
||||
/>
|
||||
<rect width="2" height="1" transform="translate(520.272 364.772)" />
|
||||
</g>
|
||||
</svg>
|
||||
</SvgIcon>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ConsoleIcon;
|
||||
@@ -1,5 +1,5 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2019 MinIO, Inc.
|
||||
// Copyright (c) 2020 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
|
||||
@@ -15,21 +15,36 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React from "react";
|
||||
import {SvgIcon} from "@material-ui/core";
|
||||
import { SvgIcon } from "@material-ui/core";
|
||||
class CreateIcon extends React.Component {
|
||||
render() {
|
||||
return (<SvgIcon>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<title>ic_h_create-new_sl</title>
|
||||
<g id="Layer_2" data-name="Layer 2">
|
||||
<g id="Layer_1-2" data-name="Layer 1">
|
||||
<path className="cls-1"
|
||||
d="M0,0V16H16V0ZM11.886,9.048H9.048v2.838h-2.1V9.048H4.114v-2.1H6.952V4.114h2.1V6.952h2.838Z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</SvgIcon>)
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<SvgIcon>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
|
||||
<g
|
||||
id="Group_55"
|
||||
data-name="Group 55"
|
||||
transform="translate(1002 -2555)"
|
||||
>
|
||||
<rect
|
||||
id="Rectangle_29"
|
||||
width="2"
|
||||
height="12"
|
||||
transform="translate(-997 2555)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<rect
|
||||
id="Rectangle_30"
|
||||
width="2"
|
||||
height="12"
|
||||
transform="translate(-990 2560) rotate(90)"
|
||||
fill="#fff"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</SvgIcon>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default CreateIcon;
|
||||
|
||||
73
portal-ui/src/icons/EgressIcon.tsx
Normal file
@@ -0,0 +1,73 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 { SvgIcon } from "@material-ui/core";
|
||||
class EgressIcon extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<SvgIcon viewBox="0 0 18.344 17.009">
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="a"
|
||||
y1="0.5"
|
||||
x2="1"
|
||||
y2="0.5"
|
||||
gradientUnits="objectBoundingBox"
|
||||
>
|
||||
<stop offset="0.044" stopColor="#362585" />
|
||||
<stop offset="0.301" stopColor="#281b6f" />
|
||||
<stop offset="1" stopColor="#1e1560" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g transform="translate(0 0.25)">
|
||||
<ellipse
|
||||
style={{ opacity: 0.1, fill: "url(#a)" }}
|
||||
cx="7.462"
|
||||
cy="7.462"
|
||||
rx="7.462"
|
||||
ry="7.462"
|
||||
transform="translate(0 1.835)"
|
||||
/>
|
||||
<rect
|
||||
style={{
|
||||
fill: "none",
|
||||
stroke: "#707070",
|
||||
strokeMiterlimit: 10,
|
||||
strokeWidth: "0.5px",
|
||||
}}
|
||||
width="9.323"
|
||||
height="9.323"
|
||||
transform="translate(4.083)"
|
||||
/>
|
||||
<rect
|
||||
style={{
|
||||
fill: "none",
|
||||
stroke: "#707070",
|
||||
strokeMiterlimit: 10,
|
||||
strokeWidth: "0.5px",
|
||||
}}
|
||||
width="8.223"
|
||||
height="8.223"
|
||||
transform="translate(9.871 5.307)"
|
||||
/>
|
||||
</g>
|
||||
</SvgIcon>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default EgressIcon;
|
||||
53
portal-ui/src/icons/HealIcon.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 { SvgIcon } from "@material-ui/core";
|
||||
class HealIcon extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<SvgIcon>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10.014 9.993">
|
||||
<path
|
||||
className="a"
|
||||
d="M9.162,5.971h0L8.192,5,9.346,3.846a2.257,2.257,0,0,0,0-3.192,2.311,2.311,0,0,0-3.192,0L5,1.808,4.029.837,3.846.654a2.311,2.311,0,0,0-3.192,0,2.257,2.257,0,0,0,0,3.192l.184.183h0L1.808,5,.654,6.154A2.257,2.257,0,0,0,3.846,9.346L5,8.192l.971.971.183.183A2.257,2.257,0,0,0,9.346,6.154Zm-2.29-4.6a1.27,1.27,0,0,1,1.757,0,1.242,1.242,0,0,1,0,1.757L7.475,4.283,5.717,2.525Zm-5.5,1.757A1.243,1.243,0,0,1,3.129,1.371l.183.183L1.555,3.312Zm1.757,5.5a1.27,1.27,0,0,1-1.757,0,1.242,1.242,0,0,1,0-1.757L2.525,5.717,4.283,7.475Zm2.843-.9-.254-.253L2.525,4.283l-.253-.254L4.029,2.272l.254.253L7.475,5.717l.253.254Zm2.657.9a1.271,1.271,0,0,1-1.757,0l-.183-.183L8.446,6.688l.183.183h0a1.241,1.241,0,0,1,0,1.757Z"
|
||||
transform="translate(0.007 -0.014)"
|
||||
/>
|
||||
<circle
|
||||
cx="0.5"
|
||||
cy="0.5"
|
||||
r="0.5"
|
||||
transform="translate(4.507 4.486)"
|
||||
/>
|
||||
<circle
|
||||
cx="0.5"
|
||||
cy="0.5"
|
||||
r="0.5"
|
||||
transform="translate(3.507 3.486)"
|
||||
/>
|
||||
<circle
|
||||
cx="0.5"
|
||||
cy="0.5"
|
||||
r="0.5"
|
||||
transform="translate(5.507 5.486)"
|
||||
/>
|
||||
</svg>
|
||||
</SvgIcon>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default HealIcon;
|
||||
47
portal-ui/src/icons/LicenseIcon.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 { SvgIcon } from "@material-ui/core";
|
||||
|
||||
class LicenseIcon extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<SvgIcon>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 11">
|
||||
<path fill="#fff" d="M11 11H0V2h11v9zM2 8v1h7V8zm0-3v1h5V5z"></path>
|
||||
<g
|
||||
fill="#07274a"
|
||||
stroke="#fdfdfd"
|
||||
strokeWidth="0.5"
|
||||
transform="translate(7)"
|
||||
>
|
||||
<circle cx="3" cy="3" r="3" stroke="none"></circle>
|
||||
<circle cx="3" cy="3" r="2.75" fill="none"></circle>
|
||||
</g>
|
||||
<path
|
||||
fill="none"
|
||||
stroke="#fff"
|
||||
strokeWidth="0.5"
|
||||
d="M8.73 2.794l.954.953 1.471-1.471"
|
||||
></path>
|
||||
</svg>
|
||||
</SvgIcon>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default LicenseIcon;
|
||||
47
portal-ui/src/icons/LogoutIcon.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 { SvgIcon } from "@material-ui/core";
|
||||
class LogoutIcon extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<SvgIcon>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12.122 10.571">
|
||||
<g transform="translate(0 0.5)">
|
||||
<path
|
||||
style={{ fill: "none", stroke: "rgba(255,255,255,0.8)" }}
|
||||
d="M4816.27,3755.205v-2.939h8.539v9.571h-8.539v-2.932"
|
||||
transform="translate(-4813.187 -3752.266)"
|
||||
/>
|
||||
<path
|
||||
style={{ fill: "none", stroke: "rgba(255,255,255,0.8)" }}
|
||||
d="M4813.187,3757.052h8.081"
|
||||
transform="translate(-4813.187 -3752.266)"
|
||||
/>
|
||||
<path
|
||||
style={{ fill: "none", stroke: "rgba(255,255,255,0.8)" }}
|
||||
d="M4806.5,3756.511l2.265,2.063-2.265,2.063"
|
||||
transform="translate(-4800.808 -3753.863)"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</SvgIcon>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default LogoutIcon;
|
||||
33
portal-ui/src/icons/RemoveIcon.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 { SvgIcon } from "@material-ui/core";
|
||||
class RemoveIcon extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<SvgIcon viewBox="0 0 11.656 3.101">
|
||||
<path
|
||||
fill="#081c42"
|
||||
d="M-13157.172,1879.551h-11.656v-3.1h11.656v3.1Z"
|
||||
transform="translate(13168.828 -1876.449)"
|
||||
/>
|
||||
</SvgIcon>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default RemoveIcon;
|
||||
41
portal-ui/src/icons/UploadFile.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 { SvgIcon } from "@material-ui/core";
|
||||
|
||||
class UploadFile extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<SvgIcon>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 12.996">
|
||||
<g transform="translate(-63.686 -70.783)">
|
||||
<path
|
||||
className="a"
|
||||
d="M74.736,79.879v1.95h-9.1v-1.95h-1.95v3.9h13v-3.9Z"
|
||||
/>
|
||||
<path
|
||||
className="a"
|
||||
d="M69.211,80.533h1.95V73.861h1.525l-2.5-3.078-2.5,3.078h1.525Z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</SvgIcon>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default UploadFile;
|
||||
64
portal-ui/src/icons/UsageIcon.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 { SvgIcon } from "@material-ui/core";
|
||||
class UsageIcon extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<SvgIcon viewBox="0 0 16.172 17.187">
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="a"
|
||||
y1="0.5"
|
||||
x2="1"
|
||||
y2="0.5"
|
||||
gradientUnits="objectBoundingBox"
|
||||
>
|
||||
<stop offset="0.044" stopColor="#362585" />
|
||||
<stop offset="0.301" stopColor="#281b6f" />
|
||||
<stop offset="1" stopColor="#1e1560" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
style={{
|
||||
fill: "none",
|
||||
stroke: "#707070",
|
||||
strokeMiterlimit: 10,
|
||||
strokeWidth: "0.5px",
|
||||
}}
|
||||
d="M-4778.1,2239.582v6.425h6.425"
|
||||
transform="translate(4787.594 -2239.582)"
|
||||
/>
|
||||
<path
|
||||
fill={"#707070"}
|
||||
d="M-4784.238,2247.532v-.581c0-.027.009-.054.012-.081.039-.313.055-.632.121-.939a6.744,6.744,0,0,1,3.064-4.441,6.514,6.514,0,0,1,3.293-1.032,6.923,6.923,0,0,1,2.667.423,6.793,6.793,0,0,1,4.119,4.333,6.053,6.053,0,0,1,.279,1.337c.006.083.014.164.021.247v.86c-.011.131-.018.261-.032.392a6.494,6.494,0,0,1-.626,2.147,6.807,6.807,0,0,1-4.044,3.528,6.052,6.052,0,0,1-1.663.3,6.576,6.576,0,0,1-2.565-.325,6.73,6.73,0,0,1-3.947-3.451,6.627,6.627,0,0,1-.658-2.288C-4784.212,2247.816-4784.225,2247.674-4784.238,2247.532Zm13.025-.306c-.024-.309-.021-.661-.082-1a6.206,6.206,0,0,0-1.658-3.293,6.153,6.153,0,0,0-4.1-1.9,5.984,5.984,0,0,0-2.476.355,6.188,6.188,0,0,0-4.134,5.708,6.453,6.453,0,0,0,.228,1.881,6.127,6.127,0,0,0,1.984,3.052,6.046,6.046,0,0,0,3.806,1.445,6.043,6.043,0,0,0,1.235-.065,6.249,6.249,0,0,0,3.783-2.2,6.2,6.2,0,0,0,1.352-3.048C-4771.228,2247.863-4771.233,2247.563-4771.212,2247.226Z"
|
||||
transform="translate(4786.834 -2240.452)"
|
||||
/>
|
||||
<ellipse
|
||||
style={{ opacity: 0.1, fill: "url(#a)" }}
|
||||
cx="6.151"
|
||||
cy="6.151"
|
||||
rx="6.151"
|
||||
ry="6.151"
|
||||
transform="translate(0 4.886)"
|
||||
/>
|
||||
</SvgIcon>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default UsageIcon;
|
||||
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 81.879 23.119"><defs><style>.cls-1{fill:#1b1556;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M10.086,13.4,8.969,14.573a4.2,4.2,0,0,0-3.01-1.279,3.886,3.886,0,0,0-3.884,4.093,3.888,3.888,0,0,0,3.884,4.1A4.4,4.4,0,0,0,9,20.2l1.082,1.186A5.344,5.344,0,0,1,6,23.119a5.512,5.512,0,0,1-5.7-5.732A5.509,5.509,0,0,1,6,11.667,5.328,5.328,0,0,1,10.086,13.4Z"/><path class="cls-1" d="M23.608,17.387a5.637,5.637,0,0,1-5.8,5.732,5.628,5.628,0,0,1-5.791-5.732,5.626,5.626,0,0,1,5.791-5.72A5.635,5.635,0,0,1,23.608,17.387Zm-9.825,0a4.024,4.024,0,1,0,8.046,0,4.024,4.024,0,1,0-8.046,0Z"/><path class="cls-1" d="M36.862,16.073V22.9H35.129V16.643c0-2.093-1.163-3.325-3.174-3.325a3.24,3.24,0,0,0-3.371,3.372V22.9H26.839V11.888H28.56v1.569a4.354,4.354,0,0,1,3.709-1.79A4.261,4.261,0,0,1,36.862,16.073Z"/><path class="cls-1" d="M48.2,14.225a6.872,6.872,0,0,0-3.605-1.035c-1.569,0-2.6.663-2.6,1.732,0,.919.8,1.372,2.244,1.547l1.3.163c2.338.3,3.7,1.267,3.7,3.069,0,2.093-1.884,3.407-4.849,3.407A7.725,7.725,0,0,1,39.791,21.7l.8-1.3a5.8,5.8,0,0,0,3.815,1.2c1.86,0,3.034-.616,3.034-1.778,0-.884-.744-1.419-2.3-1.605l-1.314-.151c-2.477-.3-3.639-1.408-3.639-3.046,0-2.082,1.755-3.338,4.4-3.338a8.067,8.067,0,0,1,4.372,1.2Z"/><path class="cls-1" d="M63.033,17.387a5.8,5.8,0,0,1-11.593,0,5.8,5.8,0,0,1,11.593,0Zm-9.825,0a4.023,4.023,0,1,0,8.045,0,4.023,4.023,0,1,0-8.045,0Z"/><path class="cls-1" d="M68.008,22.9H66.264V6.155h1.744Z"/><path class="cls-1" d="M81.879,17.353a5.606,5.606,0,0,1-.035.65H73.019a3.743,3.743,0,0,0,3.9,3.593A5.1,5.1,0,0,0,80.4,20.213l.931,1.186a6.179,6.179,0,0,1-4.524,1.72A5.394,5.394,0,0,1,71.24,17.4a5.406,5.406,0,0,1,5.465-5.732C79.693,11.667,81.856,14,81.879,17.353ZM73.043,16.6h7.069a3.446,3.446,0,0,0-3.442-3.384A3.59,3.59,0,0,0,73.043,16.6Z"/><rect class="cls-1" x="13.484" y="0.12" width="2.328" height="6.875"/><path class="cls-1" d="M10.662.215,5.936,3.1a.21.21,0,0,1-.219,0L.992.215A.651.651,0,0,0,.654.12H.648A.648.648,0,0,0,0,.768v6.22H2.327V4.028a.233.233,0,0,1,.354-.2l2.648,1.62a.829.829,0,0,0,.853.008l2.8-1.639a.232.232,0,0,1,.35.2V6.988h2.327V.768A.648.648,0,0,0,11.006.12H11A.651.651,0,0,0,10.662.215Z"/><path class="cls-1" d="M27.422.12H25.061V3.25a.233.233,0,0,1-.342.205L18.6.2A.662.662,0,0,0,18.3.12h0a.648.648,0,0,0-.648.648v6.22h2.342V3.863a.233.233,0,0,1,.342-.206L26.47,6.915a.646.646,0,0,0,.3.076h0a.648.648,0,0,0,.648-.648Z"/><path class="cls-1" d="M29.252,7V.12h1.072V7Z"/><path class="cls-1" d="M36.629,7.119c-2.882,0-4.927-1.368-4.927-3.56S33.759,0,36.629,0s4.938,1.367,4.938,3.559S39.547,7.119,36.629,7.119Zm0-6.208c-2.143,0-3.794.936-3.794,2.648s1.651,2.648,3.794,2.648,3.805-.923,3.805-2.648S38.772.911,36.629.911Z"/></g></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="121.755" height="29.822" viewBox="0 0 121.755 29.822"><defs><style>.a{fill:#fff;}</style></defs><g transform="translate(3016.56 -1037.757)"><path class="a" d="M-3000.913,1053.692l-1.772,1.194a6.088,6.088,0,0,0-5.135-2.652,6.348,6.348,0,0,0-6.522,6.654,6.348,6.348,0,0,0,6.522,6.654,6.031,6.031,0,0,0,5.124-2.64l1.735,1.266a8.126,8.126,0,0,1-6.859,3.411,8.422,8.422,0,0,1-8.74-8.691,8.422,8.422,0,0,1,8.74-8.691A7.963,7.963,0,0,1-3000.913,1053.692Z"/><path class="a" d="M-2980.919,1058.888a8.422,8.422,0,0,1-8.74,8.691,8.422,8.422,0,0,1-8.739-8.691,8.421,8.421,0,0,1,8.739-8.691A8.422,8.422,0,0,1-2980.919,1058.888Zm-15.261,0a6.347,6.347,0,0,0,6.521,6.654,6.347,6.347,0,0,0,6.521-6.654,6.347,6.347,0,0,0-6.521-6.654A6.347,6.347,0,0,0-2996.18,1058.888Z"/><path class="a" d="M-2962.831,1067.338h-1.917l-10.2-13.26-.012,13.248h-2.122v-16.888h1.917l10.21,13.26V1050.45h2.122Z"/><path class="a" d="M-2947.009,1053.777a8.835,8.835,0,0,0-5-1.555c-2.471,0-4.231,1.109-4.231,2.929,0,1.531,1.29,2.315,3.821,2.628l1.484.181c2.856.35,5.3,1.507,5.3,4.484,0,3.364-3.05,5.123-6.7,5.123a10.935,10.935,0,0,1-6.654-2.194l1.157-1.687a9.018,9.018,0,0,0,5.5,1.868c2.519,0,4.5-1.025,4.5-2.929,0-1.567-1.41-2.314-4.038-2.64l-1.567-.193c-2.784-.337-5-1.627-5-4.508,0-3.255,2.893-5.075,6.449-5.075a10.336,10.336,0,0,1,6.076,1.844Z"/><path class="a" d="M-2925.292,1058.888a8.422,8.422,0,0,1-8.74,8.691,8.422,8.422,0,0,1-8.739-8.691,8.421,8.421,0,0,1,8.739-8.691A8.422,8.422,0,0,1-2925.292,1058.888Zm-15.261,0a6.348,6.348,0,0,0,6.521,6.654,6.347,6.347,0,0,0,6.521-6.654,6.347,6.347,0,0,0-6.521-6.654A6.348,6.348,0,0,0-2940.553,1058.888Z"/><path class="a" d="M-2909.663,1067.326h-11.79V1050.45h2.122v14.863h9.668Z"/><path class="a" d="M-2894.8,1067.326h-11.982V1050.45h11.862v1.988h-9.74v5.389h9.427v2h-9.427v5.509h9.86Z"/><rect class="a" width="2.576" height="7.547" transform="translate(-3001.66 1037.924)"/><path class="a" d="M-3004.759,1037.995l-5.23,3.194a.229.229,0,0,1-.242,0l-5.23-3.194a.726.726,0,0,0-.374-.1h-.006a.717.717,0,0,0-.717.717v6.864h2.574v-3.257a.258.258,0,0,1,.392-.22l2.931,1.793a.919.919,0,0,0,.944.009l3.092-1.814a.258.258,0,0,1,.388.222v3.267h2.575v-6.864a.717.717,0,0,0-.717-.717h-.006A.723.723,0,0,0-3004.759,1037.995Z"/><path class="a" d="M-2986.212,1037.922h-2.613v3.463a.258.258,0,0,1-.379.228l-6.771-3.607a.723.723,0,0,0-.337-.084h0a.717.717,0,0,0-.717.717v6.832h2.592v-3.408a.258.258,0,0,1,.379-.227l6.8,3.606a.714.714,0,0,0,.336.083h0a.716.716,0,0,0,.717-.717v-6.886Z"/><path class="a" d="M-2984.121,1045.469v-7.547h1.2v7.547Z"/><path class="a" d="M-2976.024,1045.635c-3.189,0-5.451-1.513-5.451-3.939s2.276-3.939,5.451-3.939,5.466,1.513,5.466,3.939S-2972.794,1045.635-2976.024,1045.635Zm0-6.87c-2.371,0-4.2,1.036-4.2,2.931s1.826,2.93,4.2,2.93,4.212-1.022,4.212-2.93S-2973.652,1038.765-2976.024,1038.765Z"/></g></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.8 KiB |
@@ -1,4 +1,4 @@
|
||||
// This file is part of MinIO Buckets Server
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
createStyles,
|
||||
StyledProps,
|
||||
Theme,
|
||||
withStyles
|
||||
withStyles,
|
||||
} from "@material-ui/core/styles";
|
||||
|
||||
import history from "../../../history";
|
||||
@@ -28,7 +28,7 @@ import {
|
||||
RouteComponentProps,
|
||||
Router,
|
||||
Switch,
|
||||
withRouter
|
||||
withRouter,
|
||||
} from "react-router-dom";
|
||||
import { connect } from "react-redux";
|
||||
import { AppState } from "../../../store";
|
||||
@@ -41,62 +41,62 @@ import ViewBucket from "./ViewBucket/ViewBucket";
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
root: {
|
||||
display: "flex"
|
||||
display: "flex",
|
||||
},
|
||||
toolbar: {
|
||||
background: theme.palette.background.default,
|
||||
color: "black",
|
||||
paddingRight: 24 // keep right padding when drawer closed
|
||||
paddingRight: 24, // keep right padding when drawer closed
|
||||
},
|
||||
toolbarIcon: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-end",
|
||||
padding: "0 8px",
|
||||
...theme.mixins.toolbar
|
||||
...theme.mixins.toolbar,
|
||||
},
|
||||
appBar: {
|
||||
zIndex: theme.zIndex.drawer + 1,
|
||||
transition: theme.transitions.create(["width", "margin"], {
|
||||
easing: theme.transitions.easing.sharp,
|
||||
duration: theme.transitions.duration.leavingScreen
|
||||
})
|
||||
duration: theme.transitions.duration.leavingScreen,
|
||||
}),
|
||||
},
|
||||
|
||||
menuButton: {
|
||||
marginRight: 36
|
||||
marginRight: 36,
|
||||
},
|
||||
menuButtonHidden: {
|
||||
display: "none"
|
||||
display: "none",
|
||||
},
|
||||
title: {
|
||||
flexGrow: 1
|
||||
flexGrow: 1,
|
||||
},
|
||||
appBarSpacer: {
|
||||
height: "5px"
|
||||
height: "5px",
|
||||
},
|
||||
content: {
|
||||
flexGrow: 1,
|
||||
height: "100vh",
|
||||
overflow: "auto"
|
||||
overflow: "auto",
|
||||
},
|
||||
container: {
|
||||
paddingTop: theme.spacing(4),
|
||||
paddingBottom: theme.spacing(4)
|
||||
paddingBottom: theme.spacing(4),
|
||||
},
|
||||
paper: {
|
||||
padding: theme.spacing(2),
|
||||
display: "flex",
|
||||
overflow: "auto",
|
||||
flexDirection: "column"
|
||||
flexDirection: "column",
|
||||
},
|
||||
fixedHeight: {
|
||||
minHeight: 240
|
||||
}
|
||||
minHeight: 240,
|
||||
},
|
||||
});
|
||||
|
||||
const mapState = (state: AppState) => ({
|
||||
open: state.system.sidebarOpen
|
||||
open: state.system.sidebarOpen,
|
||||
});
|
||||
|
||||
const connector = connect(mapState, { setMenuOpen });
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import { Button, LinearProgress } from "@material-ui/core";
|
||||
@@ -23,6 +23,21 @@ import { modalBasic } from "../../Common/FormComponents/common/styleLibrary";
|
||||
import api from "../../../../common/api";
|
||||
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
|
||||
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
|
||||
import { factorForDropdown, getBytes } from "../../../../common/utils";
|
||||
import { AppState } from "../../../../store";
|
||||
import { connect } from "react-redux";
|
||||
import {
|
||||
addBucketName,
|
||||
addBucketQuota,
|
||||
addBucketQuotaSize,
|
||||
addBucketQuotaType,
|
||||
addBucketQuotaUnit,
|
||||
addBucketVersioned,
|
||||
} from "../actions";
|
||||
import { useDebounce } from "use-debounce";
|
||||
import { MakeBucketRequest } from "../types";
|
||||
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
@@ -32,126 +47,294 @@ const styles = (theme: Theme) =>
|
||||
buttonContainer: {
|
||||
textAlign: "right",
|
||||
},
|
||||
multiContainer: {
|
||||
display: "flex",
|
||||
alignItems: "center" as const,
|
||||
justifyContent: "flex-start" as const,
|
||||
},
|
||||
quotaSizeContainer: {
|
||||
flexGrow: 1,
|
||||
},
|
||||
sizeFactorContainer: {
|
||||
flexGrow: 0,
|
||||
maxWidth: 80,
|
||||
marginLeft: 8,
|
||||
alignSelf: "flex-start" as const,
|
||||
},
|
||||
...modalBasic,
|
||||
});
|
||||
|
||||
interface IAddBucketProps {
|
||||
classes: any;
|
||||
open: boolean;
|
||||
closeModalAndRefresh: () => void;
|
||||
}
|
||||
|
||||
interface IAddBucketState {
|
||||
addLoading: boolean;
|
||||
addError: string;
|
||||
closeModalAndRefresh: (refresh: boolean) => void;
|
||||
addBucketName: typeof addBucketName;
|
||||
addBucketVersioned: typeof addBucketVersioned;
|
||||
addBucketQuota: typeof addBucketQuota;
|
||||
addBucketQuotaType: typeof addBucketQuotaType;
|
||||
addBucketQuotaSize: typeof addBucketQuotaSize;
|
||||
addBucketQuotaUnit: typeof addBucketQuotaUnit;
|
||||
bucketName: string;
|
||||
versioned: boolean;
|
||||
enableQuota: boolean;
|
||||
quotaType: string;
|
||||
quotaSize: string;
|
||||
quotaUnit: string;
|
||||
}
|
||||
|
||||
class AddBucket extends React.Component<IAddBucketProps, IAddBucketState> {
|
||||
state: IAddBucketState = {
|
||||
addLoading: false,
|
||||
addError: "",
|
||||
bucketName: "",
|
||||
};
|
||||
const AddBucket = ({
|
||||
classes,
|
||||
open,
|
||||
closeModalAndRefresh,
|
||||
addBucketName,
|
||||
addBucketVersioned,
|
||||
addBucketQuota,
|
||||
addBucketQuotaType,
|
||||
addBucketQuotaSize,
|
||||
addBucketQuotaUnit,
|
||||
bucketName,
|
||||
versioned,
|
||||
enableQuota,
|
||||
quotaType,
|
||||
quotaSize,
|
||||
quotaUnit,
|
||||
}: IAddBucketProps) => {
|
||||
const [bName, setBName] = useState<string>(bucketName);
|
||||
const [addLoading, setAddLoading] = useState<boolean>(false);
|
||||
const [addError, setAddError] = useState<string>("");
|
||||
const [sendEnabled, setSendEnabled] = useState<boolean>(false);
|
||||
|
||||
addRecord(event: React.FormEvent) {
|
||||
const addRecord = (event: React.FormEvent) => {
|
||||
event.preventDefault();
|
||||
const { bucketName, addLoading } = this.state;
|
||||
if (addLoading) {
|
||||
return;
|
||||
}
|
||||
this.setState({ addLoading: true }, () => {
|
||||
api
|
||||
.invoke("POST", "/api/v1/buckets", {
|
||||
name: bucketName,
|
||||
})
|
||||
.then((res) => {
|
||||
this.setState(
|
||||
{
|
||||
addLoading: false,
|
||||
addError: "",
|
||||
},
|
||||
() => {
|
||||
this.props.closeModalAndRefresh();
|
||||
}
|
||||
);
|
||||
})
|
||||
.catch((err) => {
|
||||
this.setState({
|
||||
addLoading: false,
|
||||
addError: err,
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
setAddLoading(true);
|
||||
|
||||
render() {
|
||||
const { classes, open } = this.props;
|
||||
const { addLoading, addError, bucketName } = this.state;
|
||||
return (
|
||||
<ModalWrapper
|
||||
title="Create Bucket"
|
||||
modalOpen={open}
|
||||
onClose={() => {
|
||||
this.setState({ addError: "" }, () => {
|
||||
this.props.closeModalAndRefresh();
|
||||
});
|
||||
let request: MakeBucketRequest = {
|
||||
name: bucketName,
|
||||
versioning: versioned,
|
||||
};
|
||||
|
||||
if (enableQuota) {
|
||||
const amount = getBytes(quotaSize, quotaUnit, false);
|
||||
request.quota = {
|
||||
enabled: true,
|
||||
quota_type: quotaType,
|
||||
amount: parseInt(amount),
|
||||
};
|
||||
}
|
||||
|
||||
api
|
||||
.invoke("POST", "/api/v1/buckets", request)
|
||||
.then((res) => {
|
||||
setAddLoading(false);
|
||||
setAddError("");
|
||||
closeModalAndRefresh(true);
|
||||
})
|
||||
.catch((err) => {
|
||||
setAddLoading(false);
|
||||
setAddError(err);
|
||||
});
|
||||
};
|
||||
|
||||
const [value] = useDebounce(bName, 1000);
|
||||
|
||||
useEffect(() => {
|
||||
addBucketName(value);
|
||||
}, [value, addBucketName]);
|
||||
|
||||
const resetForm = () => {
|
||||
setBName("");
|
||||
addBucketVersioned(false);
|
||||
addBucketQuota(false);
|
||||
addBucketQuotaType("hard");
|
||||
addBucketQuotaSize("1");
|
||||
addBucketQuotaUnit("TiB");
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
let valid = false;
|
||||
|
||||
if (bName.trim() !== "") {
|
||||
valid = true;
|
||||
}
|
||||
|
||||
if (enableQuota && valid) {
|
||||
if (quotaSize.trim() === "" || parseInt(quotaSize) === 0) {
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
setSendEnabled(valid);
|
||||
}, [bName, versioned, quotaType, quotaSize, quotaUnit, enableQuota]);
|
||||
|
||||
return (
|
||||
<ModalWrapper
|
||||
title="Create Bucket"
|
||||
modalOpen={open}
|
||||
onClose={() => {
|
||||
setAddError("");
|
||||
closeModalAndRefresh(false);
|
||||
}}
|
||||
aria-labelledby="alert-dialog-title"
|
||||
aria-describedby="alert-dialog-description"
|
||||
>
|
||||
<form
|
||||
noValidate
|
||||
autoComplete="off"
|
||||
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
|
||||
addRecord(e);
|
||||
}}
|
||||
aria-labelledby="alert-dialog-title"
|
||||
aria-describedby="alert-dialog-description"
|
||||
>
|
||||
<form
|
||||
noValidate
|
||||
autoComplete="off"
|
||||
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
|
||||
this.addRecord(e);
|
||||
}}
|
||||
>
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.formScrollable}>
|
||||
{addError !== "" && (
|
||||
<Grid item xs={12}>
|
||||
<Typography
|
||||
component="p"
|
||||
variant="body1"
|
||||
className={classes.errorBlock}
|
||||
>
|
||||
{addError}
|
||||
</Typography>
|
||||
</Grid>
|
||||
)}
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.formScrollable}>
|
||||
{addError !== "" && (
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="bucket-name"
|
||||
name="bucket-name"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
this.setState({ bucketName: e.target.value });
|
||||
}}
|
||||
label="Bucket Name"
|
||||
value={bucketName}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={addLoading}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</Grid>
|
||||
{addLoading && (
|
||||
<Grid item xs={12}>
|
||||
<LinearProgress />
|
||||
<Typography
|
||||
component="p"
|
||||
variant="body1"
|
||||
className={classes.errorBlock}
|
||||
>
|
||||
{addError}
|
||||
</Typography>
|
||||
</Grid>
|
||||
)}
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="bucket-name"
|
||||
name="bucket-name"
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setBName(event.target.value);
|
||||
}}
|
||||
label="Bucket Name"
|
||||
value={bName}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<FormSwitchWrapper
|
||||
value="versioned"
|
||||
id="versioned"
|
||||
name="versioned"
|
||||
checked={versioned}
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
addBucketVersioned(event.target.checked);
|
||||
}}
|
||||
label={"Versioning"}
|
||||
indicatorLabel={"On"}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<FormSwitchWrapper
|
||||
value="bucket_quota"
|
||||
id="bucket_quota"
|
||||
name="bucket_quota"
|
||||
checked={enableQuota}
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
addBucketQuota(event.target.checked);
|
||||
}}
|
||||
label={"Enable Bucket Quota"}
|
||||
indicatorLabel={"On"}
|
||||
/>
|
||||
</Grid>
|
||||
{enableQuota && (
|
||||
<React.Fragment>
|
||||
<Grid item xs={12}>
|
||||
<SelectWrapper
|
||||
value={quotaType}
|
||||
label="Quota Type"
|
||||
id="quota_type"
|
||||
name="quota_type"
|
||||
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
|
||||
addBucketQuotaType(e.target.value as string);
|
||||
}}
|
||||
options={[
|
||||
{ value: "hard", label: "Hard" },
|
||||
{ value: "fifo", label: "FIFO" },
|
||||
]}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<div className={classes.multiContainer}>
|
||||
<div className={classes.quotaSizeContainer}>
|
||||
<InputBoxWrapper
|
||||
type="number"
|
||||
id="quota_size"
|
||||
name="quota_size"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
addBucketQuotaSize(e.target.value);
|
||||
}}
|
||||
label="Quota"
|
||||
value={quotaSize}
|
||||
required
|
||||
min="1"
|
||||
/>
|
||||
</div>
|
||||
<div className={classes.sizeFactorContainer}>
|
||||
<SelectWrapper
|
||||
label=" "
|
||||
id="quota_unit"
|
||||
name="quota_unit"
|
||||
value={quotaUnit}
|
||||
onChange={(
|
||||
e: React.ChangeEvent<{ value: unknown }>
|
||||
) => {
|
||||
addBucketQuotaUnit(e.target.value as string);
|
||||
}}
|
||||
options={factorForDropdown()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</Grid>
|
||||
</form>
|
||||
</ModalWrapper>
|
||||
);
|
||||
}
|
||||
}
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
<button
|
||||
type="button"
|
||||
color="primary"
|
||||
className={classes.clearButton}
|
||||
onClick={resetForm}
|
||||
>
|
||||
Clear
|
||||
</button>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={addLoading || !sendEnabled}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</Grid>
|
||||
{addLoading && (
|
||||
<Grid item xs={12}>
|
||||
<LinearProgress />
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
</form>
|
||||
</ModalWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(AddBucket);
|
||||
const mapState = (state: AppState) => ({
|
||||
addBucketModalOpen: state.buckets.open,
|
||||
bucketName: state.buckets.addBucketName,
|
||||
versioned: state.buckets.addBucketVersioning,
|
||||
enableQuota: state.buckets.addBucketQuotaEnabled,
|
||||
quotaType: state.buckets.addBucketQuotaType,
|
||||
quotaSize: state.buckets.addBucketQuotaSize,
|
||||
quotaUnit: state.buckets.addBucketQuotaUnit,
|
||||
});
|
||||
|
||||
const connector = connect(mapState, {
|
||||
addBucketName: addBucketName,
|
||||
addBucketVersioned: addBucketVersioned,
|
||||
addBucketQuota: addBucketQuota,
|
||||
addBucketQuotaType: addBucketQuotaType,
|
||||
addBucketQuotaSize: addBucketQuotaSize,
|
||||
addBucketQuotaUnit: addBucketQuotaUnit,
|
||||
});
|
||||
|
||||
export default connector(withStyles(styles)(AddBucket));
|
||||
|
||||
@@ -14,11 +14,10 @@
|
||||
// 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 React, { useEffect, useState } from "react";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import { Button } from "@material-ui/core";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import InputAdornment from "@material-ui/core/InputAdornment";
|
||||
import SearchIcon from "@material-ui/icons/Search";
|
||||
@@ -31,6 +30,15 @@ import DeleteBucket from "./DeleteBucket";
|
||||
import { MinTablePaginationActions } from "../../../../common/MinTablePaginationActions";
|
||||
import { CreateIcon } from "../../../../icons";
|
||||
import { niceBytes } from "../../../../common/utils";
|
||||
import { AppState } from "../../../../store";
|
||||
import { connect } from "react-redux";
|
||||
import { addBucketOpen, addBucketReset } from "../actions";
|
||||
import {
|
||||
actionsTray,
|
||||
containerForHeader,
|
||||
searchField,
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
import PageHeader from "../../Common/PageHeader/PageHeader";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
@@ -62,188 +70,156 @@ const styles = (theme: Theme) =>
|
||||
},
|
||||
},
|
||||
},
|
||||
actionsTray: {
|
||||
textAlign: "right",
|
||||
"& button": {
|
||||
marginLeft: 10,
|
||||
},
|
||||
},
|
||||
searchField: {
|
||||
background: "#FFFFFF",
|
||||
padding: 12,
|
||||
borderRadius: 5,
|
||||
boxShadow: "0px 3px 6px #00000012",
|
||||
},
|
||||
...actionsTray,
|
||||
...searchField,
|
||||
...containerForHeader(theme.spacing(4)),
|
||||
});
|
||||
|
||||
interface IListBucketsProps {
|
||||
classes: any;
|
||||
addBucketOpen: typeof addBucketOpen;
|
||||
addBucketModalOpen: boolean;
|
||||
addBucketReset: typeof addBucketReset;
|
||||
}
|
||||
|
||||
interface IListBucketsState {
|
||||
records: Bucket[];
|
||||
totalRecords: number;
|
||||
loading: boolean;
|
||||
error: string;
|
||||
deleteError: string;
|
||||
addScreenOpen: boolean;
|
||||
page: number;
|
||||
rowsPerPage: number;
|
||||
deleteOpen: boolean;
|
||||
selectedBucket: string;
|
||||
filterBuckets: string;
|
||||
}
|
||||
const ListBuckets = ({
|
||||
classes,
|
||||
addBucketOpen,
|
||||
addBucketModalOpen,
|
||||
addBucketReset,
|
||||
}: IListBucketsProps) => {
|
||||
const [records, setRecords] = useState<Bucket[]>([]);
|
||||
const [totalRecords, setTotalRecords] = useState<number>(0);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [error, setError] = useState<string>("");
|
||||
const [page, setPage] = useState<number>(0);
|
||||
const [rowsPerPage, setRowsPerPage] = useState<number>(10);
|
||||
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
|
||||
const [selectedBucket, setSelectedBucket] = useState<string>("");
|
||||
const [filterBuckets, setFilterBuckets] = useState<string>("");
|
||||
|
||||
class ListBuckets extends React.Component<
|
||||
IListBucketsProps,
|
||||
IListBucketsState
|
||||
> {
|
||||
state: IListBucketsState = {
|
||||
records: [],
|
||||
totalRecords: 0,
|
||||
loading: false,
|
||||
error: "",
|
||||
deleteError: "",
|
||||
addScreenOpen: false,
|
||||
page: 0,
|
||||
rowsPerPage: 10,
|
||||
deleteOpen: false,
|
||||
selectedBucket: "",
|
||||
filterBuckets: "",
|
||||
useEffect(() => {
|
||||
if (loading) {
|
||||
const fetchRecords = () => {
|
||||
setLoading(true);
|
||||
const offset = page * rowsPerPage;
|
||||
api
|
||||
.invoke(
|
||||
"GET",
|
||||
`/api/v1/buckets?offset=${offset}&limit=${rowsPerPage}`
|
||||
)
|
||||
.then((res: BucketList) => {
|
||||
setLoading(false);
|
||||
setRecords(res.buckets || []);
|
||||
setTotalRecords(!res.buckets ? 0 : res.total);
|
||||
setError("");
|
||||
// if we get 0 results, and page > 0 , go down 1 page
|
||||
if (
|
||||
(res.buckets === undefined ||
|
||||
res.buckets == null ||
|
||||
res.buckets.length === 0) &&
|
||||
page > 0
|
||||
) {
|
||||
const newPage = page - 1;
|
||||
setPage(newPage);
|
||||
setLoading(true);
|
||||
}
|
||||
})
|
||||
.catch((err: any) => {
|
||||
setLoading(false);
|
||||
setError(err);
|
||||
});
|
||||
};
|
||||
fetchRecords();
|
||||
}
|
||||
}, [loading, page, rowsPerPage]);
|
||||
|
||||
const closeAddModalAndRefresh = (refresh: boolean) => {
|
||||
addBucketOpen(false);
|
||||
addBucketReset();
|
||||
|
||||
if (refresh) {
|
||||
setLoading(true);
|
||||
}
|
||||
};
|
||||
|
||||
fetchRecords() {
|
||||
this.setState({ loading: true }, () => {
|
||||
const { page, rowsPerPage } = this.state;
|
||||
const offset = page * rowsPerPage;
|
||||
api
|
||||
.invoke("GET", `/api/v1/buckets?offset=${offset}&limit=${rowsPerPage}`)
|
||||
.then((res: BucketList) => {
|
||||
this.setState({
|
||||
loading: false,
|
||||
records: res.buckets || [],
|
||||
totalRecords: !res.buckets ? 0 : res.total,
|
||||
error: "",
|
||||
});
|
||||
// if we get 0 results, and page > 0 , go down 1 page
|
||||
if (
|
||||
(res.buckets === undefined ||
|
||||
res.buckets == null ||
|
||||
res.buckets.length === 0) &&
|
||||
page > 0
|
||||
) {
|
||||
const newPage = page - 1;
|
||||
this.setState({ page: newPage }, () => {
|
||||
this.fetchRecords();
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((err: any) => {
|
||||
this.setState({ loading: false, error: err });
|
||||
});
|
||||
});
|
||||
}
|
||||
const closeDeleteModalAndRefresh = (refresh: boolean) => {
|
||||
setDeleteOpen(false);
|
||||
if (refresh) {
|
||||
setLoading(true);
|
||||
}
|
||||
};
|
||||
|
||||
closeAddModalAndRefresh() {
|
||||
this.setState({ addScreenOpen: false }, () => {
|
||||
this.fetchRecords();
|
||||
});
|
||||
}
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
}, []);
|
||||
|
||||
closeDeleteModalAndRefresh(refresh: boolean) {
|
||||
this.setState({ deleteOpen: false }, () => {
|
||||
if (refresh) {
|
||||
this.fetchRecords();
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
}, [page, rowsPerPage]);
|
||||
|
||||
const confirmDeleteBucket = (bucket: string) => {
|
||||
setDeleteOpen(true);
|
||||
setSelectedBucket(bucket);
|
||||
};
|
||||
|
||||
const handleChangePage = (event: unknown, newPage: number) => {
|
||||
setPage(newPage);
|
||||
};
|
||||
|
||||
const handleChangeRowsPerPage = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
const rPP = parseInt(event.target.value, 10);
|
||||
setPage(0);
|
||||
setRowsPerPage(rPP);
|
||||
};
|
||||
const tableActions = [
|
||||
{ type: "view", to: `/buckets`, sendOnlyId: true },
|
||||
{ type: "delete", onClick: confirmDeleteBucket, sendOnlyId: true },
|
||||
];
|
||||
|
||||
const offset = page * rowsPerPage;
|
||||
|
||||
const displayParsedDate = (date: string) => {
|
||||
return <Moment>{date}</Moment>;
|
||||
};
|
||||
|
||||
const filteredRecords = records.filter((b: Bucket) => {
|
||||
if (filterBuckets === "") {
|
||||
return true;
|
||||
} else {
|
||||
if (b.name.indexOf(filterBuckets) >= 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
componentDidMount(): void {
|
||||
this.fetchRecords();
|
||||
}
|
||||
const showInPage = filteredRecords.slice(offset, offset + rowsPerPage);
|
||||
|
||||
bucketFilter(): void {}
|
||||
|
||||
render() {
|
||||
const { classes } = this.props;
|
||||
const {
|
||||
records,
|
||||
totalRecords,
|
||||
addScreenOpen,
|
||||
loading,
|
||||
page,
|
||||
rowsPerPage,
|
||||
deleteOpen,
|
||||
selectedBucket,
|
||||
filterBuckets,
|
||||
} = this.state;
|
||||
|
||||
const offset = page * rowsPerPage;
|
||||
|
||||
const handleChangePage = (event: unknown, newPage: number) => {
|
||||
this.setState({ page: newPage });
|
||||
};
|
||||
|
||||
const handleChangeRowsPerPage = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
const rPP = parseInt(event.target.value, 10);
|
||||
this.setState({ page: 0, rowsPerPage: rPP });
|
||||
};
|
||||
|
||||
const confirmDeleteBucket = (bucket: string) => {
|
||||
this.setState({ deleteOpen: true, selectedBucket: bucket });
|
||||
};
|
||||
|
||||
const tableActions = [
|
||||
{ type: "view", to: `/buckets`, sendOnlyId: true },
|
||||
{ type: "delete", onClick: confirmDeleteBucket, sendOnlyId: true },
|
||||
];
|
||||
|
||||
const displayParsedDate = (date: string) => {
|
||||
return <Moment>{date}</Moment>;
|
||||
};
|
||||
|
||||
const filteredRecords = records
|
||||
.slice(offset, offset + rowsPerPage)
|
||||
.filter((b: Bucket) => {
|
||||
if (filterBuckets === "") {
|
||||
return true;
|
||||
} else {
|
||||
if (b.name.indexOf(filterBuckets) >= 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{addScreenOpen && (
|
||||
<AddBucket
|
||||
open={addScreenOpen}
|
||||
closeModalAndRefresh={() => {
|
||||
this.closeAddModalAndRefresh();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{deleteOpen && (
|
||||
<DeleteBucket
|
||||
deleteOpen={deleteOpen}
|
||||
selectedBucket={selectedBucket}
|
||||
closeDeleteModalAndRefresh={(refresh: boolean) => {
|
||||
this.closeDeleteModalAndRefresh(refresh);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Grid container>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="h6">Buckets</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<br />
|
||||
</Grid>
|
||||
return (
|
||||
<React.Fragment>
|
||||
{addBucketModalOpen && (
|
||||
<AddBucket
|
||||
open={addBucketModalOpen}
|
||||
closeModalAndRefresh={closeAddModalAndRefresh}
|
||||
/>
|
||||
)}
|
||||
{deleteOpen && (
|
||||
<DeleteBucket
|
||||
deleteOpen={deleteOpen}
|
||||
selectedBucket={selectedBucket}
|
||||
closeDeleteModalAndRefresh={(refresh: boolean) => {
|
||||
closeDeleteModalAndRefresh(refresh);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<PageHeader label={"Buckets"} />
|
||||
<Grid container>
|
||||
{error !== "" && <span className={classes.error}>{error}</span>}
|
||||
<Grid item xs={12} className={classes.container}>
|
||||
<Grid item xs={12} className={classes.actionsTray}>
|
||||
<TextField
|
||||
placeholder="Search Buckets"
|
||||
@@ -251,9 +227,7 @@ class ListBuckets extends React.Component<
|
||||
id="search-resource"
|
||||
label=""
|
||||
onChange={(val) => {
|
||||
this.setState({
|
||||
filterBuckets: val.target.value,
|
||||
});
|
||||
setFilterBuckets(val.target.value);
|
||||
}}
|
||||
InputProps={{
|
||||
disableUnderline: true,
|
||||
@@ -269,9 +243,7 @@ class ListBuckets extends React.Component<
|
||||
color="primary"
|
||||
startIcon={<CreateIcon />}
|
||||
onClick={() => {
|
||||
this.setState({
|
||||
addScreenOpen: true,
|
||||
});
|
||||
addBucketOpen(true);
|
||||
}}
|
||||
>
|
||||
Create Bucket
|
||||
@@ -297,13 +269,13 @@ class ListBuckets extends React.Component<
|
||||
},
|
||||
]}
|
||||
isLoading={loading}
|
||||
records={filteredRecords}
|
||||
records={showInPage}
|
||||
entityName="Buckets"
|
||||
idField="name"
|
||||
paginatorConfig={{
|
||||
rowsPerPageOptions: [5, 10, 25],
|
||||
colSpan: 3,
|
||||
count: totalRecords,
|
||||
count: filteredRecords.length,
|
||||
rowsPerPage: rowsPerPage,
|
||||
page: page,
|
||||
SelectProps: {
|
||||
@@ -317,9 +289,18 @@ class ListBuckets extends React.Component<
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(ListBuckets);
|
||||
const mapState = (state: AppState) => ({
|
||||
addBucketModalOpen: state.buckets.open,
|
||||
});
|
||||
|
||||
const connector = connect(mapState, {
|
||||
addBucketOpen: addBucketOpen,
|
||||
addBucketReset: addBucketReset,
|
||||
});
|
||||
|
||||
export default connector(withStyles(styles)(ListBuckets));
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 ModalWrapper from "../../../../Common/ModalWrapper/ModalWrapper";
|
||||
import { Button, Grid, LinearProgress } from "@material-ui/core";
|
||||
import InputBoxWrapper from "../../../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import { modalBasic } from "../../../../Common/FormComponents/common/styleLibrary";
|
||||
import { connect } from "react-redux";
|
||||
import { createFolder } from "../../../../ObjectBrowser/actions";
|
||||
|
||||
interface ICreateFolder {
|
||||
classes: any;
|
||||
modalOpen: boolean;
|
||||
folderName: string;
|
||||
createFolder: (newFolder: string) => any;
|
||||
onClose: () => any;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
buttonContainer: {
|
||||
textAlign: "right",
|
||||
},
|
||||
pathLabel: {
|
||||
marginTop: 0,
|
||||
marginBottom: 32,
|
||||
},
|
||||
...modalBasic,
|
||||
});
|
||||
|
||||
const CreateFolderModal = ({
|
||||
modalOpen,
|
||||
folderName,
|
||||
onClose,
|
||||
createFolder,
|
||||
classes,
|
||||
}: ICreateFolder) => {
|
||||
const [pathUrl, setPathUrl] = useState("");
|
||||
|
||||
const resetForm = () => {
|
||||
setPathUrl("");
|
||||
};
|
||||
|
||||
const createProcess = () => {
|
||||
createFolder(pathUrl);
|
||||
onClose();
|
||||
};
|
||||
|
||||
const folderTruncated = folderName.split("/").slice(2).join("/");
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<ModalWrapper modalOpen={modalOpen} title="Add Folder" onClose={onClose}>
|
||||
<Grid container>
|
||||
<h3 className={classes.pathLabel}>
|
||||
Current Path: {folderTruncated}/
|
||||
</h3>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
value={pathUrl}
|
||||
label={"Folder Path"}
|
||||
id={"folderPath"}
|
||||
name={"folderPath"}
|
||||
placeholder={"Enter Folder Path"}
|
||||
onChange={(e) => {
|
||||
setPathUrl(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
<button
|
||||
type="button"
|
||||
color="primary"
|
||||
className={classes.clearButton}
|
||||
onClick={resetForm}
|
||||
>
|
||||
Clear
|
||||
</button>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={pathUrl.trim() === ""}
|
||||
onClick={createProcess}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ModalWrapper>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const mapDispatchToProps = {
|
||||
createFolder,
|
||||
};
|
||||
|
||||
const connector = connect(null, mapDispatchToProps);
|
||||
|
||||
export default connector(withStyles(styles)(CreateFolderModal));
|
||||
@@ -0,0 +1,160 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import React from "react";
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogContentText,
|
||||
DialogTitle,
|
||||
LinearProgress,
|
||||
} from "@material-ui/core";
|
||||
import api from "../../../../../../common/api";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
errorBlock: {
|
||||
color: "red",
|
||||
},
|
||||
});
|
||||
|
||||
interface IDeleteObjectProps {
|
||||
classes: any;
|
||||
closeDeleteModalAndRefresh: (refresh: boolean) => void;
|
||||
deleteOpen: boolean;
|
||||
selectedObject: string;
|
||||
selectedBucket: string;
|
||||
}
|
||||
|
||||
interface IDeleteObjectState {
|
||||
deleteLoading: boolean;
|
||||
deleteError: string;
|
||||
}
|
||||
|
||||
class DeleteObject extends React.Component<
|
||||
IDeleteObjectProps,
|
||||
IDeleteObjectState
|
||||
> {
|
||||
state: IDeleteObjectState = {
|
||||
deleteLoading: false,
|
||||
deleteError: "",
|
||||
};
|
||||
|
||||
removeRecord() {
|
||||
const { deleteLoading } = this.state;
|
||||
const { selectedObject, selectedBucket } = this.props;
|
||||
if (deleteLoading) {
|
||||
return;
|
||||
}
|
||||
var recursive = false;
|
||||
if (selectedObject.endsWith("/")) {
|
||||
recursive = true;
|
||||
}
|
||||
|
||||
this.setState({ deleteLoading: true }, () => {
|
||||
api
|
||||
.invoke(
|
||||
"DELETE",
|
||||
`/api/v1/buckets/${selectedBucket}/objects?path=${selectedObject}&recursive=${recursive}`
|
||||
)
|
||||
.then((res: any) => {
|
||||
this.setState(
|
||||
{
|
||||
deleteLoading: false,
|
||||
deleteError: "",
|
||||
},
|
||||
() => {
|
||||
this.props.closeDeleteModalAndRefresh(true);
|
||||
}
|
||||
);
|
||||
})
|
||||
.catch((err) => {
|
||||
this.setState({
|
||||
deleteLoading: false,
|
||||
deleteError: err,
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { classes, deleteOpen, selectedObject } = this.props;
|
||||
const { deleteLoading, deleteError } = this.state;
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={deleteOpen}
|
||||
onClose={() => {
|
||||
this.setState({ deleteError: "" }, () => {
|
||||
this.props.closeDeleteModalAndRefresh(false);
|
||||
});
|
||||
}}
|
||||
aria-labelledby="alert-dialog-title"
|
||||
aria-describedby="alert-dialog-description"
|
||||
>
|
||||
<DialogTitle id="alert-dialog-title">Delete</DialogTitle>
|
||||
<DialogContent>
|
||||
{deleteLoading && <LinearProgress />}
|
||||
<DialogContentText id="alert-dialog-description">
|
||||
Are you sure you want to delete: <b>{selectedObject}</b>?{" "}
|
||||
{deleteError !== "" && (
|
||||
<React.Fragment>
|
||||
<br />
|
||||
<Typography
|
||||
component="p"
|
||||
variant="body1"
|
||||
className={classes.errorBlock}
|
||||
>
|
||||
{deleteError}
|
||||
</Typography>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={() => {
|
||||
this.setState({ deleteError: "" }, () => {
|
||||
this.props.closeDeleteModalAndRefresh(false);
|
||||
});
|
||||
}}
|
||||
color="primary"
|
||||
disabled={deleteLoading}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
this.setState({ deleteError: "" }, () => {
|
||||
this.removeRecord();
|
||||
});
|
||||
}}
|
||||
color="secondary"
|
||||
disabled={deleteLoading}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withStyles(styles)(DeleteObject);
|
||||
@@ -0,0 +1,514 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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, useEffect } from "react";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import InputAdornment from "@material-ui/core/InputAdornment";
|
||||
import SearchIcon from "@material-ui/icons/Search";
|
||||
import { BucketObject, BucketObjectsList } from "./types";
|
||||
import api from "../../../../../../common/api";
|
||||
import TableWrapper from "../../../../Common/TableWrapper/TableWrapper";
|
||||
import { niceBytes } from "../../../../../../common/utils";
|
||||
import DeleteObject from "./DeleteObject";
|
||||
|
||||
import {
|
||||
actionsTray,
|
||||
containerForHeader,
|
||||
objectBrowserCommon,
|
||||
searchField,
|
||||
} from "../../../../Common/FormComponents/common/styleLibrary";
|
||||
import PageHeader from "../../../../Common/PageHeader/PageHeader";
|
||||
import storage from "local-storage-fallback";
|
||||
import { isNullOrUndefined } from "util";
|
||||
import { Button, Input } from "@material-ui/core";
|
||||
import * as reactMoment from "react-moment";
|
||||
import { CreateIcon } from "../../../../../../icons";
|
||||
import Snackbar from "@material-ui/core/Snackbar";
|
||||
import BrowserBreadcrumbs from "../../../../ObjectBrowser/BrowserBreadcrumbs";
|
||||
import get from "lodash/get";
|
||||
import { withRouter } from "react-router-dom";
|
||||
import { addRoute, setAllRoutes } from "../../../../ObjectBrowser/actions";
|
||||
import { connect } from "react-redux";
|
||||
import { ObjectBrowserState, Route } from "../../../../ObjectBrowser/reducers";
|
||||
import CreateFolderModal from "./CreateFolderModal";
|
||||
import { create } from "domain";
|
||||
import UploadFile from "../../../../../../icons/UploadFile";
|
||||
|
||||
const commonIcon = {
|
||||
backgroundRepeat: "no-repeat",
|
||||
backgroundPosition: "center center",
|
||||
width: 16,
|
||||
height: 40,
|
||||
marginRight: 10,
|
||||
};
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
seeMore: {
|
||||
marginTop: theme.spacing(3),
|
||||
},
|
||||
paper: {
|
||||
display: "flex",
|
||||
overflow: "auto",
|
||||
flexDirection: "column",
|
||||
},
|
||||
|
||||
addSideBar: {
|
||||
width: "320px",
|
||||
padding: "20px",
|
||||
},
|
||||
errorBlock: {
|
||||
color: "red",
|
||||
},
|
||||
tableToolbar: {
|
||||
paddingLeft: theme.spacing(2),
|
||||
paddingRight: theme.spacing(0),
|
||||
},
|
||||
minTableHeader: {
|
||||
color: "#393939",
|
||||
"& tr": {
|
||||
"& th": {
|
||||
fontWeight: "bold",
|
||||
},
|
||||
},
|
||||
},
|
||||
fileName: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
},
|
||||
iconFolder: {
|
||||
backgroundImage: "url(/images/ob_folder_clear.svg)",
|
||||
...commonIcon,
|
||||
},
|
||||
iconFile: {
|
||||
backgroundImage: "url(/images/ob_file_clear.svg)",
|
||||
...commonIcon,
|
||||
},
|
||||
buttonsContainer: {
|
||||
"& .MuiButtonBase-root": {
|
||||
marginLeft: 10,
|
||||
},
|
||||
},
|
||||
"@global": {
|
||||
".rowElementRaw:hover .iconFileElm": {
|
||||
backgroundImage: "url(/images/ob_file_filled.svg)",
|
||||
},
|
||||
".rowElementRaw:hover .iconFolderElm": {
|
||||
backgroundImage: "url(/images/ob_folder_filled.svg)",
|
||||
},
|
||||
},
|
||||
...actionsTray,
|
||||
...searchField,
|
||||
...objectBrowserCommon,
|
||||
...containerForHeader(theme.spacing(4)),
|
||||
});
|
||||
|
||||
interface IListObjectsProps {
|
||||
classes: any;
|
||||
match: any;
|
||||
addRoute: (param1: string, param2: string) => any;
|
||||
setAllRoutes: (path: string) => any;
|
||||
routesList: Route[];
|
||||
}
|
||||
|
||||
interface ObjectBrowserReducer {
|
||||
objectBrowser: ObjectBrowserState;
|
||||
}
|
||||
|
||||
const ListObjects = ({
|
||||
classes,
|
||||
match,
|
||||
addRoute,
|
||||
setAllRoutes,
|
||||
routesList,
|
||||
}: IListObjectsProps) => {
|
||||
const [records, setRecords] = useState<BucketObject[]>([]);
|
||||
const [totalRecords, setTotalRecords] = useState<number>(0);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [error, setError] = useState<string>("");
|
||||
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
|
||||
const [createFolderOpen, setCreateFolderOpen] = useState<boolean>(false);
|
||||
const [deleteError, setDeleteError] = useState<string>("");
|
||||
const [selectedObject, setSelectedObject] = useState<string>("");
|
||||
const [selectedBucket, setSelectedBucket] = useState<string>("");
|
||||
const [filterObjects, setFilterObjects] = useState<string>("");
|
||||
const [openSnackbar, setOpenSnackbar] = useState<boolean>(false);
|
||||
const [snackBarMessage, setSnackbarMessage] = useState<string>("");
|
||||
|
||||
useEffect(() => {
|
||||
const bucketName = match.params["bucket"];
|
||||
const internalPaths = match.params[0];
|
||||
|
||||
let extraPath = "";
|
||||
if (internalPaths) {
|
||||
extraPath = `?prefix=${internalPaths}/`;
|
||||
}
|
||||
|
||||
api
|
||||
.invoke("GET", `/api/v1/buckets/${bucketName}/objects${extraPath}`)
|
||||
.then((res: BucketObjectsList) => {
|
||||
setLoading(false);
|
||||
setSelectedBucket(bucketName);
|
||||
setRecords(res.objects || []);
|
||||
setTotalRecords(!res.objects ? 0 : res.total);
|
||||
setError("");
|
||||
// TODO:
|
||||
// if we get 0 results, and page > 0 , go down 1 page
|
||||
})
|
||||
.catch((err: any) => {
|
||||
setLoading(false);
|
||||
setError(err);
|
||||
});
|
||||
}, [loading, match]);
|
||||
|
||||
useEffect(() => {
|
||||
const url = get(match, "url", "/object-browser");
|
||||
if (url !== routesList[routesList.length - 1].route) {
|
||||
setAllRoutes(url);
|
||||
}
|
||||
}, [match, routesList, setAllRoutes]);
|
||||
|
||||
const closeDeleteModalAndRefresh = (refresh: boolean) => {
|
||||
setDeleteOpen(false);
|
||||
|
||||
if (refresh) {
|
||||
setLoading(true);
|
||||
}
|
||||
};
|
||||
|
||||
const closeAddFolderModal = () => {
|
||||
setCreateFolderOpen(false);
|
||||
};
|
||||
|
||||
const showSnackBarMessage = (text: string) => {
|
||||
setSnackbarMessage(text);
|
||||
setOpenSnackbar(true);
|
||||
};
|
||||
|
||||
const closeSnackBar = () => {
|
||||
setSnackbarMessage("");
|
||||
setOpenSnackbar(false);
|
||||
};
|
||||
|
||||
const upload = (e: any, bucketName: string, path: string) => {
|
||||
if (isNullOrUndefined(e) || isNullOrUndefined(e.target)) {
|
||||
return;
|
||||
}
|
||||
const token: string = storage.getItem("token")!;
|
||||
e.preventDefault();
|
||||
let file = e.target.files[0];
|
||||
const fileName = file.name;
|
||||
|
||||
const objectName = `${path}${fileName}`;
|
||||
let uploadUrl = `/api/v1/buckets/${bucketName}/objects/upload?prefix=${objectName}`;
|
||||
let xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.open("POST", uploadUrl, true);
|
||||
xhr.setRequestHeader("Authorization", `Bearer ${token}`);
|
||||
|
||||
xhr.withCredentials = false;
|
||||
xhr.onload = function (event) {
|
||||
// TODO: handle status
|
||||
if (xhr.status === 401 || xhr.status === 403) {
|
||||
showSnackBarMessage("An error occurred while uploading the file.");
|
||||
}
|
||||
if (xhr.status === 500) {
|
||||
showSnackBarMessage("An error occurred while uploading the file.");
|
||||
}
|
||||
if (xhr.status === 200) {
|
||||
showSnackBarMessage("Object uploaded successfully.");
|
||||
setLoading(true);
|
||||
}
|
||||
};
|
||||
|
||||
xhr.upload.addEventListener("error", (event) => {
|
||||
// TODO: handle error
|
||||
showSnackBarMessage("An error occurred while uploading the file.");
|
||||
});
|
||||
|
||||
xhr.upload.addEventListener("progress", (event) => {
|
||||
// TODO: handle progress with event.loaded, event.total
|
||||
});
|
||||
|
||||
xhr.onerror = () => {
|
||||
showSnackBarMessage("An error occurred while uploading the file.");
|
||||
};
|
||||
|
||||
const formData = new FormData();
|
||||
const blobFile = new Blob([file]);
|
||||
|
||||
formData.append("upfile", blobFile);
|
||||
xhr.send(formData);
|
||||
e.target.value = null;
|
||||
};
|
||||
|
||||
const download = (bucketName: string, objectName: string) => {
|
||||
const anchor = document.createElement("a");
|
||||
document.body.appendChild(anchor);
|
||||
const token: string = storage.getItem("token")!;
|
||||
const xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.open(
|
||||
"GET",
|
||||
`/api/v1/buckets/${bucketName}/objects/download?prefix=${objectName}`,
|
||||
true
|
||||
);
|
||||
xhr.setRequestHeader("Authorization", `Bearer ${token}`);
|
||||
xhr.responseType = "blob";
|
||||
|
||||
xhr.onload = function (e) {
|
||||
if (this.status === 200) {
|
||||
const blob = new Blob([this.response], {
|
||||
type: "octet/stream",
|
||||
});
|
||||
const blobUrl = window.URL.createObjectURL(blob);
|
||||
|
||||
anchor.href = blobUrl;
|
||||
anchor.download = objectName;
|
||||
|
||||
anchor.click();
|
||||
window.URL.revokeObjectURL(blobUrl);
|
||||
anchor.remove();
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
};
|
||||
|
||||
const displayParsedDate = (date: string) => {
|
||||
return <reactMoment.default>{date}</reactMoment.default>;
|
||||
};
|
||||
|
||||
const confirmDeleteObject = (object: string) => {
|
||||
setDeleteOpen(true);
|
||||
setSelectedObject(object);
|
||||
};
|
||||
|
||||
const downloadObject = (object: string) => {
|
||||
download(selectedBucket, object);
|
||||
};
|
||||
|
||||
const openPath = (idElement: string) => {
|
||||
const currentPath = get(match, "url", "/object-browser");
|
||||
|
||||
// Element is a folder, we redirect to it
|
||||
if (idElement.endsWith("/")) {
|
||||
const idElementClean = idElement
|
||||
.substr(0, idElement.length - 1)
|
||||
.split("/");
|
||||
const lastIndex = idElementClean.length - 1;
|
||||
const newPath = `${currentPath}/${idElementClean[lastIndex]}`;
|
||||
|
||||
addRoute(newPath, idElementClean[lastIndex]);
|
||||
return;
|
||||
}
|
||||
|
||||
// Element is a file. we open details here
|
||||
// TODO: Add details open function here.
|
||||
//console.log("object", idElementClean);
|
||||
};
|
||||
|
||||
const uploadObject = (e: any): void => {
|
||||
// Handle of deeper routes.
|
||||
const currentPath = routesList[routesList.length - 1].route;
|
||||
const splitPaths = currentPath
|
||||
.split("/")
|
||||
.filter((item) => item.trim() !== "");
|
||||
|
||||
let path = "";
|
||||
|
||||
if (splitPaths.length > 2) {
|
||||
path = `${splitPaths.slice(2).join("/")}/`;
|
||||
}
|
||||
|
||||
let file = e.target.files[0];
|
||||
showSnackBarMessage(`Uploading: ${file.name}`);
|
||||
upload(e, selectedBucket, path);
|
||||
};
|
||||
|
||||
const snackBarAction = (
|
||||
<Button
|
||||
color="secondary"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
closeSnackBar();
|
||||
}}
|
||||
>
|
||||
Dismiss
|
||||
</Button>
|
||||
);
|
||||
|
||||
const tableActions = [
|
||||
{ type: "view", onClick: openPath, sendOnlyId: true },
|
||||
{ type: "download", onClick: downloadObject, sendOnlyId: true },
|
||||
{ type: "delete", onClick: confirmDeleteObject, sendOnlyId: true },
|
||||
];
|
||||
|
||||
const displayName = (element: string) => {
|
||||
let elementString = element;
|
||||
let icon = `${classes.iconFile} iconFileElm`;
|
||||
// Element is a folder
|
||||
if (element.endsWith("/")) {
|
||||
icon = `${classes.iconFolder} iconFolderElm`;
|
||||
elementString = element.substr(0, element.length - 1);
|
||||
}
|
||||
|
||||
const splitItem = elementString.split("/");
|
||||
|
||||
return (
|
||||
<div className={classes.fileName}>
|
||||
<div className={icon} />
|
||||
<span>{splitItem[splitItem.length - 1]}</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const filteredRecords = records.filter((b: BucketObject) => {
|
||||
if (filterObjects === "") {
|
||||
return true;
|
||||
} else {
|
||||
if (b.name.indexOf(filterObjects) >= 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{deleteOpen && (
|
||||
<DeleteObject
|
||||
deleteOpen={deleteOpen}
|
||||
selectedBucket={selectedBucket}
|
||||
selectedObject={selectedObject}
|
||||
closeDeleteModalAndRefresh={closeDeleteModalAndRefresh}
|
||||
/>
|
||||
)}
|
||||
{createFolderOpen && (
|
||||
<CreateFolderModal
|
||||
modalOpen={createFolderOpen}
|
||||
folderName={routesList[routesList.length - 1].route}
|
||||
onClose={closeAddFolderModal}
|
||||
/>
|
||||
)}
|
||||
<Snackbar
|
||||
open={openSnackbar}
|
||||
message={snackBarMessage}
|
||||
action={snackBarAction}
|
||||
/>
|
||||
<PageHeader label="Object Browser" />
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.container}>
|
||||
<Grid item xs={12} className={classes.obTitleSection}>
|
||||
<div>
|
||||
<BrowserBreadcrumbs />
|
||||
</div>
|
||||
<div className={classes.buttonsContainer}>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
startIcon={<CreateIcon />}
|
||||
component="label"
|
||||
onClick={() => {
|
||||
setCreateFolderOpen(true);
|
||||
}}
|
||||
>
|
||||
Create Folder
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
startIcon={<UploadFile />}
|
||||
component="label"
|
||||
>
|
||||
File
|
||||
<Input
|
||||
type="file"
|
||||
onChange={(e) => uploadObject(e)}
|
||||
id="file-input"
|
||||
style={{ display: "none" }}
|
||||
/>
|
||||
</Button>
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.actionsTray}>
|
||||
<TextField
|
||||
placeholder="Search Objects"
|
||||
className={classes.searchField}
|
||||
id="search-resource"
|
||||
label=""
|
||||
onChange={(val) => {
|
||||
setFilterObjects(val.target.value);
|
||||
}}
|
||||
InputProps={{
|
||||
disableUnderline: true,
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<SearchIcon />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<br />
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<TableWrapper
|
||||
itemActions={tableActions}
|
||||
columns={[
|
||||
{
|
||||
label: "Name",
|
||||
elementKey: "name",
|
||||
renderFunction: displayName,
|
||||
},
|
||||
{
|
||||
label: "Last Modified",
|
||||
elementKey: "last_modified",
|
||||
renderFunction: displayParsedDate,
|
||||
},
|
||||
{
|
||||
label: "Size",
|
||||
elementKey: "size",
|
||||
renderFunction: niceBytes,
|
||||
},
|
||||
]}
|
||||
isLoading={loading}
|
||||
entityName="Objects"
|
||||
idField="name"
|
||||
records={filteredRecords}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const mapStateToProps = ({ objectBrowser }: ObjectBrowserReducer) => ({
|
||||
routesList: get(objectBrowser, "routesList", []),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = {
|
||||
addRoute,
|
||||
setAllRoutes,
|
||||
};
|
||||
|
||||
const connector = connect(mapStateToProps, mapDispatchToProps);
|
||||
|
||||
export default withRouter(connector(withStyles(styles)(ListObjects)));
|
||||
@@ -0,0 +1,27 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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/>.
|
||||
|
||||
export interface BucketObject {
|
||||
name: string;
|
||||
size: number;
|
||||
last_modified: Date;
|
||||
content_type: string;
|
||||
}
|
||||
|
||||
export interface BucketObjectsList {
|
||||
objects: BucketObject[];
|
||||
total: number;
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 get from "lodash/get";
|
||||
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import { modalBasic } from "../../Common/FormComponents/common/styleLibrary";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||
import { Button, LinearProgress } from "@material-ui/core";
|
||||
import api from "../../../../common/api";
|
||||
import { IRemoteBucket } from "../types";
|
||||
|
||||
interface IReplicationModal {
|
||||
open: boolean;
|
||||
closeModalAndRefresh: () => any;
|
||||
classes: any;
|
||||
bucketName: string;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
errorBlock: {
|
||||
color: "red",
|
||||
},
|
||||
minTableHeader: {
|
||||
color: "#393939",
|
||||
"& tr": {
|
||||
"& th": {
|
||||
fontWeight: "bold",
|
||||
},
|
||||
},
|
||||
},
|
||||
buttonContainer: {
|
||||
textAlign: "right",
|
||||
},
|
||||
...modalBasic,
|
||||
});
|
||||
|
||||
const AddReplicationModal = ({
|
||||
open,
|
||||
closeModalAndRefresh,
|
||||
classes,
|
||||
bucketName,
|
||||
}: IReplicationModal) => {
|
||||
const [addError, setAddError] = useState("");
|
||||
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 addRecord = () => {
|
||||
const remoteBucketInfo = {
|
||||
accessKey: accessKey,
|
||||
secretKey: secretKey,
|
||||
sourceBucket: bucketName,
|
||||
targetURL: targetURL,
|
||||
targetBucket: targetBucket,
|
||||
region: region,
|
||||
};
|
||||
|
||||
api
|
||||
.invoke("POST", "/api/v1/remote-buckets", remoteBucketInfo)
|
||||
.then(() => {
|
||||
api
|
||||
.invoke("GET", "/api/v1/remote-buckets")
|
||||
.then((res: any) => {
|
||||
const remoteBuckets = get(res, "buckets", []);
|
||||
const remoteBucket = remoteBuckets.find(
|
||||
(itemRemote: IRemoteBucket) => {
|
||||
return itemRemote.sourceBucket === bucketName;
|
||||
}
|
||||
);
|
||||
if (remoteBucket && remoteBucket.remoteARN) {
|
||||
const remoteARN = remoteBucket.remoteARN;
|
||||
const replicationInfo = {
|
||||
destination_bucket: targetBucket,
|
||||
arn: remoteARN,
|
||||
};
|
||||
api
|
||||
.invoke(
|
||||
"POST",
|
||||
`/api/v1/buckets/${bucketName}/replication`,
|
||||
replicationInfo
|
||||
)
|
||||
.then(() => {
|
||||
setAddLoading(false);
|
||||
setAddError("");
|
||||
closeModalAndRefresh();
|
||||
})
|
||||
.catch((err) => {
|
||||
setAddLoading(false);
|
||||
setAddError(err);
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
setAddError(err);
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
setAddLoading(false);
|
||||
setAddError(err);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<ModalWrapper
|
||||
modalOpen={open}
|
||||
onClose={() => {
|
||||
setAddError("");
|
||||
closeModalAndRefresh();
|
||||
}}
|
||||
title="Set Bucket Replication"
|
||||
>
|
||||
<form
|
||||
noValidate
|
||||
autoComplete="off"
|
||||
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
setAddLoading(true);
|
||||
addRecord();
|
||||
}}
|
||||
>
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.formScrollable}>
|
||||
{addError !== "" && (
|
||||
<Grid item xs={12}>
|
||||
<Typography
|
||||
component="p"
|
||||
variant="body1"
|
||||
className={classes.errorBlock}
|
||||
>
|
||||
{addError}
|
||||
</Typography>
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="target"
|
||||
name="target"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setAccessKey(e.target.value);
|
||||
}}
|
||||
label="Access Key"
|
||||
value={accessKey}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="target"
|
||||
name="target"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setSecretKey(e.target.value);
|
||||
}}
|
||||
label="Secret Key"
|
||||
value={secretKey}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="target"
|
||||
name="target"
|
||||
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="target"
|
||||
name="target"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setTargetBucket(e.target.value);
|
||||
}}
|
||||
label="Target Bucket"
|
||||
value={targetBucket}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="target"
|
||||
name="target"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setRegion(e.target.value);
|
||||
}}
|
||||
label="Region"
|
||||
value={region}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={addLoading}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</Grid>
|
||||
{addLoading && (
|
||||
<Grid item xs={12}>
|
||||
<LinearProgress />
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
</form>
|
||||
</ModalWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(AddReplicationModal);
|
||||
@@ -0,0 +1,199 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 Grid from "@material-ui/core/Grid";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import { Button, LinearProgress } from "@material-ui/core";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import api from "../../../../common/api";
|
||||
import { modalBasic } from "../../Common/FormComponents/common/styleLibrary";
|
||||
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
|
||||
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
errorBlock: {
|
||||
color: "red",
|
||||
},
|
||||
minTableHeader: {
|
||||
color: "#393939",
|
||||
"& tr": {
|
||||
"& th": {
|
||||
fontWeight: "bold",
|
||||
},
|
||||
},
|
||||
},
|
||||
buttonContainer: {
|
||||
textAlign: "right",
|
||||
},
|
||||
...modalBasic,
|
||||
});
|
||||
|
||||
interface IEnableBucketEncryptionProps {
|
||||
classes: any;
|
||||
open: boolean;
|
||||
selectedBucket: string;
|
||||
closeModalAndRefresh: () => void;
|
||||
}
|
||||
|
||||
interface IEnableBucketEncryptionState {
|
||||
loading: boolean;
|
||||
encryptionError: string;
|
||||
kmsKeyID: string;
|
||||
suffix: string;
|
||||
encryptionType: string;
|
||||
}
|
||||
|
||||
class EnableBucketEncryption extends React.Component<
|
||||
IEnableBucketEncryptionProps,
|
||||
IEnableBucketEncryptionState
|
||||
> {
|
||||
state: IEnableBucketEncryptionState = {
|
||||
loading: false,
|
||||
encryptionError: "",
|
||||
kmsKeyID: "",
|
||||
suffix: "",
|
||||
encryptionType: "sse-s3",
|
||||
};
|
||||
|
||||
enableBucketEncryption(event: React.FormEvent) {
|
||||
event.preventDefault();
|
||||
const { kmsKeyID, loading, encryptionType } = this.state;
|
||||
const { selectedBucket } = this.props;
|
||||
if (loading) {
|
||||
return;
|
||||
}
|
||||
api
|
||||
.invoke("POST", `/api/v1/buckets/${selectedBucket}/encryption/enable`, {
|
||||
encType: encryptionType,
|
||||
kmsKeyID: kmsKeyID,
|
||||
})
|
||||
.then(() => {
|
||||
this.setState(
|
||||
{
|
||||
loading: false,
|
||||
encryptionError: "",
|
||||
},
|
||||
() => {
|
||||
this.props.closeModalAndRefresh();
|
||||
}
|
||||
);
|
||||
})
|
||||
.catch((err: any) => {
|
||||
this.setState({ encryptionError: err });
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { classes, open } = this.props;
|
||||
const { loading, encryptionError, kmsKeyID, encryptionType } = this.state;
|
||||
|
||||
return (
|
||||
<ModalWrapper
|
||||
modalOpen={open}
|
||||
onClose={() => {
|
||||
this.setState({ encryptionError: "" }, () => {
|
||||
this.props.closeModalAndRefresh();
|
||||
});
|
||||
}}
|
||||
title="Enable Bucket Encryption"
|
||||
>
|
||||
<form
|
||||
noValidate
|
||||
autoComplete="off"
|
||||
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
|
||||
this.enableBucketEncryption(e);
|
||||
}}
|
||||
>
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.formScrollable}>
|
||||
{encryptionError !== "" && (
|
||||
<Grid item xs={12}>
|
||||
<Typography
|
||||
component="p"
|
||||
variant="body1"
|
||||
className={classes.errorBlock}
|
||||
>
|
||||
{encryptionError}
|
||||
</Typography>
|
||||
</Grid>
|
||||
)}
|
||||
<Grid item xs={12}>
|
||||
<SelectWrapper
|
||||
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
|
||||
this.setState({ encryptionType: e.target.value as string });
|
||||
}}
|
||||
id="select-encryption-type"
|
||||
name="select-encryption-type"
|
||||
label={"Encryption Type"}
|
||||
value={encryptionType}
|
||||
options={[
|
||||
{
|
||||
label: "SSE-S3",
|
||||
value: "sse-s3",
|
||||
},
|
||||
{
|
||||
label: "SSE-KMS",
|
||||
value: "sse-kms",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<br />
|
||||
</Grid>
|
||||
{encryptionType === "sse-kms" && (
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="kms-key-id"
|
||||
name="kms-key-id"
|
||||
label="KMS Key ID"
|
||||
value={kmsKeyID}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
this.setState({ kmsKeyID: e.target.value });
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
)}
|
||||
<Grid item xs={12}>
|
||||
<br />
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={loading}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</Grid>
|
||||
{loading && (
|
||||
<Grid item xs={12}>
|
||||
<LinearProgress />
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
</form>
|
||||
</ModalWrapper>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withStyles(styles)(EnableBucketEncryption);
|
||||
@@ -94,7 +94,7 @@ class SetAccessPolicy extends React.Component<
|
||||
}
|
||||
|
||||
render() {
|
||||
const { classes, open, actualPolicy } = this.props;
|
||||
const { classes, open } = this.props;
|
||||
const { addLoading, addError, accessPolicy } = this.state;
|
||||
return (
|
||||
<ModalWrapper
|
||||
|
||||
@@ -23,9 +23,19 @@ import Tabs from "@material-ui/core/Tabs";
|
||||
import Tab from "@material-ui/core/Tab";
|
||||
import CircularProgress from "@material-ui/core/CircularProgress";
|
||||
import api from "../../../../common/api";
|
||||
import { BucketEvent, BucketEventList, BucketInfo, BucketList } from "../types";
|
||||
import {
|
||||
BucketEvent,
|
||||
BucketEventList,
|
||||
BucketInfo,
|
||||
BucketEncryptionInfo,
|
||||
BucketList,
|
||||
BucketReplication,
|
||||
BucketReplicationDestination,
|
||||
BucketReplicationRule,
|
||||
BucketReplicationRuleDeleteMarker,
|
||||
BucketVersioning,
|
||||
} from "../types";
|
||||
import { Button } from "@material-ui/core";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import SetAccessPolicy from "./SetAccessPolicy";
|
||||
import { MinTablePaginationActions } from "../../../../common/MinTablePaginationActions";
|
||||
import { CreateIcon } from "../../../../icons";
|
||||
@@ -33,6 +43,11 @@ import AddEvent from "./AddEvent";
|
||||
import DeleteEvent from "./DeleteEvent";
|
||||
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
|
||||
import { niceBytes } from "../../../../common/utils";
|
||||
import AddReplicationModal from "./AddReplicationModal";
|
||||
import { containerForHeader } from "../../Common/FormComponents/common/styleLibrary";
|
||||
import PageHeader from "../../Common/PageHeader/PageHeader";
|
||||
import Checkbox from "@material-ui/core/Checkbox";
|
||||
import EnableBucketEncryption from "./EnableBucketEncryption";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
@@ -117,6 +132,14 @@ const styles = (theme: Theme) =>
|
||||
capitalizeFirst: {
|
||||
textTransform: "capitalize",
|
||||
},
|
||||
doubleElement: {
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
tabPan: {
|
||||
marginTop: "5px",
|
||||
},
|
||||
...containerForHeader(theme.spacing(4)),
|
||||
});
|
||||
|
||||
interface IViewBucketProps {
|
||||
@@ -124,9 +147,40 @@ interface IViewBucketProps {
|
||||
match: any;
|
||||
}
|
||||
|
||||
interface TabPanelProps {
|
||||
children?: React.ReactNode;
|
||||
index: any;
|
||||
value: any;
|
||||
}
|
||||
|
||||
function TabPanel(props: TabPanelProps) {
|
||||
const { children, value, index, ...other } = props;
|
||||
|
||||
return (
|
||||
<div
|
||||
role="tabpanel"
|
||||
hidden={value !== index}
|
||||
id={`simple-tabpanel-${index}`}
|
||||
aria-labelledby={`simple-tab-${index}`}
|
||||
style={{ marginTop: "5px" }}
|
||||
{...other}
|
||||
>
|
||||
{value === index && <React.Fragment>{children}</React.Fragment>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function a11yProps(index: any) {
|
||||
return {
|
||||
id: `simple-tab-${index}`,
|
||||
"aria-controls": `simple-tabpanel-${index}`,
|
||||
};
|
||||
}
|
||||
|
||||
interface IViewBucketState {
|
||||
info: BucketInfo | null;
|
||||
records: BucketEvent[];
|
||||
replicationRules: BucketReplicationRule[];
|
||||
totalRecords: number;
|
||||
loadingBucket: boolean;
|
||||
loadingEvents: boolean;
|
||||
@@ -137,18 +191,25 @@ interface IViewBucketState {
|
||||
setAccessPolicyScreenOpen: boolean;
|
||||
page: number;
|
||||
rowsPerPage: number;
|
||||
curTab: number;
|
||||
addScreenOpen: boolean;
|
||||
enableEncryptionScreenOpen: boolean;
|
||||
deleteOpen: boolean;
|
||||
selectedBucket: string;
|
||||
selectedEvent: BucketEvent | null;
|
||||
bucketSize: string;
|
||||
errorSize: string;
|
||||
replicationSet: boolean;
|
||||
openSetReplication: boolean;
|
||||
isVersioned: boolean;
|
||||
encryptionEnabled: boolean;
|
||||
}
|
||||
|
||||
class ViewBucket extends React.Component<IViewBucketProps, IViewBucketState> {
|
||||
state: IViewBucketState = {
|
||||
info: null,
|
||||
records: [],
|
||||
replicationRules: [],
|
||||
totalRecords: 0,
|
||||
loadingBucket: true,
|
||||
loadingEvents: true,
|
||||
@@ -158,13 +219,19 @@ class ViewBucket extends React.Component<IViewBucketProps, IViewBucketState> {
|
||||
errBucket: "",
|
||||
setAccessPolicyScreenOpen: false,
|
||||
page: 0,
|
||||
curTab: 0,
|
||||
rowsPerPage: 10,
|
||||
addScreenOpen: false,
|
||||
enableEncryptionScreenOpen: false,
|
||||
deleteOpen: false,
|
||||
selectedBucket: "",
|
||||
selectedEvent: null,
|
||||
bucketSize: "0",
|
||||
errorSize: "",
|
||||
replicationSet: false,
|
||||
openSetReplication: false,
|
||||
isVersioned: false,
|
||||
encryptionEnabled: false,
|
||||
};
|
||||
|
||||
fetchEvents() {
|
||||
@@ -195,6 +262,29 @@ class ViewBucket extends React.Component<IViewBucketProps, IViewBucketState> {
|
||||
.catch((err: any) => {
|
||||
this.setState({ loadingEvents: false, error: err });
|
||||
});
|
||||
|
||||
api
|
||||
.invoke("GET", `/api/v1/buckets/${bucketName}/versioning`)
|
||||
.then((res: BucketVersioning) => {
|
||||
this.setState({
|
||||
isVersioned: res.is_versioned,
|
||||
});
|
||||
})
|
||||
.catch((err: any) => {
|
||||
this.setState({ error: err });
|
||||
});
|
||||
|
||||
api
|
||||
.invoke("GET", `/api/v1/buckets/${bucketName}/replication`)
|
||||
.then((res: BucketReplication) => {
|
||||
const r = res.rules ? res.rules : [];
|
||||
this.setState({
|
||||
replicationRules: r,
|
||||
});
|
||||
})
|
||||
.catch((err: any) => {
|
||||
this.setState({ error: err });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -241,6 +331,21 @@ class ViewBucket extends React.Component<IViewBucketProps, IViewBucketState> {
|
||||
});
|
||||
}
|
||||
|
||||
fetchBucketEncryptionInfo() {
|
||||
const { match } = this.props;
|
||||
const bucketName = match.params["bucketName"];
|
||||
api
|
||||
.invoke("GET", `/api/v1/buckets/${bucketName}/encryption/info`)
|
||||
.then((res: BucketEncryptionInfo) => {
|
||||
if (res.algorithm) {
|
||||
this.setState({ encryptionEnabled: true });
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
|
||||
closeAddModalAndRefresh() {
|
||||
this.setState({ setAccessPolicyScreenOpen: false }, () => {
|
||||
this.loadInfo();
|
||||
@@ -259,6 +364,7 @@ class ViewBucket extends React.Component<IViewBucketProps, IViewBucketState> {
|
||||
this.loadInfo();
|
||||
this.fetchEvents();
|
||||
this.fetchBucketsSize();
|
||||
this.fetchBucketEncryptionInfo();
|
||||
}
|
||||
|
||||
bucketFilter(): void {}
|
||||
@@ -276,9 +382,15 @@ class ViewBucket extends React.Component<IViewBucketProps, IViewBucketState> {
|
||||
rowsPerPage,
|
||||
deleteOpen,
|
||||
addScreenOpen,
|
||||
enableEncryptionScreenOpen,
|
||||
selectedEvent,
|
||||
bucketSize,
|
||||
loadingSize,
|
||||
openSetReplication,
|
||||
isVersioned,
|
||||
replicationRules,
|
||||
curTab,
|
||||
encryptionEnabled,
|
||||
} = this.state;
|
||||
|
||||
const offset = page * rowsPerPage;
|
||||
@@ -301,6 +413,7 @@ class ViewBucket extends React.Component<IViewBucketProps, IViewBucketState> {
|
||||
};
|
||||
|
||||
let accessPolicy = "n/a";
|
||||
|
||||
if (info !== null) {
|
||||
accessPolicy = info.access;
|
||||
}
|
||||
@@ -309,9 +422,43 @@ class ViewBucket extends React.Component<IViewBucketProps, IViewBucketState> {
|
||||
return <React.Fragment>{events.join(", ")}</React.Fragment>;
|
||||
};
|
||||
|
||||
const ruleDestDisplay = (events: BucketReplicationDestination) => {
|
||||
return (
|
||||
<React.Fragment>
|
||||
{events.bucket.replace("arn:aws:s3:::", "")}
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const ruleDelDisplay = (events: BucketReplicationRuleDeleteMarker) => {
|
||||
return <React.Fragment>{events.status}</React.Fragment>;
|
||||
};
|
||||
|
||||
const setOpenReplicationOpen = (open = false) => {
|
||||
this.setState({ openSetReplication: open });
|
||||
};
|
||||
|
||||
const handleEncryptionCheckbox = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
if (event.target.checked) {
|
||||
this.setState({ enableEncryptionScreenOpen: true });
|
||||
} else {
|
||||
api
|
||||
.invoke("POST", `/api/v1/buckets/${bucketName}/encryption/disable`)
|
||||
.then(() => {
|
||||
this.setState({ encryptionEnabled: false });
|
||||
})
|
||||
.catch((err: any) => {
|
||||
this.setState({ error: err });
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const tableActions = [{ type: "delete", onClick: confirmDeleteEvent }];
|
||||
|
||||
const filteredRecords = records.slice(offset, offset + rowsPerPage);
|
||||
const filteredRules = replicationRules.slice(offset, offset + rowsPerPage);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
@@ -325,6 +472,16 @@ class ViewBucket extends React.Component<IViewBucketProps, IViewBucketState> {
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{enableEncryptionScreenOpen && (
|
||||
<EnableBucketEncryption
|
||||
open={enableEncryptionScreenOpen}
|
||||
selectedBucket={bucketName}
|
||||
closeModalAndRefresh={() => {
|
||||
this.setState({ enableEncryptionScreenOpen: false });
|
||||
this.fetchBucketEncryptionInfo();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{setAccessPolicyScreenOpen && (
|
||||
<SetAccessPolicy
|
||||
bucketName={bucketName}
|
||||
@@ -335,130 +492,214 @@ class ViewBucket extends React.Component<IViewBucketProps, IViewBucketState> {
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{openSetReplication && (
|
||||
<AddReplicationModal
|
||||
closeModalAndRefresh={() => {
|
||||
setOpenReplicationOpen(false);
|
||||
this.fetchEvents();
|
||||
}}
|
||||
open={openSetReplication}
|
||||
bucketName={bucketName}
|
||||
/>
|
||||
)}
|
||||
<PageHeader label={`Bucket > ${match.params["bucketName"]}`} />
|
||||
<Grid container>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="h6">
|
||||
{`Bucket > ${match.params["bucketName"]}`}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<br />
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<div className={classes.headerContainer}>
|
||||
<div>
|
||||
<Paper className={classes.paperContainer}>
|
||||
<div className={classes.gridContainer}>
|
||||
<div>Access Policy:</div>
|
||||
<div className={classes.capitalizeFirst}>
|
||||
{loadingBucket ? (
|
||||
<CircularProgress
|
||||
color="primary"
|
||||
size={16}
|
||||
variant="indeterminate"
|
||||
/>
|
||||
) : (
|
||||
accessPolicy.toLowerCase()
|
||||
)}
|
||||
</div>
|
||||
<div>Reported Usage:</div>
|
||||
<div>
|
||||
{loadingSize ? (
|
||||
<CircularProgress
|
||||
color="primary"
|
||||
size={16}
|
||||
variant="indeterminate"
|
||||
/>
|
||||
) : (
|
||||
niceBytes(bucketSize)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Paper>
|
||||
</div>
|
||||
<div className={classes.masterActions}>
|
||||
<Grid item xs={12} className={classes.container}>
|
||||
<Grid item xs={12}>
|
||||
<div className={classes.headerContainer}>
|
||||
<div>
|
||||
<Paper className={classes.paperContainer}>
|
||||
<div className={classes.gridContainer}>
|
||||
<div>Access Policy:</div>
|
||||
<div className={classes.capitalizeFirst}>
|
||||
{loadingBucket ? (
|
||||
<CircularProgress
|
||||
color="primary"
|
||||
size={16}
|
||||
variant="indeterminate"
|
||||
/>
|
||||
) : (
|
||||
accessPolicy.toLowerCase()
|
||||
)}
|
||||
</div>
|
||||
<div>Reported Usage:</div>
|
||||
<div>
|
||||
{loadingSize ? (
|
||||
<CircularProgress
|
||||
color="primary"
|
||||
size={16}
|
||||
variant="indeterminate"
|
||||
/>
|
||||
) : (
|
||||
niceBytes(bucketSize)
|
||||
)}
|
||||
</div>
|
||||
<div>Replication:</div>
|
||||
<div className={classes.doubleElement}>
|
||||
<span>{replicationRules.length ? "Yes" : "No"}</span>
|
||||
</div>
|
||||
<div>Versioning:</div>
|
||||
<div>{isVersioned ? "Yes" : "No"} </div>
|
||||
<div>Encryption:</div>
|
||||
<div>
|
||||
<Checkbox
|
||||
color="primary"
|
||||
inputProps={{
|
||||
"aria-label": "secondary checkbox",
|
||||
}}
|
||||
onChange={(event) => handleEncryptionCheckbox(event)}
|
||||
checked={encryptionEnabled}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Paper>
|
||||
</div>
|
||||
<div className={classes.masterActions}>
|
||||
<div>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
fullWidth
|
||||
size="medium"
|
||||
onClick={() => {
|
||||
this.setState({
|
||||
setAccessPolicyScreenOpen: true,
|
||||
});
|
||||
}}
|
||||
>
|
||||
Change Access Policy
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<br />
|
||||
</Grid>
|
||||
<Grid container item xs={12}>
|
||||
<Grid item xs={6}>
|
||||
<Tabs
|
||||
value={curTab}
|
||||
onChange={(e: React.ChangeEvent<{}>, newValue: number) => {
|
||||
this.setState({ curTab: newValue });
|
||||
}}
|
||||
indicatorColor="primary"
|
||||
textColor="primary"
|
||||
aria-label="cluster-tabs"
|
||||
>
|
||||
<Tab label="Events" {...a11yProps(0)} />
|
||||
<Tab label="Replication" {...a11yProps(1)} />
|
||||
</Tabs>
|
||||
</Grid>
|
||||
<Grid item xs={6} className={classes.actionsTray}>
|
||||
{curTab === 0 && (
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
fullWidth
|
||||
startIcon={<CreateIcon />}
|
||||
size="medium"
|
||||
onClick={() => {
|
||||
this.setState({
|
||||
setAccessPolicyScreenOpen: true,
|
||||
addScreenOpen: true,
|
||||
});
|
||||
}}
|
||||
>
|
||||
Change Access Policy
|
||||
Subscribe to Event
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<br />
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Tabs
|
||||
value={0}
|
||||
indicatorColor="primary"
|
||||
textColor="primary"
|
||||
aria-label="cluster-tabs"
|
||||
>
|
||||
<Tab label="Events" />
|
||||
</Tabs>
|
||||
</Grid>
|
||||
<Grid item xs={6} className={classes.actionsTray}>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
startIcon={<CreateIcon />}
|
||||
size="medium"
|
||||
onClick={() => {
|
||||
this.setState({
|
||||
addScreenOpen: true,
|
||||
});
|
||||
}}
|
||||
>
|
||||
Subcribe to Event
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<br />
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<TableWrapper
|
||||
itemActions={tableActions}
|
||||
columns={[
|
||||
{ label: "SQS", elementKey: "arn" },
|
||||
{
|
||||
label: "Events",
|
||||
elementKey: "events",
|
||||
renderFunction: eventsDisplay,
|
||||
},
|
||||
{ label: "Prefix", elementKey: "prefix" },
|
||||
{ label: "Suffix", elementKey: "suffix" },
|
||||
]}
|
||||
isLoading={loadingEvents}
|
||||
records={filteredRecords}
|
||||
entityName="Events"
|
||||
idField="id"
|
||||
paginatorConfig={{
|
||||
rowsPerPageOptions: [5, 10, 25],
|
||||
colSpan: 3,
|
||||
count: totalRecords,
|
||||
rowsPerPage: rowsPerPage,
|
||||
page: page,
|
||||
SelectProps: {
|
||||
inputProps: { "aria-label": "rows per page" },
|
||||
native: true,
|
||||
},
|
||||
onChangePage: handleChangePage,
|
||||
onChangeRowsPerPage: handleChangeRowsPerPage,
|
||||
ActionsComponent: MinTablePaginationActions,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{curTab === 1 && (
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
startIcon={<CreateIcon />}
|
||||
size="medium"
|
||||
onClick={() => {
|
||||
this.setState({
|
||||
openSetReplication: true,
|
||||
});
|
||||
}}
|
||||
>
|
||||
Add Replication Rule
|
||||
</Button>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<TabPanel index={0} value={curTab}>
|
||||
<TableWrapper
|
||||
itemActions={tableActions}
|
||||
columns={[
|
||||
{ label: "SQS", elementKey: "arn" },
|
||||
{
|
||||
label: "Events",
|
||||
elementKey: "events",
|
||||
renderFunction: eventsDisplay,
|
||||
},
|
||||
{ label: "Prefix", elementKey: "prefix" },
|
||||
{ label: "Suffix", elementKey: "suffix" },
|
||||
]}
|
||||
isLoading={loadingEvents}
|
||||
records={filteredRecords}
|
||||
entityName="Events"
|
||||
idField="id"
|
||||
paginatorConfig={{
|
||||
rowsPerPageOptions: [5, 10, 25],
|
||||
colSpan: 3,
|
||||
count: totalRecords,
|
||||
rowsPerPage: rowsPerPage,
|
||||
page: page,
|
||||
SelectProps: {
|
||||
inputProps: { "aria-label": "rows per page" },
|
||||
native: true,
|
||||
},
|
||||
onChangePage: handleChangePage,
|
||||
onChangeRowsPerPage: handleChangeRowsPerPage,
|
||||
ActionsComponent: MinTablePaginationActions,
|
||||
}}
|
||||
/>
|
||||
</TabPanel>
|
||||
<TabPanel index={1} value={curTab}>
|
||||
<TableWrapper
|
||||
itemActions={tableActions}
|
||||
columns={[
|
||||
{ label: "ID", elementKey: "id" },
|
||||
{
|
||||
label: "Priority",
|
||||
elementKey: "priority",
|
||||
},
|
||||
{
|
||||
label: "Destination",
|
||||
elementKey: "destination",
|
||||
renderFunction: ruleDestDisplay,
|
||||
},
|
||||
{
|
||||
label: "Delete Replication",
|
||||
elementKey: "delete_marker_replication",
|
||||
renderFunction: ruleDelDisplay,
|
||||
},
|
||||
{ label: "Status", elementKey: "status" },
|
||||
]}
|
||||
isLoading={loadingEvents}
|
||||
records={filteredRules}
|
||||
entityName="Replication Rules"
|
||||
idField="id"
|
||||
paginatorConfig={{
|
||||
rowsPerPageOptions: [5, 10, 25],
|
||||
colSpan: 3,
|
||||
count: totalRecords,
|
||||
rowsPerPage: rowsPerPage,
|
||||
page: page,
|
||||
SelectProps: {
|
||||
inputProps: { "aria-label": "rows per page" },
|
||||
native: true,
|
||||
},
|
||||
onChangePage: handleChangePage,
|
||||
onChangeRowsPerPage: handleChangeRowsPerPage,
|
||||
ActionsComponent: MinTablePaginationActions,
|
||||
}}
|
||||
/>
|
||||
</TabPanel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
|
||||
126
portal-ui/src/screens/Console/Buckets/actions.ts
Normal file
@@ -0,0 +1,126 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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/>.
|
||||
|
||||
export const ADD_BUCKET_OPEN = "ADD_BUCKET_OPEN";
|
||||
export const ADD_BUCKET_NAME = "ADD_BUCKET_NAME";
|
||||
export const ADD_BUCKET_VERSIONED = "ADD_BUCKET_VERSIONED";
|
||||
export const ADD_BUCKET_QUOTA = "ADD_BUCKET_QUOTA";
|
||||
export const ADD_BUCKET_QUOTA_TYPE = "ADD_BUCKET_QUOTA_TYPE";
|
||||
export const ADD_BUCKET_QUOTA_SIZE = "ADD_BUCKET_QUOTA_SIZE";
|
||||
export const ADD_BUCKET_QUOTA_UNIT = "ADD_BUCKET_QUOTA_UNIT";
|
||||
export const ADD_BUCKET_RESET = "ADD_BUCKET_RESET";
|
||||
|
||||
interface AddBucketOpenAction {
|
||||
type: typeof ADD_BUCKET_OPEN;
|
||||
open: boolean;
|
||||
}
|
||||
|
||||
interface AddBucketNameAction {
|
||||
type: typeof ADD_BUCKET_NAME;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface AddBucketVersionedAction {
|
||||
type: typeof ADD_BUCKET_VERSIONED;
|
||||
versioned: boolean;
|
||||
}
|
||||
|
||||
interface AddBucketQuotaAction {
|
||||
type: typeof ADD_BUCKET_QUOTA;
|
||||
quota: boolean;
|
||||
}
|
||||
|
||||
interface AddBucketQuotaTypeAction {
|
||||
type: typeof ADD_BUCKET_QUOTA_TYPE;
|
||||
quotaType: string;
|
||||
}
|
||||
|
||||
interface AddBucketQuotaSizeAction {
|
||||
type: typeof ADD_BUCKET_QUOTA_SIZE;
|
||||
quotaSize: string;
|
||||
}
|
||||
|
||||
interface AddBucketQuotaUnitAction {
|
||||
type: typeof ADD_BUCKET_QUOTA_UNIT;
|
||||
quotaUnit: string;
|
||||
}
|
||||
interface AddBucketResetAction {
|
||||
type: typeof ADD_BUCKET_RESET;
|
||||
}
|
||||
|
||||
export type BucketActionTypes =
|
||||
| AddBucketOpenAction
|
||||
| AddBucketNameAction
|
||||
| AddBucketVersionedAction
|
||||
| AddBucketQuotaAction
|
||||
| AddBucketQuotaTypeAction
|
||||
| AddBucketQuotaSizeAction
|
||||
| AddBucketQuotaUnitAction
|
||||
| AddBucketResetAction;
|
||||
|
||||
export function addBucketOpen(open: boolean) {
|
||||
return {
|
||||
type: ADD_BUCKET_OPEN,
|
||||
open: open,
|
||||
};
|
||||
}
|
||||
export function addBucketName(name: string) {
|
||||
return {
|
||||
type: ADD_BUCKET_NAME,
|
||||
name: name,
|
||||
};
|
||||
}
|
||||
|
||||
export function addBucketVersioned(versioned: boolean) {
|
||||
return {
|
||||
type: ADD_BUCKET_VERSIONED,
|
||||
versioned: versioned,
|
||||
};
|
||||
}
|
||||
|
||||
export function addBucketQuota(quota: boolean) {
|
||||
return {
|
||||
type: ADD_BUCKET_QUOTA,
|
||||
quota: quota,
|
||||
};
|
||||
}
|
||||
|
||||
export function addBucketQuotaType(quotaType: string) {
|
||||
return {
|
||||
type: ADD_BUCKET_QUOTA_TYPE,
|
||||
quotaType: quotaType,
|
||||
};
|
||||
}
|
||||
|
||||
export function addBucketQuotaSize(quotaSize: string) {
|
||||
return {
|
||||
type: ADD_BUCKET_QUOTA_SIZE,
|
||||
quotaSize: quotaSize,
|
||||
};
|
||||
}
|
||||
|
||||
export function addBucketQuotaUnit(quotaUnit: string) {
|
||||
return {
|
||||
type: ADD_BUCKET_QUOTA_UNIT,
|
||||
quotaUnit: quotaUnit,
|
||||
};
|
||||
}
|
||||
|
||||
export function addBucketReset() {
|
||||
return {
|
||||
type: ADD_BUCKET_RESET,
|
||||
};
|
||||
}
|
||||
102
portal-ui/src/screens/Console/Buckets/reducers.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 {
|
||||
ADD_BUCKET_NAME,
|
||||
ADD_BUCKET_OPEN,
|
||||
ADD_BUCKET_QUOTA,
|
||||
ADD_BUCKET_QUOTA_SIZE,
|
||||
ADD_BUCKET_QUOTA_TYPE,
|
||||
ADD_BUCKET_QUOTA_UNIT,
|
||||
ADD_BUCKET_RESET,
|
||||
ADD_BUCKET_VERSIONED,
|
||||
BucketActionTypes,
|
||||
} from "./actions";
|
||||
|
||||
export interface BucketsState {
|
||||
open: boolean;
|
||||
addBucketName: string;
|
||||
addBucketVersioning: boolean;
|
||||
addBucketQuotaEnabled: boolean;
|
||||
addBucketQuotaType: string;
|
||||
addBucketQuotaSize: string;
|
||||
addBucketQuotaUnit: string;
|
||||
}
|
||||
|
||||
const initialState: BucketsState = {
|
||||
open: false,
|
||||
addBucketName: "",
|
||||
addBucketVersioning: false,
|
||||
addBucketQuotaEnabled: false,
|
||||
addBucketQuotaType: "hard",
|
||||
addBucketQuotaSize: "1",
|
||||
addBucketQuotaUnit: "TiB",
|
||||
};
|
||||
|
||||
export function bucketsReducer(
|
||||
state = initialState,
|
||||
action: BucketActionTypes
|
||||
): BucketsState {
|
||||
switch (action.type) {
|
||||
case ADD_BUCKET_OPEN:
|
||||
return {
|
||||
...state,
|
||||
open: action.open,
|
||||
};
|
||||
case ADD_BUCKET_NAME:
|
||||
return {
|
||||
...state,
|
||||
addBucketName: action.name,
|
||||
};
|
||||
case ADD_BUCKET_VERSIONED:
|
||||
return {
|
||||
...state,
|
||||
addBucketVersioning: action.versioned,
|
||||
};
|
||||
case ADD_BUCKET_QUOTA:
|
||||
return {
|
||||
...state,
|
||||
addBucketQuotaEnabled: action.quota,
|
||||
};
|
||||
case ADD_BUCKET_QUOTA_TYPE:
|
||||
return {
|
||||
...state,
|
||||
addBucketQuotaType: action.quotaType,
|
||||
};
|
||||
case ADD_BUCKET_QUOTA_SIZE:
|
||||
return {
|
||||
...state,
|
||||
addBucketQuotaSize: action.quotaSize,
|
||||
};
|
||||
case ADD_BUCKET_QUOTA_UNIT:
|
||||
return {
|
||||
...state,
|
||||
addBucketQuotaUnit: action.quotaUnit,
|
||||
};
|
||||
case ADD_BUCKET_RESET:
|
||||
return {
|
||||
...state,
|
||||
addBucketName: "",
|
||||
addBucketVersioning: false,
|
||||
addBucketQuotaEnabled: false,
|
||||
addBucketQuotaType: "hard",
|
||||
addBucketQuotaSize: "1",
|
||||
addBucketQuotaUnit: "TiB",
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,11 @@ export interface Bucket {
|
||||
creation_date: Date;
|
||||
}
|
||||
|
||||
export interface BucketEncryptionInfo {
|
||||
algorithm: string;
|
||||
kmsMasterKeyID: string;
|
||||
}
|
||||
|
||||
export interface BucketInfo {
|
||||
name: string;
|
||||
access: string;
|
||||
@@ -45,3 +50,49 @@ export interface BucketEventList {
|
||||
export interface ArnList {
|
||||
arns: string[];
|
||||
}
|
||||
|
||||
export interface BucketVersioning {
|
||||
is_versioned: boolean;
|
||||
}
|
||||
|
||||
export interface BucketReplicationRuleDeleteMarker {
|
||||
status: string;
|
||||
}
|
||||
export interface BucketReplicationDestination {
|
||||
bucket: string;
|
||||
}
|
||||
export interface BucketReplicationRule {
|
||||
id: string;
|
||||
status: string;
|
||||
priority: number;
|
||||
delete_marker_replication: BucketReplicationRuleDeleteMarker;
|
||||
Destination: BucketReplicationDestination;
|
||||
}
|
||||
|
||||
export interface BucketReplication {
|
||||
rules: BucketReplicationRule[];
|
||||
}
|
||||
|
||||
export interface QuotaRequest {
|
||||
enabled: boolean;
|
||||
quota_type: string;
|
||||
amount: number;
|
||||
}
|
||||
|
||||
export interface MakeBucketRequest {
|
||||
name: string;
|
||||
versioning: boolean;
|
||||
quota?: QuotaRequest;
|
||||
}
|
||||
|
||||
export interface IRemoteBucket {
|
||||
name: string;
|
||||
accessKey: string;
|
||||
secretKey: string;
|
||||
sourceBucket: string;
|
||||
targetURL: string;
|
||||
targetBucket: string;
|
||||
remoteARN: string;
|
||||
status: string;
|
||||
service: string;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React from "react";
|
||||
import get from "lodash/get";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import { NewServiceAccount } from "./types";
|
||||
import { Button } from "@material-ui/core";
|
||||
@@ -67,6 +68,8 @@ const CredentialsPrompt = ({
|
||||
return null;
|
||||
}
|
||||
|
||||
const consoleCreds = get(newServiceAccount, "console", null);
|
||||
|
||||
return (
|
||||
<ModalWrapper
|
||||
modalOpen={open}
|
||||
@@ -87,6 +90,21 @@ const CredentialsPrompt = ({
|
||||
<b>Secret Key:</b> {newServiceAccount.secretKey}
|
||||
</li>
|
||||
</ul>
|
||||
{consoleCreds && (
|
||||
<React.Fragment>
|
||||
<Grid item xs={12}>
|
||||
<strong>Console Credentials</strong>
|
||||
<ul>
|
||||
<li>
|
||||
<b>Access Key:</b> {consoleCreds.accessKey}
|
||||
</li>
|
||||
<li>
|
||||
<b>Secret Key:</b> {consoleCreds.secretKey}
|
||||
</li>
|
||||
</ul>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
)}
|
||||
<Typography
|
||||
component="p"
|
||||
variant="body1"
|
||||
@@ -99,11 +117,23 @@ const CredentialsPrompt = ({
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
<Button
|
||||
onClick={() => {
|
||||
let consoleExtras = {};
|
||||
|
||||
if (consoleCreds) {
|
||||
consoleExtras = {
|
||||
console: {
|
||||
access_key: consoleCreds.accessKey,
|
||||
secret_key: consoleCreds.secretKey,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
download(
|
||||
"credentials.json",
|
||||
JSON.stringify({
|
||||
access_key: newServiceAccount.accessKey,
|
||||
secret_key: newServiceAccount.secretKey,
|
||||
...consoleExtras,
|
||||
})
|
||||
);
|
||||
}}
|
||||
|
||||
@@ -17,4 +17,10 @@
|
||||
export interface NewServiceAccount {
|
||||
accessKey: string;
|
||||
secretKey: string;
|
||||
console?: ConsoleSA;
|
||||
}
|
||||
|
||||
export interface ConsoleSA {
|
||||
accessKey: string;
|
||||
secretKey: string;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2019 MinIO, Inc.
|
||||
// Copyright (c) 2020 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
|
||||
@@ -13,21 +13,32 @@
|
||||
//
|
||||
// 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, useEffect, createRef, ChangeEvent } from "react";
|
||||
import React, {
|
||||
useState,
|
||||
useEffect,
|
||||
createRef,
|
||||
useLayoutEffect,
|
||||
ChangeEvent,
|
||||
useRef,
|
||||
} from "react";
|
||||
import get from "lodash/get";
|
||||
import debounce from "lodash/debounce";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import get from "lodash/get";
|
||||
import InputBoxWrapper from "../InputBoxWrapper/InputBoxWrapper";
|
||||
import HelpIcon from "@material-ui/icons/Help";
|
||||
import { InputLabel, Tooltip } from "@material-ui/core";
|
||||
import { fieldBasic, tooltipHelper } from "../common/styleLibrary";
|
||||
import HelpIcon from "@material-ui/icons/Help";
|
||||
import InputBoxWrapper from "../InputBoxWrapper/InputBoxWrapper";
|
||||
import AddIcon from "../../../../../icons/AddIcon";
|
||||
|
||||
interface ICSVMultiSelector {
|
||||
elements: string;
|
||||
name: string;
|
||||
label: string;
|
||||
tooltip?: string;
|
||||
commonPlaceholder?: string;
|
||||
classes: any;
|
||||
withBorder?: boolean;
|
||||
onChange: (elements: string) => void;
|
||||
}
|
||||
|
||||
@@ -35,16 +46,13 @@ const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
...fieldBasic,
|
||||
...tooltipHelper,
|
||||
inputLabel: {
|
||||
...fieldBasic.inputLabel,
|
||||
width: 116,
|
||||
},
|
||||
inputContainer: {
|
||||
inputWithBorder: {
|
||||
border: "1px solid #EAEAEA",
|
||||
padding: 15,
|
||||
height: 150,
|
||||
overflowY: "auto",
|
||||
padding: 15,
|
||||
position: "relative",
|
||||
border: "1px solid #c4c4c4",
|
||||
marginTop: 15,
|
||||
},
|
||||
labelContainer: {
|
||||
display: "flex",
|
||||
@@ -56,7 +64,9 @@ const CSVMultiSelector = ({
|
||||
name,
|
||||
label,
|
||||
tooltip = "",
|
||||
commonPlaceholder = "",
|
||||
onChange,
|
||||
withBorder = false,
|
||||
classes,
|
||||
}: ICSVMultiSelector) => {
|
||||
const [currentElements, setCurrentElements] = useState<string[]>([""]);
|
||||
@@ -75,29 +85,37 @@ const CSVMultiSelector = ({
|
||||
|
||||
setCurrentElements(elementsSplit);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [elements, currentElements]);
|
||||
|
||||
// Use effect to send new values to onChange
|
||||
useEffect(() => {
|
||||
const elementsString = currentElements
|
||||
.filter((element) => element.trim() !== "")
|
||||
.join(",");
|
||||
onChange(elementsString);
|
||||
const refScroll = bottomList.current;
|
||||
if (refScroll) {
|
||||
refScroll.scrollIntoView(false);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [currentElements]);
|
||||
|
||||
// We avoid multiple re-renders / hang issue typing too fast
|
||||
const firstUpdate = useRef(true);
|
||||
useLayoutEffect(() => {
|
||||
if (firstUpdate.current) {
|
||||
firstUpdate.current = false;
|
||||
return;
|
||||
}
|
||||
debouncedOnChange();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [currentElements]);
|
||||
|
||||
// If the last input is not empty, we add a new one
|
||||
const addEmptyLine = (elementsUp: string[]) => {
|
||||
if (elementsUp[elementsUp.length - 1].trim() !== "") {
|
||||
elementsUp.push("");
|
||||
const refScroll = bottomList.current;
|
||||
|
||||
if (refScroll) {
|
||||
refScroll.scrollIntoView(false);
|
||||
}
|
||||
const cpList = [...elementsUp];
|
||||
cpList.push("");
|
||||
setCurrentElements(cpList);
|
||||
}
|
||||
|
||||
return elementsUp;
|
||||
};
|
||||
|
||||
// Onchange function for input box, we get the dataset-index & only update that value in the array
|
||||
@@ -108,10 +126,18 @@ const CSVMultiSelector = ({
|
||||
const index = get(e.target, "dataset.index", 0);
|
||||
updatedElement[index] = e.target.value;
|
||||
|
||||
updatedElement = addEmptyLine(updatedElement);
|
||||
setCurrentElements(updatedElement);
|
||||
};
|
||||
|
||||
// Debounce for On Change
|
||||
const debouncedOnChange = debounce(() => {
|
||||
const elementsString = currentElements
|
||||
.filter((element) => element.trim() !== "")
|
||||
.join(",");
|
||||
|
||||
onChange(elementsString);
|
||||
}, 500);
|
||||
|
||||
const inputs = currentElements.map((element, index) => {
|
||||
return (
|
||||
<InputBoxWrapper
|
||||
@@ -122,6 +148,11 @@ const CSVMultiSelector = ({
|
||||
onChange={onChangeElement}
|
||||
index={index}
|
||||
key={`csv-${name}-${index.toString()}`}
|
||||
placeholder={commonPlaceholder}
|
||||
overlayIcon={index === currentElements.length - 1 ? <AddIcon /> : null}
|
||||
overlayAction={() => {
|
||||
addEmptyLine(currentElements);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@@ -139,7 +170,11 @@ const CSVMultiSelector = ({
|
||||
</div>
|
||||
)}
|
||||
</InputLabel>
|
||||
<Grid item xs={12} className={classes.inputContainer}>
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
className={`${withBorder ? classes.inputWithBorder : ""}`}
|
||||
>
|
||||
{inputs}
|
||||
<div ref={bottomList} />
|
||||
</Grid>
|
||||
@@ -147,5 +182,4 @@ const CSVMultiSelector = ({
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(CSVMultiSelector);
|
||||
|
||||
@@ -14,21 +14,8 @@
|
||||
// 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 {
|
||||
Checkbox,
|
||||
Grid,
|
||||
InputLabel,
|
||||
TextField,
|
||||
TextFieldProps,
|
||||
Tooltip,
|
||||
} from "@material-ui/core";
|
||||
import { OutlinedInputProps } from "@material-ui/core/OutlinedInput";
|
||||
import {
|
||||
createStyles,
|
||||
makeStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
} from "@material-ui/core/styles";
|
||||
import { Checkbox, Grid, InputLabel, Tooltip } from "@material-ui/core";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import {
|
||||
checkboxIcons,
|
||||
fieldBasic,
|
||||
@@ -54,8 +41,14 @@ const styles = (theme: Theme) =>
|
||||
...fieldBasic,
|
||||
...tooltipHelper,
|
||||
...checkboxIcons,
|
||||
labelContainer: {
|
||||
flexGrow: 1,
|
||||
fieldContainer: {
|
||||
...fieldBasic.fieldContainer,
|
||||
display: "flex",
|
||||
justifyContent: "flex-start",
|
||||
alignItems: "center",
|
||||
margin: "15px 0",
|
||||
marginBottom: 0,
|
||||
flexBasis: "initial",
|
||||
},
|
||||
});
|
||||
|
||||
@@ -73,19 +66,7 @@ const CheckboxWrapper = ({
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Grid item xs={12} className={classes.fieldContainer}>
|
||||
{label !== "" && (
|
||||
<InputLabel htmlFor={id} className={classes.inputLabel}>
|
||||
<span>{label}</span>
|
||||
{tooltip !== "" && (
|
||||
<div className={classes.tooltipContainer}>
|
||||
<Tooltip title={tooltip} placement="top-start">
|
||||
<HelpIcon className={classes.tooltip} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
)}
|
||||
</InputLabel>
|
||||
)}
|
||||
<div className={classes.labelContainer}>
|
||||
<div>
|
||||
<Checkbox
|
||||
name={name}
|
||||
id={id}
|
||||
@@ -99,6 +80,18 @@ const CheckboxWrapper = ({
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
{label !== "" && (
|
||||
<InputLabel htmlFor={id} className={classes.inputLabel}>
|
||||
<span>{label}</span>
|
||||
{tooltip !== "" && (
|
||||
<div className={classes.tooltipContainer}>
|
||||
<Tooltip title={tooltip} placement="top-start">
|
||||
<HelpIcon className={classes.tooltip} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
)}
|
||||
</InputLabel>
|
||||
)}
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 HelpIcon from "@material-ui/icons/Help";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import { Controlled as CodeMirror } from "react-codemirror2";
|
||||
import { InputLabel, Tooltip } from "@material-ui/core";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import { fieldBasic } from "../common/styleLibrary";
|
||||
import "./ConsoleCodeMirror.css";
|
||||
|
||||
require("codemirror/mode/javascript/javascript");
|
||||
|
||||
interface ICodeWrapper {
|
||||
value: string;
|
||||
label?: string;
|
||||
tooltip?: string;
|
||||
classes: any;
|
||||
onChange?: (editor: any, data: any, value: string) => any;
|
||||
onBeforeChange: (editor: any, data: any, value: string) => any;
|
||||
readOnly?: boolean;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
...fieldBasic,
|
||||
});
|
||||
|
||||
const CodeMirrorWrapper = ({
|
||||
value,
|
||||
label = "",
|
||||
tooltip = "",
|
||||
classes,
|
||||
onChange = () => {},
|
||||
onBeforeChange,
|
||||
readOnly = false,
|
||||
}: ICodeWrapper) => {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<InputLabel className={classes.inputLabel}>
|
||||
<span>{label}</span>
|
||||
{tooltip !== "" && (
|
||||
<div className={classes.tooltipContainer}>
|
||||
<Tooltip title={tooltip} placement="top-start">
|
||||
<HelpIcon className={classes.tooltip} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
)}
|
||||
</InputLabel>
|
||||
<Grid item xs={12}>
|
||||
<br />
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<CodeMirror
|
||||
value={value}
|
||||
options={{
|
||||
mode: "javascript",
|
||||
lineNumbers: true,
|
||||
readOnly,
|
||||
}}
|
||||
onBeforeChange={onBeforeChange}
|
||||
onChange={onChange}
|
||||
/>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(CodeMirrorWrapper);
|
||||
@@ -0,0 +1,353 @@
|
||||
/* BASICS */
|
||||
|
||||
.CodeMirror {
|
||||
/* Set height, width, borders, and global font properties here */
|
||||
font-family: monospace;
|
||||
height: 300px;
|
||||
color: #fff;
|
||||
background: #081C42;
|
||||
direction: ltr;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* PADDING */
|
||||
|
||||
.CodeMirror-lines {
|
||||
padding: 4px 0; /* Vertical padding around content */
|
||||
}
|
||||
.CodeMirror pre.CodeMirror-line,
|
||||
.CodeMirror pre.CodeMirror-line-like {
|
||||
padding: 0 4px; /* Horizontal padding of content */
|
||||
}
|
||||
|
||||
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
|
||||
background-color: rgba(255,255,255,0.8); /* The little square between H and V scrollbars */
|
||||
}
|
||||
|
||||
/* GUTTER */
|
||||
|
||||
.CodeMirror-gutters {
|
||||
border-right: 1px solid #ddd;
|
||||
background-color: #ffffff80;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.CodeMirror-linenumbers {}
|
||||
.CodeMirror-linenumber {
|
||||
padding: 0 3px 0 5px;
|
||||
min-width: 20px;
|
||||
white-space: nowrap;
|
||||
color: #000;
|
||||
font-size: 10px;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.CodeMirror-guttermarker { color: black; }
|
||||
.CodeMirror-guttermarker-subtle { color: #999; }
|
||||
|
||||
/* CURSOR */
|
||||
|
||||
.CodeMirror-cursor {
|
||||
border-left: 1px solid white;
|
||||
border-right: none;
|
||||
width: 0;
|
||||
}
|
||||
/* Shown when moving in bi-directional text */
|
||||
.CodeMirror div.CodeMirror-secondarycursor {
|
||||
border-left: 1px solid silver;
|
||||
}
|
||||
.cm-fat-cursor .CodeMirror-cursor {
|
||||
width: auto;
|
||||
border: 0 !important;
|
||||
background: #7e7;
|
||||
}
|
||||
.cm-fat-cursor div.CodeMirror-cursors {
|
||||
z-index: 1;
|
||||
}
|
||||
.cm-fat-cursor-mark {
|
||||
background-color: rgba(20, 255, 20, 0.5);
|
||||
-webkit-animation: blink 1.06s steps(1) infinite;
|
||||
-moz-animation: blink 1.06s steps(1) infinite;
|
||||
animation: blink 1.06s steps(1) infinite;
|
||||
}
|
||||
.cm-animate-fat-cursor {
|
||||
width: auto;
|
||||
border: 0;
|
||||
-webkit-animation: blink 1.06s steps(1) infinite;
|
||||
-moz-animation: blink 1.06s steps(1) infinite;
|
||||
animation: blink 1.06s steps(1) infinite;
|
||||
background-color: #7e7;
|
||||
}
|
||||
@-moz-keyframes blink {
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
}
|
||||
@-webkit-keyframes blink {
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
}
|
||||
@keyframes blink {
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
}
|
||||
|
||||
/* Can style cursor different in overwrite (non-insert) mode */
|
||||
.CodeMirror-overwrite .CodeMirror-cursor {}
|
||||
|
||||
.cm-tab { display: inline-block; text-decoration: inherit; }
|
||||
|
||||
.CodeMirror-rulers {
|
||||
position: absolute;
|
||||
left: 0; right: 0; top: -50px; bottom: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.CodeMirror-ruler {
|
||||
border-left: 1px solid #ccc;
|
||||
top: 0; bottom: 0;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
/* DEFAULT THEME */
|
||||
|
||||
.cm-s-default .cm-header {color: #fff;}
|
||||
.cm-s-default .cm-quote {color: #fff;}
|
||||
.cm-negative {color: #fff;}
|
||||
.cm-positive {color: #fff;}
|
||||
.cm-header, .cm-strong {font-weight: bold;}
|
||||
.cm-em {font-style: italic;}
|
||||
.cm-link {text-decoration: underline;}
|
||||
.cm-strikethrough {text-decoration: line-through;}
|
||||
|
||||
.cm-s-default .cm-keyword {color: #fff;}
|
||||
.cm-s-default .cm-atom {color: #fff;}
|
||||
.cm-s-default .cm-number {color: #fff;}
|
||||
.cm-s-default .cm-def {color: #fff;}
|
||||
.cm-s-default .cm-variable,
|
||||
.cm-s-default .cm-punctuation,
|
||||
.cm-s-default .cm-property,
|
||||
.cm-s-default .cm-operator {}
|
||||
.cm-s-default .cm-variable-2 {color: #fff;}
|
||||
.cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #fff;}
|
||||
.cm-s-default .cm-comment {color: #fff;}
|
||||
.cm-s-default .cm-string {color: #fff;}
|
||||
.cm-s-default .cm-string-2 {color: #fff;}
|
||||
.cm-s-default .cm-meta {color: #fff;}
|
||||
.cm-s-default .cm-qualifier {color: #fff;}
|
||||
.cm-s-default .cm-builtin {color: #fff;}
|
||||
.cm-s-default .cm-bracket {color: #fff;}
|
||||
.cm-s-default .cm-tag {color: #fff;}
|
||||
.cm-s-default .cm-attribute {color: #fff;}
|
||||
.cm-s-default .cm-hr {color: #fff;}
|
||||
.cm-s-default .cm-link {color: #fff;}
|
||||
|
||||
.cm-s-default .cm-error {color: #fff;}
|
||||
.cm-invalidchar {color: #fff;}
|
||||
|
||||
.CodeMirror-composing { border-bottom: 2px solid; }
|
||||
|
||||
/* Default styles for common addons */
|
||||
|
||||
div.CodeMirror span.CodeMirror-matchingbracket {color: #fff;}
|
||||
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #fff;}
|
||||
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
|
||||
.CodeMirror-activeline-background {background: #e8f2ff;}
|
||||
|
||||
/* STOP */
|
||||
|
||||
/* The rest of this file contains styles related to the mechanics of
|
||||
the editor. You probably shouldn't touch them. */
|
||||
|
||||
.CodeMirror {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.CodeMirror-scroll {
|
||||
overflow: scroll !important; /* Things will break if this is overridden */
|
||||
/* 50px is the magic margin used to hide the element's real scrollbars */
|
||||
/* See overflow: hidden in .CodeMirror */
|
||||
margin-bottom: -50px; margin-right: -50px;
|
||||
padding-bottom: 50px;
|
||||
height: 100%;
|
||||
outline: none; /* Prevent dragging from highlighting the element */
|
||||
position: relative;
|
||||
}
|
||||
.CodeMirror-sizer {
|
||||
position: relative;
|
||||
border-right: 50px solid transparent;
|
||||
}
|
||||
|
||||
/* The fake, visible scrollbars. Used to force redraw during scrolling
|
||||
before actual scrolling happens, thus preventing shaking and
|
||||
flickering artifacts. */
|
||||
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
|
||||
position: absolute;
|
||||
z-index: 6;
|
||||
display: none;
|
||||
}
|
||||
.CodeMirror-vscrollbar {
|
||||
right: 0; top: 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.CodeMirror-hscrollbar {
|
||||
bottom: 0; left: 0;
|
||||
overflow-y: hidden;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
.CodeMirror-scrollbar-filler {
|
||||
right: 0; bottom: 0;
|
||||
}
|
||||
.CodeMirror-gutter-filler {
|
||||
left: 0; bottom: 0;
|
||||
}
|
||||
|
||||
.CodeMirror-gutters {
|
||||
position: absolute; left: 0; top: 0;
|
||||
min-height: 100%;
|
||||
z-index: 3;
|
||||
}
|
||||
.CodeMirror-gutter {
|
||||
white-space: normal;
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
margin-bottom: -50px;
|
||||
}
|
||||
.CodeMirror-gutter-wrapper {
|
||||
position: absolute;
|
||||
z-index: 4;
|
||||
background: none !important;
|
||||
border: none !important;
|
||||
}
|
||||
.CodeMirror-gutter-background {
|
||||
position: absolute;
|
||||
top: 0; bottom: 0;
|
||||
z-index: 4;
|
||||
}
|
||||
.CodeMirror-gutter-elt {
|
||||
position: absolute;
|
||||
cursor: default;
|
||||
z-index: 4;
|
||||
}
|
||||
.CodeMirror-gutter-wrapper ::selection { background-color: transparent }
|
||||
.CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }
|
||||
|
||||
.CodeMirror-lines {
|
||||
cursor: text;
|
||||
min-height: 1px; /* prevents collapsing before first draw */
|
||||
}
|
||||
.CodeMirror pre.CodeMirror-line,
|
||||
.CodeMirror pre.CodeMirror-line-like {
|
||||
/* Reset some styles that the rest of the page might have set */
|
||||
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
|
||||
border-width: 0;
|
||||
background: transparent;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
margin: 0;
|
||||
white-space: pre;
|
||||
word-wrap: normal;
|
||||
line-height: inherit;
|
||||
color: inherit;
|
||||
z-index: 2;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
-webkit-font-variant-ligatures: contextual;
|
||||
font-variant-ligatures: contextual;
|
||||
}
|
||||
.CodeMirror-wrap pre.CodeMirror-line,
|
||||
.CodeMirror-wrap pre.CodeMirror-line-like {
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
.CodeMirror-linebackground {
|
||||
position: absolute;
|
||||
left: 0; right: 0; top: 0; bottom: 0;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.CodeMirror-linewidget {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
padding: 0.1px; /* Force widget margins to stay inside of the container */
|
||||
}
|
||||
|
||||
.CodeMirror-widget {}
|
||||
|
||||
.CodeMirror-rtl pre { direction: rtl; }
|
||||
|
||||
.CodeMirror-code {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Force content-box sizing for the elements where we expect it */
|
||||
.CodeMirror-scroll,
|
||||
.CodeMirror-sizer,
|
||||
.CodeMirror-gutter,
|
||||
.CodeMirror-gutters,
|
||||
.CodeMirror-linenumber {
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.CodeMirror-measure {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.CodeMirror-cursor {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
.CodeMirror-measure pre { position: static; }
|
||||
|
||||
div.CodeMirror-cursors {
|
||||
visibility: hidden;
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
}
|
||||
div.CodeMirror-dragcursors {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.CodeMirror-focused div.CodeMirror-cursors {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.CodeMirror-selected { background: #d9d9d9; }
|
||||
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
|
||||
.CodeMirror-crosshair { cursor: crosshair; }
|
||||
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
|
||||
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
|
||||
|
||||
.cm-searching {
|
||||
background-color: #ffa;
|
||||
background-color: rgba(255, 255, 0, .4);
|
||||
}
|
||||
|
||||
/* Used to force a border model for a node */
|
||||
.cm-force-border { padding-right: .1px; }
|
||||
|
||||
@media print {
|
||||
/* Hide the cursor when printing */
|
||||
.CodeMirror div.CodeMirror-cursors {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
/* See issue #2901 */
|
||||
.cm-tab-wrap-hack:after { content: ''; }
|
||||
|
||||
/* Help users use markselection to safely style text background */
|
||||
span.CodeMirror-selectedtext { background: none; }
|
||||
@@ -0,0 +1,141 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 { Grid, InputLabel, TextField, Tooltip } from "@material-ui/core";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import { fieldBasic, tooltipHelper } from "../common/styleLibrary";
|
||||
import HelpIcon from "@material-ui/icons/Help";
|
||||
|
||||
interface CommentBoxProps {
|
||||
label: string;
|
||||
classes: any;
|
||||
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
value: string | boolean;
|
||||
id: string;
|
||||
name: string;
|
||||
disabled?: boolean;
|
||||
tooltip?: string;
|
||||
index?: number;
|
||||
error?: string;
|
||||
required?: boolean;
|
||||
placeholder?: string;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
...fieldBasic,
|
||||
...tooltipHelper,
|
||||
inputLabel: {
|
||||
...fieldBasic.inputLabel,
|
||||
marginBottom: 16,
|
||||
fontSize: 14,
|
||||
},
|
||||
textBoxContainer: {
|
||||
flexGrow: 1,
|
||||
position: "relative",
|
||||
},
|
||||
errorState: {
|
||||
color: "#b53b4b",
|
||||
fontSize: 14,
|
||||
position: "absolute",
|
||||
top: 7,
|
||||
right: 7,
|
||||
},
|
||||
cssOutlinedInput: {
|
||||
borderColor: "#9C9C9C",
|
||||
padding: 16,
|
||||
},
|
||||
rootContainer: {
|
||||
"& .MuiOutlinedInput-inputMultiline": {
|
||||
...fieldBasic.inputLabel,
|
||||
fontSize: 13,
|
||||
minHeight: 150,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const CommentBoxWrapper = ({
|
||||
label,
|
||||
onChange,
|
||||
value,
|
||||
id,
|
||||
name,
|
||||
disabled = false,
|
||||
tooltip = "",
|
||||
index = 0,
|
||||
error = "",
|
||||
required = false,
|
||||
placeholder = "",
|
||||
classes,
|
||||
}: CommentBoxProps) => {
|
||||
let inputProps: any = { "data-index": index };
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
className={`${classes.fieldContainer} ${
|
||||
error !== "" ? classes.errorInField : ""
|
||||
}`}
|
||||
>
|
||||
{label !== "" && (
|
||||
<InputLabel htmlFor={id} className={classes.inputLabel}>
|
||||
<span>
|
||||
{label}
|
||||
{required ? "*" : ""}
|
||||
</span>
|
||||
{tooltip !== "" && (
|
||||
<div className={classes.tooltipContainer}>
|
||||
<Tooltip title={tooltip} placement="top-start">
|
||||
<HelpIcon className={classes.tooltip} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
)}
|
||||
</InputLabel>
|
||||
)}
|
||||
|
||||
<div className={classes.textBoxContainer}>
|
||||
<TextField
|
||||
id={id}
|
||||
name={name}
|
||||
fullWidth
|
||||
value={value}
|
||||
disabled={disabled}
|
||||
onChange={onChange}
|
||||
multiline
|
||||
inputProps={inputProps}
|
||||
error={error !== ""}
|
||||
helperText={error}
|
||||
placeholder={placeholder}
|
||||
InputLabelProps={{
|
||||
shrink: true,
|
||||
}}
|
||||
InputProps={{
|
||||
classes: {
|
||||
notchedOutline: classes.cssOutlinedInput,
|
||||
root: classes.rootContainer,
|
||||
},
|
||||
}}
|
||||
variant="outlined"
|
||||
/>
|
||||
</div>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(CommentBoxWrapper);
|
||||