Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d573007747 | ||
|
|
f054b1c251 | ||
|
|
7a2358272a | ||
|
|
8a6a75b7a2 | ||
|
|
8cf678fb27 | ||
|
|
a20c6dc907 | ||
|
|
37ff8bb60d | ||
|
|
b6ac055857 | ||
|
|
12e53a1468 | ||
|
|
b21123e1cd | ||
|
|
f1db949abc | ||
|
|
761c6529a2 | ||
|
|
1f832fa294 | ||
|
|
be569aee4f | ||
|
|
419e94ccec | ||
|
|
12bc5265b8 | ||
|
|
32898f0c57 | ||
|
|
125c9abf56 | ||
|
|
bc27db4a69 | ||
|
|
dd8e2b13d3 | ||
|
|
005e3b941c | ||
|
|
efa614c773 | ||
|
|
63350e5492 | ||
|
|
255c128b67 | ||
|
|
06f333395e | ||
|
|
3cd024ea2c | ||
|
|
9c0a407db6 | ||
|
|
dc3c619f3f | ||
|
|
5000aafba6 | ||
|
|
b9f2a39d50 | ||
|
|
df321191f4 | ||
|
|
547eb41e96 | ||
|
|
afbb83e081 | ||
|
|
b599968570 | ||
|
|
24cc60f34e | ||
|
|
f967058409 | ||
|
|
078e09ba76 | ||
|
|
d6f97841d4 | ||
|
|
619ac124b3 | ||
|
|
a2180e123d | ||
|
|
0325bb7e2d | ||
|
|
fce361e5bd | ||
|
|
ed6d6e8b9d | ||
|
|
406709f66b | ||
|
|
3ac45a2211 |
2
.github/workflows/go.yml
vendored
2
.github/workflows/go.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [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:
|
||||
-
|
||||
|
||||
@@ -11,40 +11,7 @@ $ docker run --rm -p 389:389 -p 636:636 --name my-openldap-container --detach os
|
||||
Run the `billy.ldif` file using `ldapadd` command to create a new user and assign it to a group.
|
||||
|
||||
```
|
||||
$ cat > billy.ldif << EOF
|
||||
# LDIF fragment to create group branch under root
|
||||
dn: uid=billy,dc=example,dc=org
|
||||
uid: billy
|
||||
cn: billy
|
||||
sn: 3
|
||||
objectClass: top
|
||||
objectClass: posixAccount
|
||||
objectClass: inetOrgPerson
|
||||
loginShell: /bin/bash
|
||||
homeDirectory: /home/billy
|
||||
uidNumber: 14583102
|
||||
gidNumber: 14564100
|
||||
userPassword: {SSHA}j3lBh1Seqe4rqF1+NuWmjhvtAni1JC5A
|
||||
mail: billy@example.org
|
||||
gecos: Billy User
|
||||
# Create base group
|
||||
dn: ou=groups,dc=example,dc=org
|
||||
objectclass:organizationalunit
|
||||
ou: groups
|
||||
description: generic groups branch
|
||||
# create consoleAdmin group (this already exists on minio and have a policy of s3::*)
|
||||
dn: cn=consoleAdmin,ou=groups,dc=example,dc=org
|
||||
objectClass: top
|
||||
objectClass: posixGroup
|
||||
gidNumber: 678
|
||||
# Assing group to new user
|
||||
dn: cn=consoleAdmin,ou=groups,dc=example,dc=org
|
||||
changetype: modify
|
||||
add: memberuid
|
||||
memberuid: billy
|
||||
EOF
|
||||
|
||||
$ docker cp billy.ldif my-openldap-container:/container/service/slapd/assets/test/billy.ldif
|
||||
$ docker cp console/docs/ldap/billy.ldif my-openldap-container:/container/service/slapd/assets/test/billy.ldif
|
||||
$ docker exec my-openldap-container ldapadd -x -D "cn=admin,dc=example,dc=org" -w admin -f /container/service/slapd/assets/test/billy.ldif -H ldap://localhost -ZZ
|
||||
```
|
||||
|
||||
|
||||
29
Dockerfile
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
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
|
||||
36
README.md
36
README.md
@@ -113,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
|
||||
```
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -20,10 +20,12 @@ 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"
|
||||
)
|
||||
@@ -56,14 +58,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 +79,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 +105,18 @@ 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 path
|
||||
certs.GlobalCertsDir, _ = certs.NewConfigDirFromCtx(ctx, "certs-dir", certs.DefaultCertsDir.Get)
|
||||
certs.GlobalCertsCADir = &certs.ConfigDir{Path: filepath.Join(certs.GlobalCertsDir.Get(), certs.CertsCADir)}
|
||||
|
||||
if tlsCertificatePath != "" && tlsCertificateKeyPath != "" {
|
||||
server.TLSCertificate = flags.Filename(tlsCertificatePath)
|
||||
server.TLSCertificateKey = flags.Filename(tlsCertificateKeyPath)
|
||||
// check if certs and CAs directories exists or can be created
|
||||
if err := certs.MkdirAllIgnorePerm(certs.GlobalCertsCADir.Get()); err != nil {
|
||||
log.Println(fmt.Sprintf("Unable to create certs CA directory at %s", certs.GlobalCertsCADir.Get()))
|
||||
}
|
||||
// load the certificates and the CAs
|
||||
restapi.GlobalRootCAs, restapi.GlobalPublicCerts, restapi.GlobalTLSCertsManager = certs.GetAllCertificatesAndCAs()
|
||||
|
||||
if len(restapi.GlobalPublicCerts) > 0 {
|
||||
// If TLS certificates are provided enforce the HTTPS schema, meaning console will redirect
|
||||
// plain HTTP connections to HTTPS server
|
||||
server.EnabledListeners = []string{"http", "https"}
|
||||
|
||||
35
docs/ldap/billy.ldif
Normal file
35
docs/ldap/billy.ldif
Normal file
@@ -0,0 +1,35 @@
|
||||
# LDIF fragment to create group branch under root
|
||||
dn: uid=billy,dc=example,dc=org
|
||||
uid: billy
|
||||
cn: billy
|
||||
sn: 3
|
||||
objectClass: top
|
||||
objectClass: posixAccount
|
||||
objectClass: inetOrgPerson
|
||||
loginShell: /bin/bash
|
||||
homeDirectory: /home/billy
|
||||
uidNumber: 14583102
|
||||
gidNumber: 14564100
|
||||
userPassword: {SSHA}j3lBh1Seqe4rqF1+NuWmjhvtAni1JC5A
|
||||
mail: billy@example.org
|
||||
gecos: Billy User
|
||||
|
||||
# Create base group
|
||||
dn: ou=groups,dc=example,dc=org
|
||||
objectclass:organizationalunit
|
||||
ou: groups
|
||||
description: generic groups branch
|
||||
|
||||
# create consoleAdmin group (this already exists on minio and have a policy of s3::*)
|
||||
dn: cn=consoleAdmin,ou=groups,dc=example,dc=org
|
||||
objectClass: top
|
||||
objectClass: posixGroup
|
||||
gidNumber: 678
|
||||
|
||||
# Assing group to new user
|
||||
dn: cn=consoleAdmin,ou=groups,dc=example,dc=org
|
||||
changetype: modify
|
||||
add: memberuid
|
||||
memberuid: billy
|
||||
|
||||
|
||||
15
go.mod
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-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-20200930213302-ab2bbdfae96c
|
||||
github.com/minio/mc v0.0.0-20201119214335-d4f9ea859d6c
|
||||
github.com/minio/minio v0.0.0-20201102034248-d8e07f2c41c8
|
||||
github.com/minio/minio-go/v7 v7.0.6-0.20201119032702-6914cb678dde
|
||||
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-20200820211705-5c72a883971a
|
||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73
|
||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||
gopkg.in/yaml.v2 v2.3.0
|
||||
k8s.io/api v0.18.6
|
||||
|
||||
185
go.sum
185
go.sum
@@ -2,7 +2,6 @@ bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxo
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.39.0 h1:UgQP9na6OTfp4dsAiz/eFpFA1C6tPdH5wiRdi19tuMw=
|
||||
cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
@@ -14,7 +13,6 @@ 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=
|
||||
@@ -31,7 +29,6 @@ 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=
|
||||
@@ -40,12 +37,9 @@ contrib.go.opencensus.io/exporter/stackdriver v0.12.1/go.mod h1:iwB6wGarfphGGe/e
|
||||
contrib.go.opencensus.io/integrations/ocsql v0.1.4/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE=
|
||||
contrib.go.opencensus.io/resource v0.1.1/go.mod h1:F361eGI91LCmW1I/Saf+rX0+OFcigGlFvXwEGEnkRLA=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
git.apache.org/thrift.git v0.13.0 h1:/3bz5WZ+sqYArk7MBBBbDufMxKKOA56/6JO6psDpUDY=
|
||||
git.apache.org/thrift.git v0.13.0/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||
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=
|
||||
@@ -53,19 +47,15 @@ github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9mo
|
||||
github.com/Azure/azure-sdk-for-go v38.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v42.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
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/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/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=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
||||
@@ -119,7 +109,6 @@ github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrU
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||
github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE=
|
||||
github.com/alecthomas/participle v0.2.1 h1:4AVLj1viSGa4LG5HDXKXrm5xRx19SB/rS/skPQB1Grw=
|
||||
github.com/alecthomas/participle v0.2.1/go.mod h1:SW6HZGeZgSIpcUWX3fXpfZhuaWHnmoD5KCVaqSaNTkk=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
@@ -138,7 +127,6 @@ github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQh
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496 h1:zV3ejI06GQ59hwDQAvmK1qxOQGB3WuVTRoY0okPTAv0=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
|
||||
@@ -154,11 +142,9 @@ github.com/aws/aws-sdk-go v1.27.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN
|
||||
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=
|
||||
github.com/bcicen/jstream v0.0.0-20190220045926-16c1f8af81c2/go.mod h1:RDu/qcrnpEdJC/p8tx34+YBFqqX71lB7dOX9QE+ZC4M=
|
||||
github.com/beevik/ntp v0.2.0 h1:sGsd+kAXzT0bfVfzJfce04g+dSRfrs+tbQW8lweuYgw=
|
||||
github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
|
||||
github.com/beevik/ntp v0.3.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
@@ -176,12 +162,11 @@ 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=
|
||||
github.com/cheggaaa/pb v1.0.28 h1:kWGpdAcSp3MxMU9CCHOwz/8V0kCHN4+9yQm2MzWuI98=
|
||||
github.com/cheggaaa/pb v1.0.28/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
|
||||
github.com/cheggaaa/pb v1.0.29 h1:FckUN5ngEk2LpvuG0fw1GEFx6LtyY2pWI/Z2QgCnEYo=
|
||||
github.com/cheggaaa/pb v1.0.29/go.mod h1:W40334L7FMC5JKWldsTWbdGjLo0RxUKK73K+TuPxX30=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
@@ -193,10 +178,8 @@ github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa h1:OaNxuTZr
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/codegangsta/negroni v1.0.0 h1:+aYywywx4bnKXWvoWtRfJ91vC59NbEhEY03sZjQhbVY=
|
||||
github.com/codegangsta/negroni v1.0.0/go.mod h1:v0y3T5G7Y1UlFfyxFn/QLRU4a2EuNau2iZY63YTKWo0=
|
||||
github.com/colinmarc/hdfs/v2 v2.1.1 h1:x0hw/m+o3UE20Scso/KCkvYNc9Di39TBlCfGMkJ1/a0=
|
||||
github.com/colinmarc/hdfs/v2 v2.1.1/go.mod h1:M3x+k8UKKmxtFu++uAZ0OtDU8jR3jnaZIAc6yK4Ue0c=
|
||||
github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/coredns/coredns v1.4.0 h1:RubBkYmkByUqZWWkjRHvNLnUHgkRVqAWgSMmRFvpE1A=
|
||||
github.com/coredns/coredns v1.4.0/go.mod h1:zASH/MVDgR6XZTbxvOnsZfffS+31vg6Ackf/wo1+AM0=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
@@ -205,7 +188,6 @@ github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8Nz
|
||||
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk=
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
@@ -225,29 +207,26 @@ github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dchest/siphash v1.2.1 h1:4cLinnzVJDKxTCl9B01807Yiy+W7ZzVHj/KIroQRvT4=
|
||||
github.com/dchest/siphash v1.2.1/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4=
|
||||
github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
|
||||
github.com/djherbis/atime v1.0.0 h1:ySLvBAM0EvOGaX7TI4dAM5lWj+RdJUCKtGSEHN8SGBg=
|
||||
github.com/djherbis/atime v1.0.0/go.mod h1:5W+KBIuTwVGcqjIfaTwt+KSYX1o6uep8dtevevQP/f8=
|
||||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||
github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017 h1:2HQmlpI3yI9deH18Q6xiSOIjXD4sLI55Y/gfpa8/558=
|
||||
github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7 h1:Cvj7S8I4Xpx78KAl6TwTmMHuHlZ/0SM60NUneGJQ7IE=
|
||||
github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ=
|
||||
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
||||
github.com/dswarbrick/smart v0.0.0-20190505152634-909a45200d6d h1:QK8IYltsNy+5QZcDFbVkyInrs98/wHy1tfUTGG91sps=
|
||||
github.com/dswarbrick/smart v0.0.0-20190505152634-909a45200d6d/go.mod h1:apXo4PA/BgBPrt66j0N45O2stlBTRowdip2igwcUWVc=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
@@ -272,7 +251,6 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
|
||||
github.com/etcd-io/gofail v0.0.0-20190801230047-ad7f989257ca/go.mod h1:49H/RkXP8pKaZy4h0d+NW16rSLhyVBt4o6VLJbmOqDE=
|
||||
github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I=
|
||||
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
|
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
@@ -283,12 +261,10 @@ github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8
|
||||
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||
github.com/frankban/quicktest v1.4.1 h1:Wv2VwvNn73pAdFIVUQRXYDFp31lXKbqblIXo/Q5GPSg=
|
||||
github.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
@@ -300,7 +276,6 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2
|
||||
github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-ini/ini v1.57.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-ldap/ldap v3.0.2+incompatible h1:kD5HQcAzlQ7yrhfn+h+MSABeAy/jAJhvIJ/QDllP44g=
|
||||
github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc=
|
||||
github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
@@ -429,14 +404,11 @@ github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJA
|
||||
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903 h1:LbsanbbD6LieFkXbj9YNNBupiGHJgFeLpO0j0Fza1h8=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
@@ -453,7 +425,6 @@ github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+
|
||||
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
@@ -462,7 +433,6 @@ github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
@@ -490,19 +460,15 @@ github.com/golangci/revgrep v0.0.0-20180812185044-276a5c0a1039/go.mod h1:qOQCunE
|
||||
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1 h1:/exdXoGamhu5ONeUJH0deniYLWYvQwW66yvlfiiKTu0=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-containerregistry v0.1.2 h1:YjFNKqxzWUVZND8d4ItF9wuYlE75WQfECE7yKX/Nu3o=
|
||||
github.com/google/go-containerregistry v0.1.2/go.mod h1:GPivBPgdAyd2SU+vf6EpsgOtWDuPqjW0hJZt4rNdTZ4=
|
||||
github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
@@ -528,14 +494,10 @@ 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=
|
||||
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.2.2 h1:DcFegQ7+ECdmkJMfVwWlC+89I4esJ7p8nkGt9ainGDk=
|
||||
github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
@@ -546,14 +508,11 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR
|
||||
github.com/goreleaser/goreleaser v0.136.0/go.mod h1:wiKrPUeSNh6Wu8nUHxZydSOVQ/OZvOaO7DTtFqie904=
|
||||
github.com/goreleaser/nfpm v1.2.1/go.mod h1:TtWrABZozuLOttX2uDlYyECfQX7x5XYkVxhjYcR6G9w=
|
||||
github.com/goreleaser/nfpm v1.3.0/go.mod h1:w0p7Kc9TAUgWMyrub63ex3M2Mgw88M4GZXoTq5UCb40=
|
||||
github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg=
|
||||
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
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=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
@@ -577,11 +536,9 @@ github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyN
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
|
||||
github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
||||
github.com/hashicorp/go-hclog v0.9.1 h1:9PZfAcVEvez4yhLH2TBU64/h/z4xlFI80cWXRrxuKuM=
|
||||
github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
||||
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
|
||||
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
||||
@@ -594,16 +551,12 @@ github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uP
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY=
|
||||
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
|
||||
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=
|
||||
github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc=
|
||||
github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
|
||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||
github.com/hashicorp/go-uuid v0.0.0-20180228145832-27454136f036/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
@@ -614,11 +567,9 @@ github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09
|
||||
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
|
||||
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
@@ -627,19 +578,15 @@ github.com/hashicorp/raft v1.1.2 h1:oxEL5DDeurYxLd3UbcY/hccgSPhLLpiBZ1YxtWEq59c=
|
||||
github.com/hashicorp/raft v1.1.2/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8=
|
||||
github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/hashicorp/vault/api v1.0.4 h1:j08Or/wryXT4AcHj1oCbMd7IijXcKzYUGw59LGu9onU=
|
||||
github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoIospckxBxk6Q=
|
||||
github.com/hashicorp/vault/sdk v0.1.13 h1:mOEPeOhT7jl0J4AMl1E705+BcmeRs1VmKNb9F0sMLy8=
|
||||
github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M=
|
||||
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
|
||||
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf h1:WfD7VjIE6z8dIvMsI4/s+1qr5EL+zoIGev1BQj1eoJ8=
|
||||
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg=
|
||||
@@ -666,7 +613,6 @@ github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBv
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
@@ -689,40 +635,30 @@ github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eT
|
||||
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid v1.2.2 h1:1xAgYebNnsb9LKCdLOvFWtAxGU/33mjJtyOVbmUa0Us=
|
||||
github.com/klauspost/cpuid v1.2.2/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid v1.2.4 h1:EBfaK0SWSwk+fgk6efYFWdzl8MwRWoOO1gkmiaTXPW4=
|
||||
github.com/klauspost/cpuid v1.2.4/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid v1.3.1 h1:5JNjFYYQrZeKRJ0734q51WCEEn2huer72Dc7K+R/b6s=
|
||||
github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4=
|
||||
github.com/klauspost/pgzip v1.2.1 h1:oIPZROsWuPHpOdMVWLuJZXwgjhrW8r1yEX8UqMyeNHM=
|
||||
github.com/klauspost/pgzip v1.2.1/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/klauspost/readahead v1.3.1 h1:QqXNYvm+VvqYcbrRT4LojUciM0XrznFRIDrbHiJtu/0=
|
||||
github.com/klauspost/readahead v1.3.1/go.mod h1:AH9juHzNH7xqdqFHrMRSHeH2Ps+vFf+kblDqzPFiLJg=
|
||||
github.com/klauspost/reedsolomon v1.9.9 h1:qCL7LZlv17xMixl55nq2/Oa1Y86nfO8EqDfv2GHND54=
|
||||
github.com/klauspost/reedsolomon v1.9.9/go.mod h1:O7yFFHiQwDR6b2t63KPUpccPtNdp5ADgh1gg4fd12wo=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
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=
|
||||
@@ -745,9 +681,7 @@ github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
||||
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=
|
||||
@@ -758,13 +692,12 @@ github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
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.4/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=
|
||||
@@ -776,7 +709,6 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5
|
||||
github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.8 h1:1QYRAKU3lN5cRfLCkPU08hwvLJFhvjP6MqNMmQz6ZVI=
|
||||
github.com/miekg/dns v1.1.8/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/minio/cli v1.22.0 h1:VTQm7lmXm3quxO917X3p+el1l0Ca5X3S4PM2ruUYO68=
|
||||
github.com/minio/cli v1.22.0/go.mod h1:bYxnK0uS629N3Bq+AOZZ+6lwF77Sodk4+UL9vNuXhOY=
|
||||
@@ -784,32 +716,27 @@ 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-20201001165056-7f2df96e4821 h1:+09Ta2rY29df6U4bfSC85t7jxlNuYpUfl7lIVgTiDEA=
|
||||
github.com/minio/mc v0.0.0-20201001165056-7f2df96e4821/go.mod h1:+OeGPfw7qpvO1x2Td65ejwAuFT0Cxzx0GFTJSDlPMZQ=
|
||||
github.com/minio/mc v0.0.0-20201119214335-d4f9ea859d6c h1:/wGiTfC8pFOC2JzwE+XrPeH31LqFR/Dam4Lx1zX3Wag=
|
||||
github.com/minio/mc v0.0.0-20201119214335-d4f9ea859d6c/go.mod h1:B738ZPTRQiyp3uJ3p2W2mqk8Yp1puYASKY7GIhYyHP8=
|
||||
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-20200927172404-27d9bd04e544 h1:G6M9uXdFShowoLG3rMkdCtHsx37ZYB1vc+7bu22r85I=
|
||||
github.com/minio/minio v0.0.0-20200927172404-27d9bd04e544/go.mod h1:5uolst3SWpgvDNF+KJwfViU+j9WH7dB5i2YCi0nMNVo=
|
||||
github.com/minio/minio v0.0.0-20201102034248-d8e07f2c41c8 h1:yCDFjUBUoE1uNr8dEqjHuwySdAtOyvVONchEVrPPOGQ=
|
||||
github.com/minio/minio v0.0.0-20201102034248-d8e07f2c41c8/go.mod h1:640kMkCwiyOX8dheptHYModdUw4HrnUFHKw3McqUXD8=
|
||||
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.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-20200930213302-ab2bbdfae96c h1:OIKdzEJDFmUokbJ1rIdlr3kcfsBfXelYgSCTN/+Ppec=
|
||||
github.com/minio/operator v0.0.0-20200930213302-ab2bbdfae96c/go.mod h1:6lavbNo2YuJWeQR5bZYsEWdbpRCO2KrTyfQ0PtC/AN4=
|
||||
github.com/minio/selfupdate v0.3.1 h1:BWEFSNnrZVMUWXbXIgLDNDjbejkmpAmZvy/nCz1HlEs=
|
||||
github.com/minio/minio-go/v7 v7.0.6-0.20200929220449-755b5633803a/go.mod h1:CSt2ETZNs+bIIhWTse0mcZKZWMGrFU7Er7RR0TmkDYk=
|
||||
github.com/minio/minio-go/v7 v7.0.6-0.20201119032702-6914cb678dde h1:Ag2kFFpCxct9ayux92WQUlT938y7+IbibERYOraT8dM=
|
||||
github.com/minio/minio-go/v7 v7.0.6-0.20201119032702-6914cb678dde/go.mod h1:HcIuq+11d/3MfavIPZiswSzfQ1VJ2Lwxp/XLtW46IWQ=
|
||||
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/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/minio/sio v0.2.1/go.mod h1:8b0yPp2avGThviy/+OCJBI6OMpvxoUuiLvE6F1lebhw=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
@@ -822,13 +749,11 @@ github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUb
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg=
|
||||
github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
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=
|
||||
@@ -857,7 +782,6 @@ github.com/nats-io/nats-streaming-server v0.18.0 h1:+RDozeN9scwCm0Wc2fYlvGcP144h
|
||||
github.com/nats-io/nats-streaming-server v0.18.0/go.mod h1:Y9Aiif2oANuoKazQrs4wXtF3jqt6p97ODQg68lR5TnY=
|
||||
github.com/nats-io/nats.go v1.10.0 h1:L8qnKaofSfNFbXg0C5F71LdjPRnmQwSsA4ukmkt1TvY=
|
||||
github.com/nats-io/nats.go v1.10.0/go.mod h1:AjGArbfyR50+afOUotNX2Xs5SYHf+CoOa5HH1eEl2HE=
|
||||
github.com/nats-io/nkeys v0.1.3 h1:6JrEfig+HzTH85yxzhSVbjHRJv9cn0p6n3IngIcM5/k=
|
||||
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nkeys v0.1.4 h1:aEsHIssIk6ETN5m2/MD8Y4B2X7FfXrBAUdkyRvbVYzA=
|
||||
github.com/nats-io/nkeys v0.1.4/go.mod h1:XdZpAbhgyyODYqjTawOnIOI7VlbKSarI9Gfy1tqEu/s=
|
||||
@@ -880,13 +804,11 @@ github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB
|
||||
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=
|
||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
|
||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=
|
||||
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
|
||||
@@ -906,14 +828,13 @@ github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUr
|
||||
github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw=
|
||||
github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=
|
||||
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||
github.com/philhofer/fwd v1.1.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pierrec/lz4 v2.2.6+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pierrec/lz4 v2.4.0+incompatible h1:06usnXXDNcPvCHDkmPpkidf4jTc52UKld7UPfqKatY4=
|
||||
github.com/pierrec/lz4 v2.4.0+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -936,7 +857,6 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf
|
||||
github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
@@ -965,7 +885,6 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
||||
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
@@ -976,13 +895,11 @@ github.com/ryancurrah/gomodguard v1.0.4/go.mod h1:9T/Cfuxs5StfsocWr4WzDL36HqnX0f
|
||||
github.com/ryancurrah/gomodguard v1.1.0/go.mod h1:4O8tr7hBODaGE6VIhfJDHcwzh5GUccKSJBU0UMXJFVM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
|
||||
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
|
||||
github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/secure-io/sio-go v0.3.0 h1:QKGb6rGJeiExac9wSWxnWPYo8O8OFN7lxXQvHshX6vo=
|
||||
github.com/secure-io/sio-go v0.3.0/go.mod h1:D3KmXgKETffyYxBdFRN+Hpd2WzhzqS0EQwT3XWsAcBU=
|
||||
github.com/secure-io/sio-go v0.3.1 h1:dNvY9awjabXTYGsTF1PiCySl9Ltofk9GA3VdWlo7rRc=
|
||||
github.com/secure-io/sio-go v0.3.1/go.mod h1:+xbkjDzPjwh4Axd07pRKSNriS9SCiYksWnZqdnfpQxs=
|
||||
@@ -1000,18 +917,15 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
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=
|
||||
@@ -1022,7 +936,6 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k
|
||||
github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE=
|
||||
github.com/sourcegraph/go-diff v0.5.3/go.mod h1:v9JDtjCE4HHHCZGId75rg8gkKKa98RVjBcBGsVmMmak=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
@@ -1046,7 +959,6 @@ github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94 h1:0ngsPmuP6XIjiFRN
|
||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
@@ -1060,23 +972,19 @@ github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2/go.mod h1:yHp0
|
||||
github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM=
|
||||
github.com/tetafro/godot v0.3.7/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0=
|
||||
github.com/tetafro/godot v0.4.2/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0=
|
||||
github.com/tidwall/gjson v1.3.5 h1:2oW9FBNu8qt9jy5URgrzsVx/T/KSn3qn/smJQ0crlDQ=
|
||||
github.com/tidwall/gjson v1.3.5/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
|
||||
github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc=
|
||||
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
|
||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tidwall/sjson v1.0.4 h1:UcdIRXff12Lpnu3OLtZvnc03g4vH2suXDXhBwBqmzYg=
|
||||
github.com/tidwall/sjson v1.0.4/go.mod h1:bURseu1nuBkFpIES5cz6zBtjmYeOQmEESshn7VpF15Y=
|
||||
github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
|
||||
github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
|
||||
github.com/tinylib/msgp v1.1.2 h1:gWmO7n0Ys2RBEb7GPYB9Ujq8Mk5p2U08lRnmMcGy6BQ=
|
||||
github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tinylib/msgp v1.1.3/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0=
|
||||
github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0=
|
||||
github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao=
|
||||
github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8 h1:ndzgwNDnKIqyCvHTXaCqh9KlOWKvBry6nuXMJmonVsE=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
@@ -1101,11 +1009,8 @@ github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a h1:0R4NLDRDZX6Jc
|
||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
||||
github.com/vdemeester/k8s-pkg-credentialprovider v1.17.4/go.mod h1:inCTmtUdr5KJbreVojo06krnTgaeAz/Z7lynpPk/Q2c=
|
||||
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=
|
||||
github.com/xanzy/go-gitlab v0.32.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
|
||||
@@ -1132,16 +1037,13 @@ go.etcd.io/etcd/v3 v3.3.0-rc.0.0.20200707003333-58bb8ae09f8e h1:HZQLoe71Q24wVyDr
|
||||
go.etcd.io/etcd/v3 v3.3.0-rc.0.0.20200707003333-58bb8ae09f8e/go.mod h1:UENlOa05tkNvLx9VnNziSerG4Ro74upGK6Apd4v6M/Y=
|
||||
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
go.mongodb.org/mongo-driver v1.3.0 h1:ew6uUIeJOo+qdUUv7LxFCUhtWmVv7ZV/Xuy4FAUsw2E=
|
||||
go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE=
|
||||
go.mongodb.org/mongo-driver v1.3.4 h1:zs/dKNwX0gYUtzwrN9lLiR15hCO0nDwQj5xXx+vjCdE=
|
||||
go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE=
|
||||
go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0=
|
||||
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=
|
||||
@@ -1179,15 +1081,14 @@ golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo=
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
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-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee h1:4yd7jl+vXjalO5ztz6Vc1VADv+S/80LGJmyl1ROJ2AI=
|
||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/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=
|
||||
@@ -1208,7 +1109,6 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
@@ -1220,7 +1120,6 @@ golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKG
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
@@ -1263,19 +1162,17 @@ golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM=
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
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/net v0.0.0-20201010224723-4f7140c49acb h1:mUVeFHoDKis5nxCAzoAi7E8Ghb86EXh/RK6wtvJIqRY=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
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=
|
||||
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
|
||||
@@ -1285,12 +1182,9 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -1341,28 +1235,26 @@ golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
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-20200915084602-288bc346aa39 h1:356XA7ITklAU2//sYkjFeco+dH1bCRD8XCJ9FIEsvo4=
|
||||
golang.org/x/sys v0.0.0-20200915084602-288bc346aa39/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201013132646-2da7054afaeb h1:HS9IzC4UFbpMBLQUDSQcU+ViVT1vdFCQVjdPVpTlZrs=
|
||||
golang.org/x/sys v0.0.0-20201013132646-2da7054afaeb/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=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 h1:NusfzzA6yGQ+ua51ck7E3omNUX/JuqbFSaRGqU8CcLI=
|
||||
@@ -1434,21 +1326,16 @@ golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWc
|
||||
golang.org/x/tools v0.0.0-20200331202046-9d5940d49312/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200425043458-8463f397d07c h1:iHhCR0b26amDCiiO+kBguKZom9aMF+NrFxh9zeKR/XU=
|
||||
golang.org/x/tools v0.0.0-20200425043458-8463f397d07c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
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-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=
|
||||
@@ -1456,7 +1343,6 @@ gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40
|
||||
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=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.5.0 h1:lj9SyhMzyoa38fgFF0oO2T6pjs5IzkLPKfVtxpyCRMM=
|
||||
google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.6.0/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4=
|
||||
google.golang.org/api v0.6.1-0.20190607001116-5213b8090861/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4=
|
||||
@@ -1472,12 +1358,10 @@ 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=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
@@ -1493,7 +1377,6 @@ google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRn
|
||||
google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
||||
google.golang.org/genproto v0.0.0-20190620144150-6af8c5fc6601/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
@@ -1519,12 +1402,10 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.22.0 h1:J0UbZOIrCAl+fpTOf8YLs4dJo8L/owV4LYVtAXQoPkw=
|
||||
google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
@@ -1536,26 +1417,19 @@ google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0 h1:cJv5/xdbk1NnMPR1VP9+HU6gupuG9MLBoH1r6RHZ2MY=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM=
|
||||
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
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=
|
||||
@@ -1574,16 +1448,13 @@ gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN
|
||||
gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q=
|
||||
gopkg.in/jcmturner/goidentity.v3 v3.0.0 h1:1duIyWiTaYvVx3YX2CYtpJbUFd7/UuPYCfgXtQ3VTbI=
|
||||
gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
|
||||
gopkg.in/jcmturner/gokrb5.v7 v7.2.3 h1:hHMV/yKPwMnJhPuPx7pH2Uw/3Qyf+thJYlisUc44010=
|
||||
gopkg.in/jcmturner/gokrb5.v7 v7.2.3/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
|
||||
gopkg.in/jcmturner/gokrb5.v7 v7.3.0 h1:0709Jtq/6QXEuWRfAm260XqlpcwL1vxtO1tUE2qK8Z4=
|
||||
gopkg.in/jcmturner/gokrb5.v7 v7.3.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
|
||||
gopkg.in/jcmturner/rpc.v1 v1.1.0 h1:QHIUxTX1ISuAv9dD2wJ9HWQVuWDX/Zc0PfeC2tjc4rU=
|
||||
gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8=
|
||||
gopkg.in/ldap.v3 v3.0.3 h1:YKRHW/2sIl05JsCtx/5ZuUueFuJyoj/6+DGXe3wp6ro=
|
||||
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=
|
||||
@@ -1601,7 +1472,6 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
@@ -1614,7 +1484,6 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.5 h1:nI5egYTGJakVyOryqLs1cQO5dO0ksin5XXs2pspk75k=
|
||||
|
||||
@@ -15,7 +15,7 @@ spec:
|
||||
serviceAccountName: console-sa
|
||||
containers:
|
||||
- name: console
|
||||
image: minio/console:v0.4.2
|
||||
image: minio/console:v0.4.6
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
args:
|
||||
- server
|
||||
|
||||
@@ -15,7 +15,7 @@ spec:
|
||||
serviceAccountName: console-sa
|
||||
containers:
|
||||
- name: console
|
||||
image: minio/console:v0.4.2
|
||||
image: minio/console:v0.4.6
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
env:
|
||||
- name: CONSOLE_OPERATOR_MODE
|
||||
|
||||
63
models/bucket_encryption_info.go
Normal file
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
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
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
|
||||
}
|
||||
@@ -65,6 +65,9 @@ type BucketObject struct {
|
||||
// size
|
||||
Size int64 `json:"size,omitempty"`
|
||||
|
||||
// tags
|
||||
Tags map[string]string `json:"tags,omitempty"`
|
||||
|
||||
// user tags
|
||||
UserTags map[string]string `json:"user_tags,omitempty"`
|
||||
|
||||
|
||||
@@ -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"`
|
||||
|
||||
|
||||
@@ -33,14 +33,8 @@ import (
|
||||
// swagger:model createTenantResponse
|
||||
type CreateTenantResponse struct {
|
||||
|
||||
// access key
|
||||
AccessKey string `json:"access_key,omitempty"`
|
||||
|
||||
// console
|
||||
Console *CreateTenantResponseConsole `json:"console,omitempty"`
|
||||
|
||||
// secret key
|
||||
SecretKey string `json:"secret_key,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this create tenant response
|
||||
|
||||
80
models/object_legal_hold_status.go
Normal file
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
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
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
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
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
|
||||
}
|
||||
@@ -22,27 +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"
|
||||
remoteBuckets = "/remote-buckets"
|
||||
replication = "/replication"
|
||||
objectBrowser = "/object-browser/:bucket?"
|
||||
mainObjectBrowser = "/object-browser"
|
||||
license = "/license"
|
||||
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 {
|
||||
@@ -60,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(
|
||||
@@ -118,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(
|
||||
@@ -245,25 +224,24 @@ var licenseActionSet = ConfigurationActionSet{
|
||||
|
||||
// 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,
|
||||
remoteBuckets: remoteBucketsActionSet,
|
||||
replication: replicationActionSet,
|
||||
objectBrowser: objectBrowserActionSet,
|
||||
mainObjectBrowser: objectBrowserActionSet,
|
||||
license: licenseActionSet,
|
||||
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: 5,
|
||||
want: 6,
|
||||
},
|
||||
{
|
||||
name: "policies endpoint",
|
||||
@@ -63,7 +63,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
|
||||
"admin:ListUserPolicies",
|
||||
},
|
||||
},
|
||||
want: 5,
|
||||
want: 6,
|
||||
},
|
||||
{
|
||||
name: "all admin endpoints",
|
||||
@@ -72,7 +72,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
|
||||
"admin:*",
|
||||
},
|
||||
},
|
||||
want: 16,
|
||||
want: 15,
|
||||
},
|
||||
{
|
||||
name: "all s3 endpoints",
|
||||
@@ -81,7 +81,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
|
||||
"s3:*",
|
||||
},
|
||||
},
|
||||
want: 7,
|
||||
want: 8,
|
||||
},
|
||||
{
|
||||
name: "all admin and s3 endpoints",
|
||||
@@ -91,7 +91,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
|
||||
"s3:*",
|
||||
},
|
||||
},
|
||||
want: 19,
|
||||
want: 18,
|
||||
},
|
||||
{
|
||||
name: "no endpoints",
|
||||
@@ -177,7 +177,7 @@ func TestGetActionsStringFromPolicy(t *testing.T) {
|
||||
args: args{
|
||||
policy: &iampolicy.AdminDiagnostics,
|
||||
},
|
||||
want: 6,
|
||||
want: 7,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
|
||||
@@ -18,7 +18,7 @@ package auth
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/minio/minio-go/v7/pkg/credentials"
|
||||
)
|
||||
@@ -27,13 +27,14 @@ var (
|
||||
errInvalidCredentials = errors.New("invalid Login")
|
||||
)
|
||||
|
||||
// GetConsoleCredentialsFromLDAP authenticates the user against MinIO when the LDAP integration is enabled
|
||||
// GetCredentialsFromLDAP authenticates the user against MinIO when the LDAP integration is enabled
|
||||
// if the authentication succeed *credentials.Login object is returned and we continue with the normal STSAssumeRole flow
|
||||
func GetConsoleCredentialsFromLDAP(endpoint, ldapUser, ldapPassword string) (*credentials.Credentials, error) {
|
||||
creds, err := credentials.NewLDAPIdentity(endpoint, ldapUser, ldapPassword)
|
||||
if err != nil {
|
||||
log.Println("LDAP authentication error: ", err)
|
||||
return nil, errInvalidCredentials
|
||||
}
|
||||
func GetCredentialsFromLDAP(client *http.Client, endpoint, ldapUser, ldapPassword string) (*credentials.Credentials, error) {
|
||||
creds := credentials.New(&credentials.LDAPIdentity{
|
||||
Client: client,
|
||||
STSEndpoint: endpoint,
|
||||
LDAPUsername: ldapUser,
|
||||
LDAPPassword: ldapPassword,
|
||||
})
|
||||
return creds, nil
|
||||
}
|
||||
|
||||
233
pkg/certs/certs.go
Normal file
233
pkg/certs/certs.go
Normal file
@@ -0,0 +1,233 @@
|
||||
// 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"
|
||||
certsx "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
|
||||
}
|
||||
|
||||
func GetAllCertificatesAndCAs() (*x509.CertPool, []*x509.Certificate, *certs.Manager) {
|
||||
// load all CAs from ~/.console/certs/CAs
|
||||
GlobalRootCAs, err := certsx.GetRootCAs(GlobalCertsCADir.Get())
|
||||
logger.FatalIf(err, "Failed to read root CAs (%v)", err)
|
||||
// load all certs from ~/.console/certs
|
||||
globalPublicCerts, globalTLSCertsManager, err := GetTLSConfig()
|
||||
logger.FatalIf(err, "Unable to load the TLS configuration")
|
||||
return GlobalRootCAs, globalPublicCerts, globalTLSCertsManager
|
||||
}
|
||||
34
pkg/certs/const.go
Normal file
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"
|
||||
)
|
||||
File diff suppressed because one or more lines are too long
30
portal-ui/package-lock.json
generated
30
portal-ui/package-lock.json
generated
@@ -1827,6 +1827,14 @@
|
||||
"csstype": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"@types/react-copy-to-clipboard": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-copy-to-clipboard/-/react-copy-to-clipboard-4.3.0.tgz",
|
||||
"integrity": "sha512-iideNPRyroENqsOFh1i2Dv3zkviYS9r/9qD9Uh3Z9NNoAAqqa2x53i7iGndGNnJFIo20wIu7Hgh77tx1io8bgw==",
|
||||
"requires": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"version": "16.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.4.tgz",
|
||||
@@ -3943,6 +3951,14 @@
|
||||
"resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
|
||||
"integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
|
||||
},
|
||||
"copy-to-clipboard": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz",
|
||||
"integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==",
|
||||
"requires": {
|
||||
"toggle-selection": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"core-js": {
|
||||
"version": "3.6.5",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
|
||||
@@ -13932,6 +13948,15 @@
|
||||
"resolved": "https://registry.npmjs.org/react-codemirror2/-/react-codemirror2-7.1.0.tgz",
|
||||
"integrity": "sha512-Rel0QbPnCTjHxgZYt6TkGw4icSZXNyONHb72a+1wWA+PlYJIvzFAv4pZlDPG0rpKpKmy4kSUlkoWgneH7w3A0g=="
|
||||
},
|
||||
"react-copy-to-clipboard": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.2.tgz",
|
||||
"integrity": "sha512-/2t5mLMMPuN5GmdXo6TebFa8IoFxZ+KTDDqYhcDm0PhkgEzSxVvIX26G20s1EB02A4h2UZgwtfymZ3lGJm0OLg==",
|
||||
"requires": {
|
||||
"copy-to-clipboard": "^3",
|
||||
"prop-types": "^15.5.8"
|
||||
}
|
||||
},
|
||||
"react-dev-utils": {
|
||||
"version": "10.2.1",
|
||||
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-10.2.1.tgz",
|
||||
@@ -16325,6 +16350,11 @@
|
||||
"repeat-string": "^1.6.1"
|
||||
}
|
||||
},
|
||||
"toggle-selection": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
|
||||
"integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI="
|
||||
},
|
||||
"toidentifier": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
|
||||
|
||||
@@ -13,10 +13,12 @@
|
||||
"@types/lodash": "^4.14.149",
|
||||
"@types/node": "12.12.8",
|
||||
"@types/react": "16.9.11",
|
||||
"@types/react-copy-to-clipboard": "^4.3.0",
|
||||
"@types/react-dom": "16.9.4",
|
||||
"@types/react-redux": "^7.1.5",
|
||||
"@types/react-router": "^5.1.3",
|
||||
"@types/react-router-dom": "^5.1.2",
|
||||
"@types/react-virtualized": "^9.21.10",
|
||||
"@types/recharts": "^1.8.9",
|
||||
"@types/superagent": "^4.1.4",
|
||||
"@types/webpack-env": "^1.14.1",
|
||||
@@ -28,19 +30,21 @@
|
||||
"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-copy-to-clipboard": "^5.0.2",
|
||||
"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",
|
||||
"react-virtualized": "^9.22.2",
|
||||
"react-window-infinite-loader": "^1.0.5",
|
||||
"recharts": "^1.8.5",
|
||||
"redux": "^4.0.4",
|
||||
"redux-thunk": "^2.3.0",
|
||||
|
||||
6
portal-ui/public/images/ob_bucket_clear.svg
Normal file
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
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
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
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
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
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 |
68
portal-ui/src/ProtectedRoutes.tsx
Normal file
68
portal-ui/src/ProtectedRoutes.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
// 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, { useEffect, useState } from "react";
|
||||
import { Redirect } from "react-router-dom";
|
||||
import { connect } from "react-redux";
|
||||
import { AppState } from "./store";
|
||||
import { userLoggedIn } from "./actions";
|
||||
import api from "./common/api";
|
||||
import { clearSession } from "./common/utils";
|
||||
import { saveSessionResponse } from "./screens/Console/actions";
|
||||
|
||||
const mapState = (state: AppState) => ({
|
||||
loggedIn: state.system.loggedIn,
|
||||
});
|
||||
|
||||
const connector = connect(mapState, {
|
||||
userLoggedIn,
|
||||
saveSessionResponse,
|
||||
});
|
||||
|
||||
interface ProtectedRouteProps {
|
||||
loggedIn: boolean;
|
||||
Component: any;
|
||||
userLoggedIn: typeof userLoggedIn;
|
||||
saveSessionResponse: typeof saveSessionResponse;
|
||||
}
|
||||
|
||||
const ProtectedRoute = ({
|
||||
Component,
|
||||
loggedIn,
|
||||
userLoggedIn,
|
||||
saveSessionResponse,
|
||||
}: ProtectedRouteProps) => {
|
||||
const [sessionLoading, setSessionLoading] = useState<boolean>(true);
|
||||
useEffect(() => {
|
||||
api
|
||||
.invoke("GET", `/api/v1/session`)
|
||||
.then((res) => {
|
||||
saveSessionResponse(res);
|
||||
userLoggedIn(true);
|
||||
setSessionLoading(false);
|
||||
})
|
||||
.catch(() => setSessionLoading(false));
|
||||
}, [saveSessionResponse]);
|
||||
|
||||
// if we still trying to retrieve user session render nothing
|
||||
if (sessionLoading) {
|
||||
return null;
|
||||
}
|
||||
// redirect user to the right page based on session status
|
||||
return loggedIn ? <Component /> : <Redirect to={{ pathname: "/login" }} />;
|
||||
};
|
||||
|
||||
export default connector(ProtectedRoute);
|
||||
@@ -15,72 +15,24 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React from "react";
|
||||
import {
|
||||
Redirect,
|
||||
Route,
|
||||
Router,
|
||||
Switch,
|
||||
BrowserRouter,
|
||||
} from "react-router-dom";
|
||||
import { 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";
|
||||
import ProtectedRoute from "./ProtectedRoutes";
|
||||
|
||||
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 = () => {
|
||||
const Routes = () => {
|
||||
return (
|
||||
storage.getItem("token") !== undefined &&
|
||||
storage.getItem("token") !== null &&
|
||||
storage.getItem("token") !== ""
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
<Route exact path="/oauth_callback" component={LoginCallback} />
|
||||
<Route exact path="/login" component={Login} />
|
||||
<ProtectedRoute Component={Console} />
|
||||
</Switch>
|
||||
</Router>
|
||||
);
|
||||
};
|
||||
|
||||
const mapState = (state: AppState) => ({
|
||||
loggedIn: state.system.loggedIn,
|
||||
});
|
||||
|
||||
const connector = connect(mapState, { userLoggedIn });
|
||||
|
||||
interface RoutesProps {
|
||||
loggedIn: boolean;
|
||||
userLoggedIn: typeof userLoggedIn;
|
||||
}
|
||||
|
||||
class Routes extends React.Component<RoutesProps> {
|
||||
render() {
|
||||
const loggedIn = isLoggedIn();
|
||||
return (
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
<Route exact path="/oauth_callback" component={LoginCallback} />
|
||||
<Route exact path="/login" component={Login} />
|
||||
<ProtectedRoute component={Console} loggedIn={loggedIn} />
|
||||
</Switch>
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default hot(connector(Routes));
|
||||
export default hot(Routes);
|
||||
|
||||
@@ -14,16 +14,13 @@
|
||||
// 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 storage from "local-storage-fallback";
|
||||
import request from "superagent";
|
||||
import get from "lodash/get";
|
||||
import { clearSession } from "../utils";
|
||||
|
||||
export class API {
|
||||
invoke(method: string, url: string, data?: object) {
|
||||
const token: string = storage.getItem("token")!;
|
||||
return request(method, url)
|
||||
.set("Authorization", `Bearer ${token}`)
|
||||
.send(data)
|
||||
.then((res) => res.body)
|
||||
.catch((err) => {
|
||||
|
||||
@@ -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
|
||||
@@ -62,17 +62,12 @@ export const deleteCookie = (name: string) => {
|
||||
document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:01 GMT;";
|
||||
};
|
||||
|
||||
export const setSession = (token: string) => {
|
||||
setCookie("token", token);
|
||||
storage.setItem("token", token);
|
||||
};
|
||||
|
||||
export const clearSession = () => {
|
||||
storage.removeItem("token");
|
||||
deleteCookie("token");
|
||||
};
|
||||
|
||||
// timeFromdate gets time string from date input
|
||||
// timeFromDate gets time string from date input
|
||||
export const timeFromDate = (d: Date) => {
|
||||
let h = d.getHours() < 10 ? `0${d.getHours()}` : `${d.getHours()}`;
|
||||
let m = d.getMinutes() < 10 ? `0${d.getMinutes()}` : `${d.getMinutes()}`;
|
||||
|
||||
39
portal-ui/src/icons/CopyIcon.tsx
Normal file
39
portal-ui/src/icons/CopyIcon.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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 CopyIcon extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<SvgIcon>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<title>ic_h_copy-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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default CopyIcon;
|
||||
@@ -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;
|
||||
|
||||
@@ -15,21 +15,20 @@
|
||||
// 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 DeleteIcon extends React.Component {
|
||||
render() {
|
||||
return (<SvgIcon>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<title>ic_h_delete</title>
|
||||
<g id="Layer_2" data-name="Layer 2">
|
||||
<g id="Layer_1-2" data-name="Layer 1">
|
||||
<path className="cls-1"
|
||||
d="M0,8H0a8,8,0,0,0,8,8H8a8,8,0,0,0,8-8h0A8,8,0,0,0,8,0H8A8,8,0,0,0,0,8Zm10.007,3.489L8,9.482,5.993,11.489,4.511,10.007,6.518,8,4.511,5.993,5.993,4.511,8,6.518l2.007-2.007,1.482,1.482L9.482,8l2.007,2.007Z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</SvgIcon>)
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<SvgIcon>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10.402 13">
|
||||
<path
|
||||
d="M6.761 1V0H3.64v1H.004v1h10.4V1zM.004 2.998l1.672 10h7.052l1.673-10zm3.412 8.243l-.552-6.478h.653l.553 6.472zm3.569 0h-.653l.551-6.472h.654z"
|
||||
className="a"
|
||||
></path>
|
||||
</svg>
|
||||
</SvgIcon>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default DeleteIcon;
|
||||
|
||||
33
portal-ui/src/icons/DownloadIcon.tsx
Normal file
33
portal-ui/src/icons/DownloadIcon.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/SvgIcon";
|
||||
|
||||
class DownloadIcon extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<SvgIcon>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 12.996">
|
||||
<path d="M11.05 9.096v1.95h-9.1v-1.95H0v3.9h13v-3.9z"></path>
|
||||
<path d="M6.5 9.75L9 6.672H7.475V0h-1.95v6.672H4z"></path>
|
||||
</svg>
|
||||
</SvgIcon>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default DownloadIcon;
|
||||
39
portal-ui/src/icons/ShareIcon.tsx
Normal file
39
portal-ui/src/icons/ShareIcon.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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/SvgIcon";
|
||||
|
||||
class ShareIcon extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<SvgIcon>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 13">
|
||||
<path
|
||||
d="M11.05 8.617v2.429h-9.1v-9.1h2.429v-1.95H0v13h13V8.617z"
|
||||
className="a"
|
||||
></path>
|
||||
<path
|
||||
d="M3.854 9.256h1.95a4.945 4.945 0 013.6-4.74v1.3l.6-.487 2.474-2.012L9.4.817v1.7a6.9 6.9 0 00-5.546 6.739z"
|
||||
className="a"
|
||||
></path>
|
||||
</svg>
|
||||
</SvgIcon>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ShareIcon;
|
||||
41
portal-ui/src/icons/UploadFile.tsx
Normal file
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;
|
||||
@@ -15,6 +15,7 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export { default as PermissionIcon } from "./PermissionIcon";
|
||||
export { default as CopyIcon } from "./CopyIcon";
|
||||
export { default as CreateIcon } from "./CreateIcon";
|
||||
export { default as DeleteIcon } from "./DeleteIcon";
|
||||
export { default as ServiceAccountIcon } from "./ServiceAccountIcon";
|
||||
|
||||
@@ -21,6 +21,7 @@ import Routes from "./Routes";
|
||||
import configureStore from "./store";
|
||||
import * as serviceWorker from "./serviceWorker";
|
||||
import { ThemeProvider, withStyles } from "@material-ui/core/styles";
|
||||
import "react-virtualized/styles.css";
|
||||
|
||||
import "./index.css";
|
||||
import theme from "./theme/main";
|
||||
|
||||
@@ -23,7 +23,6 @@ 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 CheckboxWrapper from "../../Common/FormComponents/CheckboxWrapper/CheckboxWrapper";
|
||||
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
|
||||
import { factorForDropdown, getBytes } from "../../../../common/utils";
|
||||
import { AppState } from "../../../../store";
|
||||
@@ -68,7 +67,7 @@ const styles = (theme: Theme) =>
|
||||
interface IAddBucketProps {
|
||||
classes: any;
|
||||
open: boolean;
|
||||
closeModalAndRefresh: () => void;
|
||||
closeModalAndRefresh: (refresh: boolean) => void;
|
||||
addBucketName: typeof addBucketName;
|
||||
addBucketVersioned: typeof addBucketVersioned;
|
||||
addBucketQuota: typeof addBucketQuota;
|
||||
@@ -131,7 +130,7 @@ const AddBucket = ({
|
||||
.then((res) => {
|
||||
setAddLoading(false);
|
||||
setAddError("");
|
||||
closeModalAndRefresh();
|
||||
closeModalAndRefresh(true);
|
||||
})
|
||||
.catch((err) => {
|
||||
setAddLoading(false);
|
||||
@@ -143,7 +142,7 @@ const AddBucket = ({
|
||||
|
||||
useEffect(() => {
|
||||
addBucketName(value);
|
||||
}, [value]);
|
||||
}, [value, addBucketName]);
|
||||
|
||||
const resetForm = () => {
|
||||
setBName("");
|
||||
@@ -176,7 +175,7 @@ const AddBucket = ({
|
||||
modalOpen={open}
|
||||
onClose={() => {
|
||||
setAddError("");
|
||||
closeModalAndRefresh();
|
||||
closeModalAndRefresh(false);
|
||||
}}
|
||||
aria-labelledby="alert-dialog-title"
|
||||
aria-describedby="alert-dialog-description"
|
||||
@@ -222,7 +221,7 @@ const AddBucket = ({
|
||||
addBucketVersioned(event.target.checked);
|
||||
}}
|
||||
label={"Versioning"}
|
||||
indicatorLabel={"On"}
|
||||
indicatorLabels={["On", "Off"]}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
@@ -235,7 +234,7 @@ const AddBucket = ({
|
||||
addBucketQuota(event.target.checked);
|
||||
}}
|
||||
label={"Enable Bucket Quota"}
|
||||
indicatorLabel={"On"}
|
||||
indicatorLabels={["On", "Off"]}
|
||||
/>
|
||||
</Grid>
|
||||
{enableQuota && (
|
||||
|
||||
@@ -18,7 +18,6 @@ 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";
|
||||
@@ -93,7 +92,6 @@ const ListBuckets = ({
|
||||
const [totalRecords, setTotalRecords] = useState<number>(0);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [error, setError] = useState<string>("");
|
||||
const [deleteError, setDeleteError] = useState<string>("");
|
||||
const [page, setPage] = useState<number>(0);
|
||||
const [rowsPerPage, setRowsPerPage] = useState<number>(10);
|
||||
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
|
||||
@@ -136,10 +134,13 @@ const ListBuckets = ({
|
||||
}
|
||||
}, [loading, page, rowsPerPage]);
|
||||
|
||||
const closeAddModalAndRefresh = () => {
|
||||
const closeAddModalAndRefresh = (refresh: boolean) => {
|
||||
addBucketOpen(false);
|
||||
addBucketReset();
|
||||
setLoading(true);
|
||||
|
||||
if (refresh) {
|
||||
setLoading(true);
|
||||
}
|
||||
};
|
||||
|
||||
const closeDeleteModalAndRefresh = (refresh: boolean) => {
|
||||
@@ -184,28 +185,26 @@ const ListBuckets = ({
|
||||
return <Moment>{date}</Moment>;
|
||||
};
|
||||
|
||||
const filteredRecords = records
|
||||
.filter((b: Bucket) => {
|
||||
if (filterBuckets === "") {
|
||||
const filteredRecords = records.filter((b: Bucket) => {
|
||||
if (filterBuckets === "") {
|
||||
return true;
|
||||
} else {
|
||||
if (b.name.indexOf(filterBuckets) >= 0) {
|
||||
return true;
|
||||
} else {
|
||||
if (b.name.indexOf(filterBuckets) >= 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.slice(offset, offset + rowsPerPage);
|
||||
}
|
||||
});
|
||||
|
||||
const showInPage = filteredRecords;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{addBucketModalOpen && (
|
||||
<AddBucket
|
||||
open={addBucketModalOpen}
|
||||
closeModalAndRefresh={() => {
|
||||
closeAddModalAndRefresh();
|
||||
}}
|
||||
closeModalAndRefresh={closeAddModalAndRefresh}
|
||||
/>
|
||||
)}
|
||||
{deleteOpen && (
|
||||
@@ -219,6 +218,7 @@ const ListBuckets = ({
|
||||
)}
|
||||
<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
|
||||
@@ -266,26 +266,14 @@ const ListBuckets = ({
|
||||
label: "Size",
|
||||
elementKey: "size",
|
||||
renderFunction: niceBytes,
|
||||
width: 60,
|
||||
contentTextAlign: "right",
|
||||
},
|
||||
]}
|
||||
isLoading={loading}
|
||||
records={filteredRecords}
|
||||
records={showInPage}
|
||||
entityName="Buckets"
|
||||
idField="name"
|
||||
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,
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -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 } 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));
|
||||
@@ -14,6 +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, { 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";
|
||||
@@ -21,7 +22,6 @@ 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 React from "react";
|
||||
import TableWrapper from "../../../../Common/TableWrapper/TableWrapper";
|
||||
import { niceBytes } from "../../../../../../common/utils";
|
||||
import DeleteObject from "./DeleteObject";
|
||||
@@ -29,6 +29,7 @@ import DeleteObject from "./DeleteObject";
|
||||
import {
|
||||
actionsTray,
|
||||
containerForHeader,
|
||||
objectBrowserCommon,
|
||||
searchField,
|
||||
} from "../../../../Common/FormComponents/common/styleLibrary";
|
||||
import PageHeader from "../../../../Common/PageHeader/PageHeader";
|
||||
@@ -38,6 +39,28 @@ 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,
|
||||
setLastAsFile,
|
||||
} from "../../../../ObjectBrowser/actions";
|
||||
import { connect } from "react-redux";
|
||||
import { ObjectBrowserState, Route } from "../../../../ObjectBrowser/reducers";
|
||||
import CreateFolderModal from "./CreateFolderModal";
|
||||
import UploadFile from "../../../../../../icons/UploadFile";
|
||||
import { download } from "../utils";
|
||||
|
||||
const commonIcon = {
|
||||
backgroundRepeat: "no-repeat",
|
||||
backgroundPosition: "center center",
|
||||
width: 16,
|
||||
minWidth: 16,
|
||||
height: 40,
|
||||
marginRight: 10,
|
||||
};
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
@@ -69,93 +92,162 @@ const styles = (theme: Theme) =>
|
||||
},
|
||||
},
|
||||
},
|
||||
fileName: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
},
|
||||
fileNameText: {
|
||||
whiteSpace: "nowrap",
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
},
|
||||
iconFolder: {
|
||||
backgroundImage: "url(/images/ob_folder_clear.svg)",
|
||||
...commonIcon,
|
||||
},
|
||||
iconFile: {
|
||||
backgroundImage: "url(/images/ob_file_clear.svg)",
|
||||
...commonIcon,
|
||||
},
|
||||
buttonsContainer: {
|
||||
"& .MuiButtonBase-root": {
|
||||
marginLeft: 10,
|
||||
},
|
||||
},
|
||||
browsePaper: {
|
||||
height: "calc(100vh - 280px)",
|
||||
},
|
||||
"@global": {
|
||||
".rowLine:hover .iconFileElm": {
|
||||
backgroundImage: "url(/images/ob_file_filled.svg)",
|
||||
},
|
||||
".rowLine: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, param3: string) => any;
|
||||
setAllRoutes: (path: string) => any;
|
||||
routesList: Route[];
|
||||
setLastAsFile: () => any;
|
||||
}
|
||||
|
||||
interface IListObjectsState {
|
||||
records: BucketObject[];
|
||||
totalRecords: number;
|
||||
loading: boolean;
|
||||
error: string;
|
||||
deleteOpen: boolean;
|
||||
deleteError: string;
|
||||
selectedObject: string;
|
||||
selectedBucket: string;
|
||||
filterObjects: string;
|
||||
openSnackbar: boolean;
|
||||
snackBarMessage: string;
|
||||
interface ObjectBrowserReducer {
|
||||
objectBrowser: ObjectBrowserState;
|
||||
}
|
||||
|
||||
class ListObjects extends React.Component<
|
||||
IListObjectsProps,
|
||||
IListObjectsState
|
||||
> {
|
||||
state: IListObjectsState = {
|
||||
records: [],
|
||||
totalRecords: 0,
|
||||
loading: false,
|
||||
error: "",
|
||||
deleteOpen: false,
|
||||
deleteError: "",
|
||||
selectedObject: "",
|
||||
selectedBucket: "",
|
||||
filterObjects: "",
|
||||
openSnackbar: false,
|
||||
snackBarMessage: "",
|
||||
const ListObjects = ({
|
||||
classes,
|
||||
match,
|
||||
addRoute,
|
||||
setAllRoutes,
|
||||
routesList,
|
||||
setLastAsFile,
|
||||
}: 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) => {
|
||||
setSelectedBucket(bucketName);
|
||||
setRecords(res.objects || []);
|
||||
setTotalRecords(!res.objects ? 0 : res.total);
|
||||
setError("");
|
||||
// In case no objects were retrieved, We check if item is a file
|
||||
if (!res.objects && extraPath !== "") {
|
||||
verifyIfIsFile();
|
||||
return;
|
||||
}
|
||||
setLoading(false);
|
||||
})
|
||||
.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 verifyIfIsFile = () => {
|
||||
const bucketName = match.params["bucket"];
|
||||
const internalPaths = match.params[0];
|
||||
|
||||
api
|
||||
.invoke(
|
||||
"GET",
|
||||
`/api/v1/buckets/${bucketName}/objects?prefix=${internalPaths}`
|
||||
)
|
||||
.then((res: BucketObjectsList) => {
|
||||
//It is a file since it has elements in the object, setting file flag and waiting for component mount
|
||||
if (res.objects !== null) {
|
||||
setLastAsFile();
|
||||
} else {
|
||||
// It is a folder, we remove loader
|
||||
setLoading(false);
|
||||
}
|
||||
})
|
||||
.catch((err: any) => {
|
||||
setLoading(false);
|
||||
setError(err);
|
||||
});
|
||||
};
|
||||
|
||||
fetchRecords = () => {
|
||||
this.setState({ loading: true }, () => {
|
||||
const { match } = this.props;
|
||||
const bucketName = match.params["bucket"];
|
||||
api
|
||||
.invoke("GET", `/api/v1/buckets/${bucketName}/objects`)
|
||||
.then((res: BucketObjectsList) => {
|
||||
this.setState({
|
||||
loading: false,
|
||||
selectedBucket: bucketName,
|
||||
records: res.objects || [],
|
||||
totalRecords: !res.objects ? 0 : res.total,
|
||||
error: "",
|
||||
});
|
||||
// TODO:
|
||||
// if we get 0 results, and page > 0 , go down 1 page
|
||||
})
|
||||
.catch((err: any) => {
|
||||
this.setState({ loading: false, error: err });
|
||||
});
|
||||
});
|
||||
const closeDeleteModalAndRefresh = (refresh: boolean) => {
|
||||
setDeleteOpen(false);
|
||||
|
||||
if (refresh) {
|
||||
setLoading(true);
|
||||
}
|
||||
};
|
||||
|
||||
componentDidMount(): void {
|
||||
this.fetchRecords();
|
||||
}
|
||||
const closeAddFolderModal = () => {
|
||||
setCreateFolderOpen(false);
|
||||
};
|
||||
|
||||
closeDeleteModalAndRefresh(refresh: boolean) {
|
||||
this.setState({ deleteOpen: false }, () => {
|
||||
if (refresh) {
|
||||
this.fetchRecords();
|
||||
}
|
||||
});
|
||||
}
|
||||
const showSnackBarMessage = (text: string) => {
|
||||
setSnackbarMessage(text);
|
||||
setOpenSnackbar(true);
|
||||
};
|
||||
|
||||
showSnackBarMessage(text: string) {
|
||||
this.setState({ openSnackbar: true, snackBarMessage: text });
|
||||
}
|
||||
const closeSnackBar = () => {
|
||||
setSnackbarMessage("");
|
||||
setOpenSnackbar(false);
|
||||
};
|
||||
|
||||
closeSnackBar() {
|
||||
this.setState({ openSnackbar: false, snackBarMessage: `` });
|
||||
}
|
||||
|
||||
upload(e: any, bucketName: string, path: string) {
|
||||
let listObjects = this;
|
||||
const upload = (e: any, bucketName: string, path: string) => {
|
||||
if (isNullOrUndefined(e) || isNullOrUndefined(e.target)) {
|
||||
return;
|
||||
}
|
||||
@@ -169,30 +261,25 @@ class ListObjects extends React.Component<
|
||||
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) {
|
||||
listObjects.showSnackBarMessage(
|
||||
"An error occurred while uploading the file."
|
||||
);
|
||||
if (xhr.status === 401 || xhr.status === 403) {
|
||||
showSnackBarMessage("An error occurred while uploading the file.");
|
||||
}
|
||||
if (xhr.status == 500) {
|
||||
listObjects.showSnackBarMessage(
|
||||
"An error occurred while uploading the file."
|
||||
);
|
||||
if (xhr.status === 500) {
|
||||
showSnackBarMessage("An error occurred while uploading the file.");
|
||||
}
|
||||
if (xhr.status == 200) {
|
||||
listObjects.showSnackBarMessage("Object uploaded successfully.");
|
||||
listObjects.fetchRecords();
|
||||
if (xhr.status === 200) {
|
||||
showSnackBarMessage("Object uploaded successfully.");
|
||||
setLoading(true);
|
||||
}
|
||||
};
|
||||
|
||||
xhr.upload.addEventListener("error", (event) => {
|
||||
// TODO: handle error
|
||||
this.showSnackBarMessage("An error occurred while uploading the file.");
|
||||
showSnackBarMessage("An error occurred while uploading the file.");
|
||||
});
|
||||
|
||||
xhr.upload.addEventListener("progress", (event) => {
|
||||
@@ -200,201 +287,246 @@ class ListObjects extends React.Component<
|
||||
});
|
||||
|
||||
xhr.onerror = () => {
|
||||
listObjects.showSnackBarMessage(
|
||||
"An error occurred while uploading the file."
|
||||
);
|
||||
showSnackBarMessage("An error occurred while uploading the file.");
|
||||
};
|
||||
|
||||
var formData = new FormData();
|
||||
var blobFile = new Blob([file]);
|
||||
const formData = new FormData();
|
||||
const blobFile = new Blob([file]);
|
||||
|
||||
formData.append("upfile", blobFile);
|
||||
xhr.send(formData);
|
||||
e.target.value = null;
|
||||
}
|
||||
};
|
||||
|
||||
download(bucketName: string, objectName: string) {
|
||||
var anchor = document.createElement("a");
|
||||
document.body.appendChild(anchor);
|
||||
const token: string = storage.getItem("token")!;
|
||||
var xhr = new XMLHttpRequest();
|
||||
const displayParsedDate = (date: string) => {
|
||||
return <reactMoment.default>{date}</reactMoment.default>;
|
||||
};
|
||||
|
||||
xhr.open(
|
||||
"GET",
|
||||
`/api/v1/buckets/${bucketName}/objects/download?prefix=${objectName}`,
|
||||
true
|
||||
);
|
||||
xhr.setRequestHeader("Authorization", `Bearer ${token}`);
|
||||
xhr.responseType = "blob";
|
||||
const confirmDeleteObject = (object: string) => {
|
||||
setDeleteOpen(true);
|
||||
setSelectedObject(object);
|
||||
};
|
||||
|
||||
xhr.onload = function (e) {
|
||||
if (this.status == 200) {
|
||||
var blob = new Blob([this.response], {
|
||||
type: "octet/stream",
|
||||
});
|
||||
var blobUrl = window.URL.createObjectURL(blob);
|
||||
const downloadObject = (object: string) => {
|
||||
download(selectedBucket, object);
|
||||
};
|
||||
|
||||
anchor.href = blobUrl;
|
||||
anchor.download = objectName;
|
||||
const openPath = (idElement: string) => {
|
||||
const currentPath = get(match, "url", "/object-browser");
|
||||
|
||||
anchor.click();
|
||||
window.URL.revokeObjectURL(blobUrl);
|
||||
anchor.remove();
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
}
|
||||
// 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]}`;
|
||||
|
||||
bucketFilter(): void {}
|
||||
addRoute(newPath, idElementClean[lastIndex], "path");
|
||||
return;
|
||||
}
|
||||
// Element is a file. we open details here
|
||||
const pathInArray = idElement.split("/");
|
||||
const fileName = pathInArray[pathInArray.length - 1];
|
||||
const newPath = `${currentPath}/${fileName}`;
|
||||
|
||||
render() {
|
||||
const { classes } = this.props;
|
||||
const {
|
||||
records,
|
||||
loading,
|
||||
selectedObject,
|
||||
selectedBucket,
|
||||
deleteOpen,
|
||||
filterObjects,
|
||||
snackBarMessage,
|
||||
openSnackbar,
|
||||
} = this.state;
|
||||
const displayParsedDate = (date: string) => {
|
||||
return <reactMoment.default>{date}</reactMoment.default>;
|
||||
};
|
||||
addRoute(newPath, fileName, "file");
|
||||
return;
|
||||
};
|
||||
|
||||
const confirmDeleteObject = (object: string) => {
|
||||
this.setState({ deleteOpen: true, selectedObject: object });
|
||||
};
|
||||
const uploadObject = (e: any): void => {
|
||||
// Handle of deeper routes.
|
||||
const currentPath = routesList[routesList.length - 1].route;
|
||||
const splitPaths = currentPath
|
||||
.split("/")
|
||||
.filter((item) => item.trim() !== "");
|
||||
|
||||
const downloadObject = (object: string) => {
|
||||
this.download(selectedBucket, object);
|
||||
};
|
||||
let path = "";
|
||||
|
||||
const uploadObject = (e: any): void => {
|
||||
// TODO: handle deeper paths/folders
|
||||
let file = e.target.files[0];
|
||||
this.showSnackBarMessage(`Uploading: ${file.name}`);
|
||||
this.upload(e, selectedBucket, "");
|
||||
};
|
||||
if (splitPaths.length > 2) {
|
||||
path = `${splitPaths.slice(2).join("/")}/`;
|
||||
}
|
||||
|
||||
const snackBarAction = (
|
||||
<Button
|
||||
color="secondary"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
this.closeSnackBar();
|
||||
}}
|
||||
>
|
||||
Dismiss
|
||||
</Button>
|
||||
);
|
||||
let file = e.target.files[0];
|
||||
showSnackBarMessage(`Uploading: ${file.name}`);
|
||||
upload(e, selectedBucket, path);
|
||||
};
|
||||
|
||||
const tableActions = [
|
||||
{ type: "download", onClick: downloadObject, sendOnlyId: true },
|
||||
{ type: "delete", onClick: confirmDeleteObject, sendOnlyId: true },
|
||||
];
|
||||
const snackBarAction = (
|
||||
<Button
|
||||
color="secondary"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
closeSnackBar();
|
||||
}}
|
||||
>
|
||||
Dismiss
|
||||
</Button>
|
||||
);
|
||||
|
||||
const filteredRecords = records.filter((b: BucketObject) => {
|
||||
if (filterObjects === "") {
|
||||
return true;
|
||||
} else {
|
||||
if (b.name.indexOf(filterObjects) >= 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
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 (
|
||||
<React.Fragment>
|
||||
{deleteOpen && (
|
||||
<DeleteObject
|
||||
deleteOpen={deleteOpen}
|
||||
selectedBucket={selectedBucket}
|
||||
selectedObject={selectedObject}
|
||||
closeDeleteModalAndRefresh={(refresh: boolean) => {
|
||||
this.closeDeleteModalAndRefresh(refresh);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Snackbar
|
||||
open={openSnackbar}
|
||||
message={snackBarMessage}
|
||||
action={snackBarAction}
|
||||
/>
|
||||
<PageHeader label="Objects" />
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.container}>
|
||||
<Grid item xs={12} className={classes.actionsTray}>
|
||||
<TextField
|
||||
placeholder="Search Objects"
|
||||
className={classes.searchField}
|
||||
id="search-resource"
|
||||
label=""
|
||||
onChange={(val) => {
|
||||
this.setState({
|
||||
filterObjects: val.target.value,
|
||||
});
|
||||
}}
|
||||
InputProps={{
|
||||
disableUnderline: true,
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<SearchIcon />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<div className={classes.fileName}>
|
||||
<div className={icon} />
|
||||
<span className={classes.fileNameText}>
|
||||
{splitItem[splitItem.length - 1]}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
<>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
startIcon={<CreateIcon />}
|
||||
component="label"
|
||||
>
|
||||
Upload Object
|
||||
<Input
|
||||
type="file"
|
||||
onChange={(e) => uploadObject(e)}
|
||||
id="file-input"
|
||||
style={{ display: "none" }}
|
||||
/>
|
||||
</Button>
|
||||
</>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<br />
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<TableWrapper
|
||||
itemActions={tableActions}
|
||||
columns={[
|
||||
{ label: "Name", elementKey: "name" },
|
||||
{
|
||||
label: "Last Modified",
|
||||
elementKey: "last_modified",
|
||||
renderFunction: displayParsedDate,
|
||||
},
|
||||
{
|
||||
label: "Size",
|
||||
elementKey: "size",
|
||||
renderFunction: niceBytes,
|
||||
},
|
||||
]}
|
||||
isLoading={loading}
|
||||
entityName="Objects"
|
||||
idField="name"
|
||||
records={filteredRecords}
|
||||
/>
|
||||
</Grid>
|
||||
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,
|
||||
width: 60,
|
||||
contentTextAlign: "right",
|
||||
},
|
||||
]}
|
||||
isLoading={loading}
|
||||
entityName="Objects"
|
||||
idField="name"
|
||||
records={filteredRecords}
|
||||
customPaperHeight={classes.browsePaper}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(ListObjects);
|
||||
const mapStateToProps = ({ objectBrowser }: ObjectBrowserReducer) => ({
|
||||
routesList: get(objectBrowser, "routesList", []),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = {
|
||||
addRoute,
|
||||
setAllRoutes,
|
||||
setLastAsFile,
|
||||
};
|
||||
|
||||
const connector = connect(mapStateToProps, mapDispatchToProps);
|
||||
|
||||
export default withRouter(connector(withStyles(styles)(ListObjects)));
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
// 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, { useEffect } from "react";
|
||||
import ListObjects from "./ListObjects";
|
||||
import ObjectDetails from "../ObjectDetails/ObjectDetails";
|
||||
import get from "lodash/get";
|
||||
import { setAllRoutes } from "../../../../ObjectBrowser/actions";
|
||||
import { connect } from "react-redux";
|
||||
import { withRouter } from "react-router-dom";
|
||||
import { ObjectBrowserState, Route } from "../../../../ObjectBrowser/reducers";
|
||||
|
||||
interface ObjectBrowserReducer {
|
||||
objectBrowser: ObjectBrowserState;
|
||||
}
|
||||
|
||||
interface ObjectRoutingProps {
|
||||
routesList: Route[];
|
||||
setAllRoutes: (path: string) => any;
|
||||
match: any;
|
||||
}
|
||||
|
||||
const ObjectRouting = ({
|
||||
routesList,
|
||||
match,
|
||||
setAllRoutes,
|
||||
}: ObjectRoutingProps) => {
|
||||
const currentItem = routesList[routesList.length - 1];
|
||||
|
||||
useEffect(() => {
|
||||
const url = get(match, "url", "/object-browser");
|
||||
|
||||
if (url !== routesList[routesList.length - 1].route) {
|
||||
setAllRoutes(url);
|
||||
}
|
||||
}, [match, routesList, setAllRoutes]);
|
||||
|
||||
return currentItem.type === "path" ? (
|
||||
<ListObjects />
|
||||
) : (
|
||||
<ObjectDetails routesList={routesList} />
|
||||
);
|
||||
};
|
||||
|
||||
const mapStateToProps = ({ objectBrowser }: ObjectBrowserReducer) => ({
|
||||
routesList: get(objectBrowser, "routesList", []),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = {
|
||||
setAllRoutes,
|
||||
};
|
||||
|
||||
const connector = connect(mapStateToProps, mapDispatchToProps);
|
||||
|
||||
export default withRouter(connector(ObjectRouting));
|
||||
@@ -0,0 +1,138 @@
|
||||
import React, { useState } from "react";
|
||||
import { Button, Grid } from "@material-ui/core";
|
||||
import InputBoxWrapper from "../../../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||
import ModalWrapper from "../../../../Common/ModalWrapper/ModalWrapper";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import { modalBasic } from "../../../../Common/FormComponents/common/styleLibrary";
|
||||
import api from "../../../../../../common/api";
|
||||
|
||||
interface ITagModal {
|
||||
modalOpen: boolean;
|
||||
currentTags: any;
|
||||
bucketName: string;
|
||||
versionId: string;
|
||||
onCloseAndUpdate: (refresh: boolean) => void;
|
||||
selectedObject: string;
|
||||
classes: any;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
buttonContainer: {
|
||||
textAlign: "right",
|
||||
},
|
||||
pathLabel: {
|
||||
marginTop: 0,
|
||||
marginBottom: 32,
|
||||
},
|
||||
...modalBasic,
|
||||
});
|
||||
|
||||
const AddTagModal = ({
|
||||
modalOpen,
|
||||
currentTags,
|
||||
selectedObject,
|
||||
onCloseAndUpdate,
|
||||
bucketName,
|
||||
versionId,
|
||||
classes,
|
||||
}: ITagModal) => {
|
||||
const [newKey, setNewKey] = useState<string>("");
|
||||
const [newLabel, setNewLabel] = useState<string>("");
|
||||
const [error, setError] = useState<string>("");
|
||||
const [isSending, setIsSending] = useState<boolean>(false);
|
||||
|
||||
const resetForm = () => {
|
||||
setNewLabel("");
|
||||
setNewKey("");
|
||||
};
|
||||
|
||||
const addTagProcess = () => {
|
||||
setIsSending(true);
|
||||
const newTag: any = {};
|
||||
|
||||
newTag[newKey] = newLabel;
|
||||
const newTagList = { ...currentTags, ...newTag };
|
||||
|
||||
api
|
||||
.invoke(
|
||||
"PUT",
|
||||
`/api/v1/buckets/${bucketName}/objects/tags?prefix=${selectedObject}&version_id=${versionId}`,
|
||||
{ tags: newTagList }
|
||||
)
|
||||
.then((res: any) => {
|
||||
setIsSending(false);
|
||||
onCloseAndUpdate(true);
|
||||
})
|
||||
.catch((error) => {
|
||||
setError(error);
|
||||
setIsSending(false);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<ModalWrapper
|
||||
modalOpen={modalOpen}
|
||||
title="Add New Tag"
|
||||
onClose={() => {
|
||||
onCloseAndUpdate(false);
|
||||
}}
|
||||
>
|
||||
<Grid container>
|
||||
<h3 className={classes.pathLabel}>
|
||||
Selected Object: {selectedObject}
|
||||
</h3>
|
||||
{error !== "" && <span>{error}</span>}
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
value={newKey}
|
||||
label={"New Tag Key"}
|
||||
id={"newTagKey"}
|
||||
name={"newTagKey"}
|
||||
placeholder={"Enter New Tag Key"}
|
||||
onChange={(e) => {
|
||||
setNewKey(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
value={newLabel}
|
||||
label={"New Tag Label"}
|
||||
id={"newTagLabel"}
|
||||
name={"newTagLabel"}
|
||||
placeholder={"Enter New Tag Label"}
|
||||
onChange={(e) => {
|
||||
setNewLabel(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={
|
||||
newLabel.trim() === "" || newKey.trim() === "" || isSending
|
||||
}
|
||||
onClick={addTagProcess}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ModalWrapper>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(AddTagModal);
|
||||
@@ -0,0 +1,125 @@
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogContentText,
|
||||
DialogTitle,
|
||||
Grid,
|
||||
LinearProgress,
|
||||
} from "@material-ui/core";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import { modalBasic } from "../../../../Common/FormComponents/common/styleLibrary";
|
||||
import api from "../../../../../../common/api";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
|
||||
interface IDeleteTagModal {
|
||||
deleteOpen: boolean;
|
||||
currentTags: any;
|
||||
bucketName: string;
|
||||
versionId: string;
|
||||
selectedTag: [string, string];
|
||||
onCloseAndUpdate: (refresh: boolean) => void;
|
||||
selectedObject: string;
|
||||
classes: any;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
buttonContainer: {
|
||||
textAlign: "right",
|
||||
},
|
||||
pathLabel: {
|
||||
marginTop: 0,
|
||||
marginBottom: 32,
|
||||
},
|
||||
...modalBasic,
|
||||
});
|
||||
|
||||
const DeleteTagModal = ({
|
||||
deleteOpen,
|
||||
currentTags,
|
||||
selectedObject,
|
||||
selectedTag,
|
||||
onCloseAndUpdate,
|
||||
bucketName,
|
||||
versionId,
|
||||
classes,
|
||||
}: IDeleteTagModal) => {
|
||||
const [deleteError, setDeleteError] = useState<string>("");
|
||||
const [deleteLoading, setDeleteSending] = useState<boolean>(false);
|
||||
const [tagKey, tagLabel] = selectedTag;
|
||||
|
||||
const removeTagProcess = () => {
|
||||
setDeleteSending(true);
|
||||
const cleanObject = { ...currentTags };
|
||||
delete cleanObject[tagKey];
|
||||
|
||||
api
|
||||
.invoke(
|
||||
"PUT",
|
||||
`/api/v1/buckets/${bucketName}/objects/tags?prefix=${selectedObject}&version_id=${versionId}`,
|
||||
{ tags: cleanObject }
|
||||
)
|
||||
.then((res: any) => {
|
||||
setDeleteSending(false);
|
||||
onCloseAndUpdate(true);
|
||||
})
|
||||
.catch((error) => {
|
||||
setDeleteError(error);
|
||||
setDeleteSending(false);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={deleteOpen}
|
||||
onClose={() => {
|
||||
onCloseAndUpdate(false);
|
||||
}}
|
||||
aria-labelledby="alert-dialog-title"
|
||||
aria-describedby="alert-dialog-description"
|
||||
>
|
||||
<DialogTitle id="alert-dialog-title">Delete Tag</DialogTitle>
|
||||
<DialogContent>
|
||||
{deleteLoading && <LinearProgress />}
|
||||
<DialogContentText id="alert-dialog-description">
|
||||
Are you sure you want to delete the tag{" "}
|
||||
<b className={classes.wrapText}>
|
||||
{tagKey} : {tagLabel}
|
||||
</b>{" "}
|
||||
from {selectedObject}?
|
||||
{deleteError !== "" && (
|
||||
<React.Fragment>
|
||||
<br />
|
||||
<Typography
|
||||
component="p"
|
||||
variant="body1"
|
||||
className={classes.errorBlock}
|
||||
>
|
||||
{deleteError}
|
||||
</Typography>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={() => {
|
||||
onCloseAndUpdate(false);
|
||||
}}
|
||||
color="primary"
|
||||
disabled={deleteLoading}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button onClick={removeTagProcess} color="secondary" autoFocus>
|
||||
Delete
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(DeleteTagModal);
|
||||
@@ -0,0 +1,508 @@
|
||||
// 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 get from "lodash/get";
|
||||
import * as reactMoment from "react-moment";
|
||||
import clsx from "clsx";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import Chip from "@material-ui/core/Chip";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import IconButton from "@material-ui/core/IconButton";
|
||||
import InputAdornment from "@material-ui/core/InputAdornment";
|
||||
import SearchIcon from "@material-ui/icons/Search";
|
||||
import AddIcon from "@material-ui/icons/Add";
|
||||
import CloseIcon from "@material-ui/icons/Close";
|
||||
import ShareFile from "./ShareFile";
|
||||
import {
|
||||
actionsTray,
|
||||
containerForHeader,
|
||||
searchField,
|
||||
} from "../../../../Common/FormComponents/common/styleLibrary";
|
||||
import history from "../../../../../../history";
|
||||
import { Route } from "../../../../ObjectBrowser/reducers";
|
||||
import { download } from "../utils";
|
||||
import api from "../../../../../../common/api";
|
||||
import PageHeader from "../../../../Common/PageHeader/PageHeader";
|
||||
import ShareIcon from "../../../../../../icons/ShareIcon";
|
||||
import DownloadIcon from "../../../../../../icons/DownloadIcon";
|
||||
import DeleteIcon from "../../../../../../icons/DeleteIcon";
|
||||
import TableWrapper from "../../../../Common/TableWrapper/TableWrapper";
|
||||
import PencilIcon from "../../../../Common/TableWrapper/TableActionIcons/PencilIcon";
|
||||
import SetRetention from "./SetRetention";
|
||||
import BrowserBreadcrumbs from "../../../../ObjectBrowser/BrowserBreadcrumbs";
|
||||
import DeleteObject from "../ListObjects/DeleteObject";
|
||||
import { removeRouteLevel } from "../../../../ObjectBrowser/actions";
|
||||
import { connect } from "react-redux";
|
||||
import AddTagModal from "./AddTagModal";
|
||||
import DeleteTagModal from "./DeleteTagModal";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
objectNameContainer: {
|
||||
marginBottom: 8,
|
||||
},
|
||||
objectPathContainer: {
|
||||
marginBottom: 26,
|
||||
fontSize: 10,
|
||||
},
|
||||
objectPathLink: {
|
||||
"&:visited": {
|
||||
color: "#000",
|
||||
},
|
||||
},
|
||||
objectName: {
|
||||
fontSize: 24,
|
||||
},
|
||||
propertiesContainer: {
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
marginBottom: 15,
|
||||
},
|
||||
propertiesItem: {
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
marginRight: 21,
|
||||
},
|
||||
propertiesItemBold: {
|
||||
fontWeight: 700,
|
||||
},
|
||||
propertiesValue: {
|
||||
marginLeft: 8,
|
||||
textTransform: "capitalize",
|
||||
},
|
||||
propertiesIcon: {
|
||||
marginLeft: 5,
|
||||
},
|
||||
actionsIconContainer: {
|
||||
marginLeft: 12,
|
||||
},
|
||||
actionsIcon: {
|
||||
height: 16,
|
||||
width: 16,
|
||||
"& .MuiSvgIcon-root": {
|
||||
height: 16,
|
||||
},
|
||||
},
|
||||
tagsContainer: {
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginBottom: 15,
|
||||
},
|
||||
tagText: {
|
||||
marginRight: 13,
|
||||
},
|
||||
tag: {
|
||||
marginRight: 6,
|
||||
fontSize: 10,
|
||||
fontWeight: 700,
|
||||
"&.MuiChip-sizeSmall": {
|
||||
height: 18,
|
||||
},
|
||||
"& .MuiSvgIcon-root": {
|
||||
height: 10,
|
||||
width: 10,
|
||||
},
|
||||
},
|
||||
search: {
|
||||
marginBottom: 8,
|
||||
"&.MuiFormControl-root": {
|
||||
marginRight: 0,
|
||||
},
|
||||
},
|
||||
...actionsTray,
|
||||
...searchField,
|
||||
...containerForHeader(theme.spacing(4)),
|
||||
});
|
||||
|
||||
interface IObjectDetailsProps {
|
||||
classes: any;
|
||||
routesList: Route[];
|
||||
removeRouteLevel: (newRoute: string) => any;
|
||||
}
|
||||
|
||||
interface IFileInfo {
|
||||
is_latest?: boolean;
|
||||
last_modified: string;
|
||||
legal_hold_status?: string;
|
||||
name: string;
|
||||
retention_mode?: string;
|
||||
retention_until_date?: string;
|
||||
size?: string;
|
||||
tags?: object;
|
||||
version_id: string;
|
||||
}
|
||||
|
||||
const emptyFile: IFileInfo = {
|
||||
is_latest: true,
|
||||
last_modified: "",
|
||||
legal_hold_status: "",
|
||||
name: "",
|
||||
retention_mode: "",
|
||||
retention_until_date: "",
|
||||
size: "0",
|
||||
tags: {},
|
||||
version_id: "",
|
||||
};
|
||||
|
||||
const ObjectDetails = ({
|
||||
classes,
|
||||
routesList,
|
||||
removeRouteLevel,
|
||||
}: IObjectDetailsProps) => {
|
||||
const [loadObjectData, setLoadObjectData] = useState<boolean>(true);
|
||||
const [shareFileModalOpen, setShareFileModalOpen] = useState<boolean>(false);
|
||||
const [retentionModalOpen, setRetentionModalOpen] = useState<boolean>(false);
|
||||
const [tagModalOpen, setTagModalOpen] = useState<boolean>(false);
|
||||
const [deleteTagModalOpen, setDeleteTagModalOpen] = useState<boolean>(false);
|
||||
const [selectedTag, setSelectedTag] = useState<[string, string]>(["", ""]);
|
||||
const [actualInfo, setActualInfo] = useState<IFileInfo>(emptyFile);
|
||||
const [versions, setVersions] = useState<IFileInfo[]>([]);
|
||||
const [filterVersion, setFilterVersion] = useState<string>("");
|
||||
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
|
||||
const [error, setError] = useState<string>("");
|
||||
|
||||
const currentItem = routesList[routesList.length - 1];
|
||||
const allPathData = currentItem.route.split("/");
|
||||
const objectName = allPathData[allPathData.length - 1];
|
||||
const bucketName = allPathData[2];
|
||||
const pathInBucket = allPathData.slice(3).join("/");
|
||||
|
||||
useEffect(() => {
|
||||
if (loadObjectData) {
|
||||
api
|
||||
.invoke(
|
||||
"GET",
|
||||
`/api/v1/buckets/${bucketName}/objects?prefix=${pathInBucket}&with_versions=true`
|
||||
)
|
||||
.then((res: IFileInfo[]) => {
|
||||
const result = get(res, "objects", []);
|
||||
setActualInfo(
|
||||
result.find((el: IFileInfo) => el.is_latest) || emptyFile
|
||||
);
|
||||
setVersions(result.filter((el: IFileInfo) => !el.is_latest));
|
||||
setLoadObjectData(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
setError(error);
|
||||
setLoadObjectData(false);
|
||||
});
|
||||
}
|
||||
}, [loadObjectData]);
|
||||
|
||||
let tagKeys: string[] = [];
|
||||
|
||||
if (actualInfo.tags) {
|
||||
tagKeys = Object.keys(actualInfo.tags);
|
||||
}
|
||||
|
||||
const openRetentionModal = () => {
|
||||
setRetentionModalOpen(true);
|
||||
console.log("open retention modal");
|
||||
};
|
||||
|
||||
const closeRetentionModal = () => {
|
||||
setRetentionModalOpen(false);
|
||||
console.log("close retention modal");
|
||||
};
|
||||
|
||||
const shareObject = () => {
|
||||
setShareFileModalOpen(true);
|
||||
console.log("share object");
|
||||
};
|
||||
|
||||
const closeShareModal = () => {
|
||||
setShareFileModalOpen(false);
|
||||
console.log("close share modal");
|
||||
};
|
||||
|
||||
const deleteTag = (tagKey: string, tagLabel: string) => {
|
||||
setSelectedTag([tagKey, tagLabel]);
|
||||
setDeleteTagModalOpen(true);
|
||||
};
|
||||
|
||||
const downloadObject = (path: string) => {
|
||||
download(bucketName, path);
|
||||
};
|
||||
|
||||
const tableActions = [
|
||||
{ type: "share", onClick: shareObject, sendOnlyId: true },
|
||||
{ type: "download", onClick: downloadObject, sendOnlyId: true },
|
||||
];
|
||||
|
||||
const filteredRecords = versions.filter((version) =>
|
||||
version.version_id.includes(filterVersion)
|
||||
);
|
||||
|
||||
const displayParsedDate = (date: string) => {
|
||||
return <reactMoment.default>{date}</reactMoment.default>;
|
||||
};
|
||||
|
||||
const closeDeleteModal = (redirectBack: boolean) => {
|
||||
setDeleteOpen(false);
|
||||
|
||||
if (redirectBack) {
|
||||
const newPath = allPathData.slice(0, -1).join("/");
|
||||
|
||||
removeRouteLevel(newPath);
|
||||
history.push(newPath);
|
||||
}
|
||||
};
|
||||
|
||||
const closeAddTagModal = (reloadObjectData: boolean) => {
|
||||
setTagModalOpen(false);
|
||||
|
||||
if (reloadObjectData) {
|
||||
setLoadObjectData(true);
|
||||
}
|
||||
};
|
||||
|
||||
const closeDeleteTagModal = (reloadObjectData: boolean) => {
|
||||
setDeleteTagModalOpen(false);
|
||||
|
||||
if (reloadObjectData) {
|
||||
setLoadObjectData(true);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<PageHeader label={"Object Browser"} />
|
||||
{shareFileModalOpen && (
|
||||
<ShareFile
|
||||
open={shareFileModalOpen}
|
||||
closeModalAndRefresh={closeShareModal}
|
||||
/>
|
||||
)}
|
||||
{retentionModalOpen && (
|
||||
<SetRetention
|
||||
open={retentionModalOpen}
|
||||
closeModalAndRefresh={closeRetentionModal}
|
||||
objectName={objectName}
|
||||
/>
|
||||
)}
|
||||
{deleteOpen && (
|
||||
<DeleteObject
|
||||
deleteOpen={deleteOpen}
|
||||
selectedBucket={bucketName}
|
||||
selectedObject={pathInBucket}
|
||||
closeDeleteModalAndRefresh={closeDeleteModal}
|
||||
/>
|
||||
)}
|
||||
{tagModalOpen && (
|
||||
<AddTagModal
|
||||
modalOpen={tagModalOpen}
|
||||
currentTags={actualInfo.tags}
|
||||
selectedObject={pathInBucket}
|
||||
versionId={actualInfo.version_id}
|
||||
bucketName={bucketName}
|
||||
onCloseAndUpdate={closeAddTagModal}
|
||||
/>
|
||||
)}
|
||||
{deleteTagModalOpen && (
|
||||
<DeleteTagModal
|
||||
deleteOpen={deleteTagModalOpen}
|
||||
currentTags={actualInfo.tags}
|
||||
selectedObject={pathInBucket}
|
||||
versionId={actualInfo.version_id}
|
||||
bucketName={bucketName}
|
||||
onCloseAndUpdate={closeDeleteTagModal}
|
||||
selectedTag={selectedTag}
|
||||
/>
|
||||
)}
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.container}>
|
||||
<Grid item xs={12} className={classes.obTitleSection}>
|
||||
<div>
|
||||
<BrowserBreadcrumbs />
|
||||
</div>
|
||||
</Grid>
|
||||
<br />
|
||||
<Grid item xs={12} className={classes.propertiesContainer}>
|
||||
<div className={classes.propertiesItem}>
|
||||
<div>
|
||||
<span className={classes.propertiesItemBold}>Legal Hold:</span>
|
||||
<span className={classes.propertiesValue}>
|
||||
{actualInfo.legal_hold_status
|
||||
? actualInfo.legal_hold_status.toLowerCase()
|
||||
: "Off"}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<IconButton
|
||||
color="primary"
|
||||
aria-label="legal-hold"
|
||||
size="small"
|
||||
className={classes.propertiesIcon}
|
||||
onClick={() => {
|
||||
console.log("open legal hold modal");
|
||||
}}
|
||||
>
|
||||
<PencilIcon active={true} />
|
||||
</IconButton>
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.propertiesItem}>
|
||||
<div>
|
||||
<span className={classes.propertiesItemBold}>Retention:</span>
|
||||
<span className={classes.propertiesValue}>
|
||||
{actualInfo.retention_mode
|
||||
? actualInfo.retention_mode.toLowerCase()
|
||||
: "Undefined"}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<IconButton
|
||||
color="primary"
|
||||
aria-label="retention"
|
||||
size="small"
|
||||
className={classes.propertiesIcon}
|
||||
onClick={() => {
|
||||
openRetentionModal();
|
||||
}}
|
||||
>
|
||||
<PencilIcon active={true} />
|
||||
</IconButton>
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.propertiesItem}>
|
||||
<div className={classes.propertiesItemBold}>File Actions:</div>
|
||||
<div className={classes.actionsIconContainer}>
|
||||
<IconButton
|
||||
color="primary"
|
||||
aria-label="share"
|
||||
size="small"
|
||||
className={classes.actionsIcon}
|
||||
onClick={() => {
|
||||
shareObject();
|
||||
}}
|
||||
>
|
||||
<ShareIcon />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div className={classes.actionsIconContainer}>
|
||||
<IconButton
|
||||
color="primary"
|
||||
aria-label="download"
|
||||
size="small"
|
||||
className={classes.actionsIcon}
|
||||
onClick={() => {
|
||||
downloadObject(pathInBucket);
|
||||
}}
|
||||
>
|
||||
<DownloadIcon />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div className={classes.actionsIconContainer}>
|
||||
<IconButton
|
||||
color="primary"
|
||||
aria-label="delete"
|
||||
size="small"
|
||||
className={classes.actionsIcon}
|
||||
onClick={() => {
|
||||
setDeleteOpen(true);
|
||||
}}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
</div>
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.tagsContainer}>
|
||||
<div className={classes.tagText}>Tags:</div>
|
||||
{tagKeys.map((tagKey, index) => {
|
||||
const tag = get(actualInfo, `tags.${tagKey}`, "");
|
||||
if (tag !== "") {
|
||||
return (
|
||||
<Chip
|
||||
key={`chip-${index}`}
|
||||
className={classes.tag}
|
||||
size="small"
|
||||
label={`${tagKey} : ${tag}`}
|
||||
color="primary"
|
||||
deleteIcon={<CloseIcon />}
|
||||
onDelete={() => {
|
||||
deleteTag(tagKey, tag);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
})}
|
||||
<Chip
|
||||
className={classes.tag}
|
||||
icon={<AddIcon />}
|
||||
clickable
|
||||
size="small"
|
||||
label="Add tag"
|
||||
color="primary"
|
||||
variant="outlined"
|
||||
onClick={() => {
|
||||
setTagModalOpen(true);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.actionsTray}>
|
||||
<TextField
|
||||
placeholder={`Search ${objectName}`}
|
||||
className={clsx(classes.search, classes.searchField)}
|
||||
id="search-resource"
|
||||
label=""
|
||||
onChange={(val) => {
|
||||
setFilterVersion(val.target.value);
|
||||
}}
|
||||
InputProps={{
|
||||
disableUnderline: true,
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<SearchIcon />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<TableWrapper
|
||||
itemActions={tableActions}
|
||||
columns={[
|
||||
{ label: "Version ID", elementKey: "version_id" },
|
||||
{
|
||||
label: "Last Modified",
|
||||
elementKey: "last_modified",
|
||||
renderFunction: displayParsedDate,
|
||||
},
|
||||
]}
|
||||
isLoading={false}
|
||||
entityName="Versions"
|
||||
idField="version_id"
|
||||
records={filteredRecords}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const mapDispatchToProps = {
|
||||
removeRouteLevel,
|
||||
};
|
||||
|
||||
const connector = connect(null, mapDispatchToProps);
|
||||
|
||||
export default connector(withStyles(styles)(ObjectDetails));
|
||||
@@ -0,0 +1,138 @@
|
||||
import React, { useState, useRef } from "react";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import Button from "@material-ui/core/Button";
|
||||
import { modalBasic } from "../../../../Common/FormComponents/common/styleLibrary";
|
||||
import ModalWrapper from "../../../../Common/ModalWrapper/ModalWrapper";
|
||||
import FormSwitchWrapper from "../../../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
|
||||
import RadioGroupSelector from "../../../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector";
|
||||
import DateSelector from "../../../../Common/FormComponents/DateSelector/DateSelector";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
objectName: {
|
||||
fontSize: 18,
|
||||
fontWeight: 700,
|
||||
marginBottom: 40,
|
||||
},
|
||||
buttonContainer: {
|
||||
textAlign: "right",
|
||||
},
|
||||
...modalBasic,
|
||||
});
|
||||
|
||||
interface ISetRetentionProps {
|
||||
classes: any;
|
||||
open: boolean;
|
||||
closeModalAndRefresh: () => void;
|
||||
objectName: string;
|
||||
}
|
||||
|
||||
interface IRefObject {
|
||||
resetDate: () => void;
|
||||
}
|
||||
|
||||
const SetRetention = ({
|
||||
classes,
|
||||
open,
|
||||
closeModalAndRefresh,
|
||||
objectName,
|
||||
}: ISetRetentionProps) => {
|
||||
const [statusEnabled, setStatusEnabled] = useState<boolean>(false);
|
||||
const [type, setType] = useState<string>("");
|
||||
|
||||
const dateElement = useRef<IRefObject>(null);
|
||||
|
||||
const dateFieldDisabled = () => {
|
||||
return !(statusEnabled && (type === "governance" || type === "compliance"));
|
||||
};
|
||||
|
||||
const onSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
const resetForm = () => {
|
||||
setStatusEnabled(false);
|
||||
setType("");
|
||||
if (dateElement.current) {
|
||||
dateElement.current.resetDate();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ModalWrapper
|
||||
title="Set Retention Policy"
|
||||
modalOpen={open}
|
||||
onClose={() => {
|
||||
resetForm();
|
||||
closeModalAndRefresh();
|
||||
}}
|
||||
>
|
||||
<Grid item xs={12} className={classes.objectName}>
|
||||
{objectName}
|
||||
</Grid>
|
||||
<form
|
||||
noValidate
|
||||
autoComplete="off"
|
||||
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
|
||||
onSubmit(e);
|
||||
}}
|
||||
>
|
||||
<Grid item xs={12}>
|
||||
<FormSwitchWrapper
|
||||
value="status"
|
||||
id="status"
|
||||
name="status"
|
||||
checked={statusEnabled}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setStatusEnabled(!statusEnabled);
|
||||
setType("");
|
||||
}}
|
||||
label={"Status"}
|
||||
indicatorLabels={["Enabled", "Disabled"]}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<RadioGroupSelector
|
||||
currentSelection={type}
|
||||
id="type"
|
||||
name="type"
|
||||
label="Type"
|
||||
disableOptions={!statusEnabled}
|
||||
onChange={(e) => {
|
||||
setType(e.target.value);
|
||||
}}
|
||||
selectorOptions={[
|
||||
{ label: "Governance", value: "governance" },
|
||||
{ label: "Compliance", value: "compliance" },
|
||||
]}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<DateSelector
|
||||
id="date"
|
||||
label="Date"
|
||||
disableOptions={dateFieldDisabled()}
|
||||
ref={dateElement}
|
||||
borderBottom={true}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
<button
|
||||
type="button"
|
||||
color="primary"
|
||||
className={classes.clearButton}
|
||||
onClick={resetForm}
|
||||
>
|
||||
Reset
|
||||
</button>
|
||||
<Button type="submit" variant="contained" color="primary">
|
||||
Save
|
||||
</Button>
|
||||
</Grid>
|
||||
</form>
|
||||
</ModalWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(SetRetention);
|
||||
@@ -0,0 +1,78 @@
|
||||
import React, { useState } from "react";
|
||||
import CopyToClipboard from "react-copy-to-clipboard";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import Button from "@material-ui/core/Button";
|
||||
import {
|
||||
modalBasic,
|
||||
predefinedList,
|
||||
} from "../../../../Common/FormComponents/common/styleLibrary";
|
||||
import ModalWrapper from "../../../../Common/ModalWrapper/ModalWrapper";
|
||||
import DateSelector from "../../../../Common/FormComponents/DateSelector/DateSelector";
|
||||
import { CopyIcon } from "../../../../../../icons";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
copyButtonContainer: {
|
||||
paddingLeft: 16,
|
||||
},
|
||||
modalContent: {
|
||||
paddingBottom: 53,
|
||||
},
|
||||
...modalBasic,
|
||||
...predefinedList,
|
||||
});
|
||||
|
||||
interface IShareFileProps {
|
||||
classes: any;
|
||||
open: boolean;
|
||||
closeModalAndRefresh: () => void;
|
||||
}
|
||||
|
||||
const ShareFile = ({
|
||||
classes,
|
||||
open,
|
||||
closeModalAndRefresh,
|
||||
}: IShareFileProps) => {
|
||||
return (
|
||||
<ModalWrapper
|
||||
title="Share File"
|
||||
modalOpen={open}
|
||||
onClose={() => {
|
||||
closeModalAndRefresh();
|
||||
}}
|
||||
>
|
||||
<Grid container className={classes.modalContent}>
|
||||
<Grid item xs={12} className={classes.dateContainer}>
|
||||
<DateSelector
|
||||
id="date"
|
||||
label="Active until"
|
||||
borderBottom={false}
|
||||
addSwitch={true}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid container item xs={12}>
|
||||
<Grid item xs={10} className={classes.predefinedList}>
|
||||
{"https://somelink.will/go/here"}
|
||||
</Grid>
|
||||
<Grid item xs={2} className={classes.copyButtonContainer}>
|
||||
<CopyToClipboard text={"https://somelink.will/go/here"}>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
startIcon={<CopyIcon />}
|
||||
onClick={() => {
|
||||
console.log("copied!");
|
||||
}}
|
||||
>
|
||||
Copy
|
||||
</Button>
|
||||
</CopyToClipboard>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ModalWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(ShareFile);
|
||||
@@ -0,0 +1,48 @@
|
||||
// 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 storage from "local-storage-fallback";
|
||||
|
||||
export 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.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();
|
||||
};
|
||||
@@ -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, { useState, useEffect } from "react";
|
||||
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";
|
||||
@@ -22,7 +22,6 @@ 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 SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
|
||||
import { Button, LinearProgress } from "@material-ui/core";
|
||||
import api from "../../../../common/api";
|
||||
import { IRemoteBucket } from "../types";
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
BucketEvent,
|
||||
BucketEventList,
|
||||
BucketInfo,
|
||||
BucketEncryptionInfo,
|
||||
BucketList,
|
||||
BucketReplication,
|
||||
BucketReplicationDestination,
|
||||
@@ -34,8 +35,7 @@ import {
|
||||
BucketReplicationRuleDeleteMarker,
|
||||
BucketVersioning,
|
||||
} from "../types";
|
||||
import { Box, Button } from "@material-ui/core";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import { Button } from "@material-ui/core";
|
||||
import SetAccessPolicy from "./SetAccessPolicy";
|
||||
import { MinTablePaginationActions } from "../../../../common/MinTablePaginationActions";
|
||||
import { CreateIcon } from "../../../../icons";
|
||||
@@ -46,6 +46,8 @@ 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({
|
||||
@@ -191,6 +193,7 @@ interface IViewBucketState {
|
||||
rowsPerPage: number;
|
||||
curTab: number;
|
||||
addScreenOpen: boolean;
|
||||
enableEncryptionScreenOpen: boolean;
|
||||
deleteOpen: boolean;
|
||||
selectedBucket: string;
|
||||
selectedEvent: BucketEvent | null;
|
||||
@@ -199,6 +202,7 @@ interface IViewBucketState {
|
||||
replicationSet: boolean;
|
||||
openSetReplication: boolean;
|
||||
isVersioned: boolean;
|
||||
encryptionEnabled: boolean;
|
||||
}
|
||||
|
||||
class ViewBucket extends React.Component<IViewBucketProps, IViewBucketState> {
|
||||
@@ -218,6 +222,7 @@ class ViewBucket extends React.Component<IViewBucketProps, IViewBucketState> {
|
||||
curTab: 0,
|
||||
rowsPerPage: 10,
|
||||
addScreenOpen: false,
|
||||
enableEncryptionScreenOpen: false,
|
||||
deleteOpen: false,
|
||||
selectedBucket: "",
|
||||
selectedEvent: null,
|
||||
@@ -226,6 +231,7 @@ class ViewBucket extends React.Component<IViewBucketProps, IViewBucketState> {
|
||||
replicationSet: false,
|
||||
openSetReplication: false,
|
||||
isVersioned: false,
|
||||
encryptionEnabled: false,
|
||||
};
|
||||
|
||||
fetchEvents() {
|
||||
@@ -325,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();
|
||||
@@ -343,6 +364,7 @@ class ViewBucket extends React.Component<IViewBucketProps, IViewBucketState> {
|
||||
this.loadInfo();
|
||||
this.fetchEvents();
|
||||
this.fetchBucketsSize();
|
||||
this.fetchBucketEncryptionInfo();
|
||||
}
|
||||
|
||||
bucketFilter(): void {}
|
||||
@@ -360,14 +382,15 @@ class ViewBucket extends React.Component<IViewBucketProps, IViewBucketState> {
|
||||
rowsPerPage,
|
||||
deleteOpen,
|
||||
addScreenOpen,
|
||||
enableEncryptionScreenOpen,
|
||||
selectedEvent,
|
||||
bucketSize,
|
||||
loadingSize,
|
||||
replicationSet,
|
||||
openSetReplication,
|
||||
isVersioned,
|
||||
replicationRules,
|
||||
curTab,
|
||||
encryptionEnabled,
|
||||
} = this.state;
|
||||
|
||||
const offset = page * rowsPerPage;
|
||||
@@ -415,6 +438,23 @@ class ViewBucket extends React.Component<IViewBucketProps, IViewBucketState> {
|
||||
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);
|
||||
@@ -432,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}
|
||||
@@ -490,6 +540,17 @@ class ViewBucket extends React.Component<IViewBucketProps, IViewBucketState> {
|
||||
</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>
|
||||
@@ -581,20 +642,6 @@ class ViewBucket extends React.Component<IViewBucketProps, IViewBucketState> {
|
||||
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}>
|
||||
@@ -622,20 +669,6 @@ class ViewBucket extends React.Component<IViewBucketProps, IViewBucketState> {
|
||||
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>
|
||||
|
||||
@@ -19,6 +19,11 @@ export interface Bucket {
|
||||
creation_date: Date;
|
||||
}
|
||||
|
||||
export interface BucketEncryptionInfo {
|
||||
algorithm: string;
|
||||
kmsMasterKeyID: string;
|
||||
}
|
||||
|
||||
export interface BucketInfo {
|
||||
name: string;
|
||||
access: string;
|
||||
|
||||
@@ -82,14 +82,6 @@ const CredentialsPrompt = ({
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.formScrollable}>
|
||||
A new {entity} has been created with the following details:
|
||||
<ul>
|
||||
<li>
|
||||
<b>Access Key:</b> {newServiceAccount.accessKey}
|
||||
</li>
|
||||
<li>
|
||||
<b>Secret Key:</b> {newServiceAccount.secretKey}
|
||||
</li>
|
||||
</ul>
|
||||
{consoleCreds && (
|
||||
<React.Fragment>
|
||||
<Grid item xs={12}>
|
||||
@@ -131,8 +123,6 @@ const CredentialsPrompt = ({
|
||||
download(
|
||||
"credentials.json",
|
||||
JSON.stringify({
|
||||
access_key: newServiceAccount.accessKey,
|
||||
secret_key: newServiceAccount.secretKey,
|
||||
...consoleExtras,
|
||||
})
|
||||
);
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export interface NewServiceAccount {
|
||||
accessKey: string;
|
||||
secretKey: string;
|
||||
console?: ConsoleSA;
|
||||
}
|
||||
|
||||
|
||||
@@ -105,8 +105,8 @@ const CSVMultiSelector = ({
|
||||
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
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -14,20 +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 {
|
||||
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 { 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";
|
||||
|
||||
@@ -105,12 +93,7 @@ const CommentBoxWrapper = ({
|
||||
}`}
|
||||
>
|
||||
{label !== "" && (
|
||||
<InputLabel
|
||||
htmlFor={id}
|
||||
className={`${error !== "" ? classes.fieldLabelError : ""} ${
|
||||
classes.inputLabel
|
||||
}`}
|
||||
>
|
||||
<InputLabel htmlFor={id} className={classes.inputLabel}>
|
||||
<span>
|
||||
{label}
|
||||
{required ? "*" : ""}
|
||||
|
||||
@@ -0,0 +1,245 @@
|
||||
import React, { useState, forwardRef, useImperativeHandle } from "react";
|
||||
import clsx from "clsx";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import InputLabel from "@material-ui/core/InputLabel";
|
||||
import Tooltip from "@material-ui/core/Tooltip";
|
||||
import HelpIcon from "@material-ui/icons/Help";
|
||||
import FormControl from "@material-ui/core/FormControl";
|
||||
import Select from "@material-ui/core/Select";
|
||||
import MenuItem from "@material-ui/core/MenuItem";
|
||||
import InputBase from "@material-ui/core/InputBase";
|
||||
import { fieldBasic, tooltipHelper } from "../common/styleLibrary";
|
||||
import FormSwitchWrapper from "../FormSwitchWrapper/FormSwitchWrapper";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
dateInput: {
|
||||
"&:not(:last-child)": {
|
||||
marginRight: 22,
|
||||
},
|
||||
},
|
||||
...fieldBasic,
|
||||
...tooltipHelper,
|
||||
labelContainer: {
|
||||
flex: 1,
|
||||
},
|
||||
fieldContainer: {
|
||||
...fieldBasic.fieldContainer,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
paddingBottom: 10,
|
||||
marginTop: 11,
|
||||
marginBottom: 6,
|
||||
},
|
||||
fieldContainerBorder: {
|
||||
borderBottom: "#9c9c9c 1px solid",
|
||||
marginBottom: 20,
|
||||
},
|
||||
});
|
||||
|
||||
const SelectStyled = withStyles((theme: Theme) =>
|
||||
createStyles({
|
||||
root: {
|
||||
"& .MuiSelect-icon": {
|
||||
color: "#000",
|
||||
"&.Mui-disabled": {
|
||||
color: "#9c9c9c",
|
||||
},
|
||||
},
|
||||
},
|
||||
input: {
|
||||
borderBottom: 0,
|
||||
fontSize: 12,
|
||||
},
|
||||
})
|
||||
)(InputBase);
|
||||
|
||||
interface IDateSelectorProps {
|
||||
classes: any;
|
||||
id: string;
|
||||
label: string;
|
||||
disableOptions?: boolean;
|
||||
addSwitch?: boolean;
|
||||
tooltip?: string;
|
||||
borderBottom?: boolean;
|
||||
}
|
||||
|
||||
const DateSelector = forwardRef(
|
||||
(
|
||||
{
|
||||
classes,
|
||||
id,
|
||||
label,
|
||||
disableOptions = false,
|
||||
addSwitch = false,
|
||||
tooltip = "",
|
||||
borderBottom = false,
|
||||
}: IDateSelectorProps,
|
||||
ref: any
|
||||
) => {
|
||||
useImperativeHandle(ref, () => ({ resetDate }));
|
||||
|
||||
const [dateEnabled, setDateEnabled] = useState<boolean>(false);
|
||||
const [month, setMonth] = useState<string>("");
|
||||
const [day, setDay] = useState<string>("");
|
||||
const [year, setYear] = useState<string>("");
|
||||
|
||||
const resetDate = () => {
|
||||
setMonth("");
|
||||
setDay("");
|
||||
setYear("");
|
||||
};
|
||||
|
||||
const isDateDisabled = () => {
|
||||
if (disableOptions) {
|
||||
return disableOptions;
|
||||
} else if (addSwitch) {
|
||||
return !dateEnabled;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const onMonthChange = (
|
||||
e: React.ChangeEvent<{ name?: string | undefined; value: unknown }>
|
||||
) => {
|
||||
setMonth(e.target.value as string);
|
||||
};
|
||||
|
||||
const onDayChange = (
|
||||
e: React.ChangeEvent<{ name?: string | undefined; value: unknown }>
|
||||
) => {
|
||||
setDay(e.target.value as string);
|
||||
};
|
||||
|
||||
const onYearChange = (
|
||||
e: React.ChangeEvent<{ name?: string | undefined; value: unknown }>
|
||||
) => {
|
||||
setYear(e.target.value as string);
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
className={clsx(classes.fieldContainer, {
|
||||
[classes.fieldContainerBorder]: borderBottom,
|
||||
})}
|
||||
>
|
||||
<div className={classes.labelContainer}>
|
||||
<Grid container>
|
||||
<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>
|
||||
{addSwitch && (
|
||||
<FormSwitchWrapper
|
||||
indicatorLabels={["Specific Date", "Always active"]}
|
||||
checked={dateEnabled}
|
||||
value={"date_enabled"}
|
||||
id="date-status"
|
||||
name="date-status"
|
||||
onChange={(e) => {
|
||||
setDateEnabled(e.target.checked);
|
||||
}}
|
||||
switchOnly
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
</div>
|
||||
<div>
|
||||
<FormControl
|
||||
disabled={isDateDisabled()}
|
||||
className={classes.dateInput}
|
||||
>
|
||||
<Select
|
||||
id={`${id}-month`}
|
||||
name={`${id}-month`}
|
||||
value={month}
|
||||
displayEmpty
|
||||
onChange={onMonthChange}
|
||||
input={<SelectStyled />}
|
||||
>
|
||||
<MenuItem value="" disabled>
|
||||
{"<Month>"}
|
||||
</MenuItem>
|
||||
<MenuItem value={"1"}>January</MenuItem>
|
||||
{/* {options.map((option) => (
|
||||
<MenuItem
|
||||
value={option.value}
|
||||
key={`select-${name}-${option.label}`}
|
||||
>
|
||||
{option.label}
|
||||
</MenuItem>
|
||||
))} */}
|
||||
</Select>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
disabled={isDateDisabled()}
|
||||
className={classes.dateInput}
|
||||
>
|
||||
<Select
|
||||
id={`${id}-day`}
|
||||
name={`${id}-day`}
|
||||
value={day}
|
||||
displayEmpty
|
||||
onChange={onDayChange}
|
||||
input={<SelectStyled />}
|
||||
>
|
||||
<MenuItem value="" disabled>
|
||||
{"<Day>"}
|
||||
</MenuItem>
|
||||
<MenuItem value={"1"}>1</MenuItem>
|
||||
<MenuItem value={"2"}>2</MenuItem>
|
||||
{/* {options.map((option) => (
|
||||
<MenuItem
|
||||
value={option.value}
|
||||
key={`select-${name}-${option.label}`}
|
||||
>
|
||||
{option.label}
|
||||
</MenuItem>
|
||||
))} */}
|
||||
</Select>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
disabled={isDateDisabled()}
|
||||
className={classes.dateInput}
|
||||
>
|
||||
<Select
|
||||
id={`${id}-year`}
|
||||
name={`${id}-year`}
|
||||
value={year}
|
||||
displayEmpty
|
||||
onChange={onYearChange}
|
||||
input={<SelectStyled />}
|
||||
>
|
||||
<MenuItem value="" disabled>
|
||||
{"<Year>"}
|
||||
</MenuItem>
|
||||
<MenuItem value={"2020"}>2020</MenuItem>
|
||||
<MenuItem value={"2021"}>2021</MenuItem>
|
||||
{/* {options.map((option) => (
|
||||
<MenuItem
|
||||
value={option.value}
|
||||
key={`select-${name}-${option.label}`}
|
||||
>
|
||||
{option.label}
|
||||
</MenuItem>
|
||||
))} */}
|
||||
</Select>
|
||||
</FormControl>
|
||||
</div>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default withStyles(styles)(DateSelector);
|
||||
@@ -76,6 +76,12 @@ const styles = (theme: Theme) =>
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
},
|
||||
fieldBottom: {
|
||||
borderBottom: "#9c9c9c 1px solid",
|
||||
},
|
||||
fileInputField: {
|
||||
margin: "13px 0",
|
||||
},
|
||||
});
|
||||
|
||||
const FileSelector = ({
|
||||
@@ -98,7 +104,7 @@ const FileSelector = ({
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
className={`${classes.fieldContainer} ${
|
||||
className={`${classes.fieldBottom} ${classes.fieldContainer} ${
|
||||
error !== "" ? classes.errorInField : ""
|
||||
}`}
|
||||
>
|
||||
@@ -137,6 +143,7 @@ const FileSelector = ({
|
||||
accept={accept}
|
||||
required={required}
|
||||
disabled={disabled}
|
||||
className={classes.fileInputField}
|
||||
/>
|
||||
|
||||
{value !== "" && (
|
||||
|
||||
@@ -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, { useEffect, useState } from "react";
|
||||
import React from "react";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import { InputLabel, Switch, Tooltip } from "@material-ui/core";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
@@ -31,7 +31,7 @@ interface IFormSwitch {
|
||||
disabled?: boolean;
|
||||
tooltip?: string;
|
||||
index?: number;
|
||||
indicatorLabel?: string;
|
||||
indicatorLabels?: string[];
|
||||
checked: boolean;
|
||||
switchOnly?: boolean;
|
||||
}
|
||||
@@ -142,14 +142,21 @@ const StyledSwitch = withStyles({
|
||||
opacity: 1,
|
||||
height: 15,
|
||||
},
|
||||
"&:hover": {
|
||||
backgroundColor: "#fff",
|
||||
},
|
||||
},
|
||||
checked: {},
|
||||
track: {
|
||||
height: 15,
|
||||
backgroundColor: "#081C42",
|
||||
backgroundColor: "#9C9C9C",
|
||||
border: "#081C42 1px solid",
|
||||
opacity: 1,
|
||||
padding: 0,
|
||||
marginTop: 1.5,
|
||||
"&$checked": {
|
||||
backgroundColor: "#081C42",
|
||||
},
|
||||
},
|
||||
thumb: {
|
||||
backgroundColor: "#fff",
|
||||
@@ -172,7 +179,7 @@ const FormSwitchWrapper = ({
|
||||
disabled = false,
|
||||
switchOnly = false,
|
||||
tooltip = "",
|
||||
indicatorLabel = "",
|
||||
indicatorLabels = [],
|
||||
classes,
|
||||
}: IFormSwitch) => {
|
||||
const switchComponent = (
|
||||
@@ -190,8 +197,10 @@ const FormSwitchWrapper = ({
|
||||
disableTouchRipple
|
||||
value={value}
|
||||
/>
|
||||
{indicatorLabel !== "" && (
|
||||
<span className={classes.indicatorLabel}>{indicatorLabel}</span>
|
||||
{indicatorLabels.length === 2 && (
|
||||
<span className={classes.indicatorLabel}>
|
||||
{checked ? indicatorLabels[0] : indicatorLabels[1]}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
||||
@@ -109,7 +109,6 @@ const inputStyles = makeStyles((theme: Theme) =>
|
||||
},
|
||||
error: {
|
||||
color: "#b53b4b",
|
||||
boxShadow: "inset 0px 0px 1px 1px #b53b4b",
|
||||
},
|
||||
})
|
||||
);
|
||||
@@ -166,12 +165,7 @@ const InputBoxWrapper = ({
|
||||
}`}
|
||||
>
|
||||
{label !== "" && (
|
||||
<InputLabel
|
||||
htmlFor={id}
|
||||
className={`${error !== "" ? classes.fieldLabelError : ""} ${
|
||||
classes.inputLabel
|
||||
}`}
|
||||
>
|
||||
<InputLabel htmlFor={id} className={classes.inputLabel}>
|
||||
<span>
|
||||
{label}
|
||||
{required ? "*" : ""}
|
||||
|
||||
@@ -14,6 +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 clsx from "clsx";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import RadioGroup from "@material-ui/core/RadioGroup";
|
||||
import FormControlLabel from "@material-ui/core/FormControlLabel";
|
||||
@@ -40,6 +41,7 @@ interface RadioGroupProps {
|
||||
id: string;
|
||||
name: string;
|
||||
tooltip?: string;
|
||||
disableOptions?: boolean;
|
||||
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
classes: any;
|
||||
displayInColumn?: boolean;
|
||||
@@ -58,8 +60,23 @@ const styles = (theme: Theme) =>
|
||||
paddingBottom: 10,
|
||||
marginTop: 11,
|
||||
},
|
||||
optionLabel: {
|
||||
"&.Mui-disabled": {
|
||||
"& .MuiFormControlLabel-label": {
|
||||
color: "#9c9c9c",
|
||||
},
|
||||
},
|
||||
"&:last-child": {
|
||||
marginRight: 0,
|
||||
},
|
||||
"& .MuiFormControlLabel-label": {
|
||||
fontSize: 12,
|
||||
color: "#000",
|
||||
},
|
||||
},
|
||||
checkedOption: {
|
||||
"& .MuiFormControlLabel-label": {
|
||||
fontSize: 12,
|
||||
color: "#000",
|
||||
fontWeight: 700,
|
||||
},
|
||||
@@ -98,6 +115,7 @@ export const RadioGroupSelector = ({
|
||||
name,
|
||||
onChange,
|
||||
tooltip = "",
|
||||
disableOptions = false,
|
||||
classes,
|
||||
displayInColumn = false,
|
||||
}: RadioGroupProps) => {
|
||||
@@ -128,14 +146,14 @@ export const RadioGroupSelector = ({
|
||||
return (
|
||||
<FormControlLabel
|
||||
key={`rd-${name}-${selectorOption.value}`}
|
||||
value={selectorOption.value}
|
||||
value={disableOptions ? "disabled" : selectorOption.value}
|
||||
control={<RadioButton />}
|
||||
label={selectorOption.label}
|
||||
className={
|
||||
selectorOption.value === currentSelection
|
||||
? classes.checkedOption
|
||||
: ""
|
||||
}
|
||||
disabled={disableOptions}
|
||||
className={clsx(classes.optionLabel, {
|
||||
[classes.checkedOption]:
|
||||
selectorOption.value === currentSelection,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -54,6 +54,7 @@ export const modalBasic = {
|
||||
marginLeft: 0,
|
||||
},
|
||||
clearButton: {
|
||||
fontFamily: "Lato, sans-serif",
|
||||
border: "0",
|
||||
backgroundColor: "transparent",
|
||||
color: "#393939",
|
||||
@@ -104,6 +105,9 @@ const radioBasic = {
|
||||
width: 12,
|
||||
height: 12,
|
||||
borderRadius: "100%",
|
||||
"input:disabled ~ &": {
|
||||
border: "1px solid #9C9C9C",
|
||||
},
|
||||
};
|
||||
|
||||
export const radioIcons = {
|
||||
@@ -117,8 +121,7 @@ export const radioIcons = {
|
||||
|
||||
export const containerForHeader = (bottomSpacing: any) => ({
|
||||
container: {
|
||||
padding: "110px 33px 30px",
|
||||
paddingBottom: bottomSpacing,
|
||||
padding: "110px 33px 0",
|
||||
"& h6": {
|
||||
color: "#777777",
|
||||
fontSize: 14,
|
||||
@@ -145,6 +148,7 @@ export const actionsTray = {
|
||||
export const searchField = {
|
||||
searchField: {
|
||||
flexGrow: 1,
|
||||
height: 40,
|
||||
background: "#FFFFFF",
|
||||
borderRadius: 5,
|
||||
border: "#EAEDEE 1px solid",
|
||||
@@ -152,13 +156,17 @@ export const searchField = {
|
||||
justifyContent: "center",
|
||||
padding: "0 16px",
|
||||
"& input": {
|
||||
fontSize: 14,
|
||||
fontSize: 12,
|
||||
fontWeight: 700,
|
||||
color: "#000",
|
||||
"&::placeholder": {
|
||||
color: "#393939",
|
||||
opacity: 1,
|
||||
},
|
||||
},
|
||||
"&:hover": {
|
||||
borderColor: "#000",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -178,3 +186,37 @@ export const predefinedList = {
|
||||
minHeight: 41,
|
||||
},
|
||||
};
|
||||
|
||||
export const objectBrowserCommon = {
|
||||
obTitleSection: {
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "flex-start",
|
||||
marginBottom: 20,
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 22,
|
||||
color: "#000",
|
||||
fontWeight: 600,
|
||||
height: 40,
|
||||
lineHeight: "40px",
|
||||
},
|
||||
breadcrumbs: {
|
||||
fontSize: 10,
|
||||
color: "#000",
|
||||
marginTop: 2,
|
||||
"& a": {
|
||||
textDecoration: "none",
|
||||
color: "#000",
|
||||
"&:hover": {
|
||||
textDecoration: "underline",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const selectorsCommon = {
|
||||
multiSelectTable: {
|
||||
height: 200,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -30,7 +30,7 @@ const styles = (theme: Theme) =>
|
||||
minWidth: 180,
|
||||
marginRight: 10,
|
||||
"& ul": {
|
||||
padding: 15,
|
||||
padding: "0 15px 0 0",
|
||||
|
||||
"& li": {
|
||||
listStyle: "lower-roman",
|
||||
|
||||
@@ -51,6 +51,7 @@ const WizardPage = ({ classes, page, pageChange }: IWizardPage) => {
|
||||
break;
|
||||
case "to":
|
||||
pageChange(btn.toPage || 0);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
|
||||
@@ -16,12 +16,7 @@
|
||||
import React from "react";
|
||||
import { Dialog, DialogContent, DialogTitle } from "@material-ui/core";
|
||||
import IconButton from "@material-ui/core/IconButton";
|
||||
import {
|
||||
createStyles,
|
||||
makeStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
} from "@material-ui/core/styles";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
|
||||
interface IModalProps {
|
||||
classes: any;
|
||||
|
||||
@@ -18,13 +18,21 @@ import isString from "lodash/isString";
|
||||
import { IconButton } from "@material-ui/core";
|
||||
import ViewIcon from "./TableActionIcons/ViewIcon";
|
||||
import PencilIcon from "./TableActionIcons/PencilIcon";
|
||||
import ShareIcon from "./TableActionIcons/ShareIcon";
|
||||
import DeleteIcon from "./TableActionIcons/DeleteIcon";
|
||||
import DescriptionIcon from "./TableActionIcons/DescriptionIcon";
|
||||
import CloudIcon from "./TableActionIcons/CloudIcon";
|
||||
import ConsoleIcon from "./TableActionIcons/ConsoleIcon";
|
||||
import GetAppIcon from "@material-ui/icons/GetApp";
|
||||
import SvgIcon from "@material-ui/core/SvgIcon";
|
||||
import DownloadIcon from "./TableActionIcons/DownloadIcon";
|
||||
import { Link } from "react-router-dom";
|
||||
import { createStyles, withStyles } from "@material-ui/core/styles";
|
||||
|
||||
const styles = () =>
|
||||
createStyles({
|
||||
spacing: {
|
||||
margin: "0 8px",
|
||||
},
|
||||
});
|
||||
|
||||
interface IActionButton {
|
||||
type: string;
|
||||
@@ -34,6 +42,7 @@ interface IActionButton {
|
||||
selected: boolean;
|
||||
sendOnlyId?: boolean;
|
||||
idField: string;
|
||||
classes: any;
|
||||
}
|
||||
|
||||
const defineIcon = (type: string, selected: boolean) => {
|
||||
@@ -46,14 +55,14 @@ const defineIcon = (type: string, selected: boolean) => {
|
||||
return <DeleteIcon active={selected} />;
|
||||
case "description":
|
||||
return <DescriptionIcon active={selected} />;
|
||||
case "share":
|
||||
return <ShareIcon active={selected} />;
|
||||
case "cloud":
|
||||
return <CloudIcon active={selected} />;
|
||||
case "console":
|
||||
return <ConsoleIcon active={selected} />;
|
||||
case "download":
|
||||
return (
|
||||
<SvgIcon component={GetAppIcon} fontSize="small" color="primary" />
|
||||
);
|
||||
return <DownloadIcon active={selected} />;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -67,6 +76,7 @@ const TableActionButton = ({
|
||||
selected,
|
||||
to,
|
||||
sendOnlyId = false,
|
||||
classes,
|
||||
}: IActionButton) => {
|
||||
const valueClick = sendOnlyId ? valueToSend[idField] : valueToSend;
|
||||
|
||||
@@ -82,6 +92,7 @@ const TableActionButton = ({
|
||||
}
|
||||
: () => null
|
||||
}
|
||||
className={classes.spacing}
|
||||
>
|
||||
{defineIcon(type, selected)}
|
||||
</IconButton>
|
||||
@@ -107,4 +118,4 @@ const TableActionButton = ({
|
||||
return null;
|
||||
};
|
||||
|
||||
export default TableActionButton;
|
||||
export default withStyles(styles)(TableActionButton);
|
||||
|
||||
@@ -7,15 +7,12 @@ const DeleteIcon = ({ active = false }: IIcon) => {
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
viewBox="0 0 10.402 13"
|
||||
>
|
||||
<g transform="translate(-1225 -657)">
|
||||
<path
|
||||
fill={active ? selected : unSelected}
|
||||
d="M0,8H0a8,8,0,0,0,8,8H8a8,8,0,0,0,8-8h0A8,8,0,0,0,8,0H8A8,8,0,0,0,0,8Zm10.007,3.489L8,9.482,5.993,11.489,4.511,10.007,6.518,8,4.511,5.993,5.993,4.511,8,6.518l2.007-2.007,1.482,1.482L9.482,8l2.007,2.007Z"
|
||||
transform="translate(1225 657)"
|
||||
/>
|
||||
</g>
|
||||
<path
|
||||
fill={active ? selected : unSelected}
|
||||
d="M6.761 1V0H3.64v1H.004v1h10.4V1zM.004 2.998l1.672 10h7.052l1.673-10zm3.412 8.243l-.552-6.478h.653l.553 6.472zm3.569 0h-.653l.551-6.472h.654z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import React from "react";
|
||||
import { IIcon, selected, unSelected } from "./common";
|
||||
|
||||
const DeleteIcon = ({ active = false }: IIcon) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 13 12.996"
|
||||
>
|
||||
<path
|
||||
fill={active ? selected : unSelected}
|
||||
d="M11.05 9.096v1.95h-9.1v-1.95H0v3.9h13v-3.9z"
|
||||
></path>
|
||||
<path
|
||||
fill={active ? selected : unSelected}
|
||||
d="M6.5 9.75L9 6.672H7.475V0h-1.95v6.672H4z"
|
||||
></path>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default DeleteIcon;
|
||||
@@ -0,0 +1,26 @@
|
||||
import React from "react";
|
||||
import { IIcon, selected, unSelected } from "./common";
|
||||
|
||||
const ShareIcon = ({ active = false }: IIcon) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 13 13"
|
||||
>
|
||||
<path
|
||||
fill={active ? selected : unSelected}
|
||||
d="M11.05 8.617v2.429h-9.1v-9.1h2.429v-1.95H0v13h13V8.617z"
|
||||
className="a"
|
||||
></path>
|
||||
<path
|
||||
fill={active ? selected : unSelected}
|
||||
d="M3.854 9.256h1.95a4.945 4.945 0 013.6-4.74v1.3l.6-.487 2.474-2.012L9.4.817v1.7a6.9 6.9 0 00-5.546 6.739z"
|
||||
className="a"
|
||||
></path>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default ShareIcon;
|
||||
@@ -18,19 +18,13 @@ import get from "lodash/get";
|
||||
import isString from "lodash/isString";
|
||||
import {
|
||||
LinearProgress,
|
||||
TablePagination,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableRow,
|
||||
Paper,
|
||||
Grid,
|
||||
Checkbox,
|
||||
Typography,
|
||||
} from "@material-ui/core";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import { TablePaginationActionsProps } from "@material-ui/core/TablePagination/TablePaginationActions";
|
||||
import { Table, Column, AutoSizer } from "react-virtualized";
|
||||
import { createStyles, withStyles } from "@material-ui/core/styles";
|
||||
import TableActionButton from "./TableActionButton";
|
||||
import history from "../../../../history";
|
||||
import {
|
||||
@@ -50,27 +44,13 @@ interface ItemActions {
|
||||
interface IColumns {
|
||||
label: string;
|
||||
elementKey: string;
|
||||
sortable?: boolean;
|
||||
renderFunction?: (input: any) => any;
|
||||
renderFullObject?: boolean;
|
||||
globalClass?: any;
|
||||
}
|
||||
|
||||
interface IPaginatorConfig {
|
||||
rowsPerPageOptions: number[];
|
||||
colSpan: number;
|
||||
count: number;
|
||||
rowsPerPage: number;
|
||||
page: number;
|
||||
SelectProps: any;
|
||||
onChangePage: (
|
||||
event: React.MouseEvent<HTMLButtonElement> | null,
|
||||
page: number
|
||||
) => void;
|
||||
onChangeRowsPerPage?: React.ChangeEventHandler<
|
||||
HTMLTextAreaElement | HTMLInputElement
|
||||
>;
|
||||
ActionsComponent?: React.ElementType<TablePaginationActionsProps>;
|
||||
rowClass?: any;
|
||||
width?: number;
|
||||
headerTextAlign?: string;
|
||||
contentTextAlign?: string;
|
||||
}
|
||||
|
||||
interface TableWrapperProps {
|
||||
@@ -83,21 +63,26 @@ interface TableWrapperProps {
|
||||
classes: any;
|
||||
entityName: string;
|
||||
selectedItems?: string[];
|
||||
stickyHeader?: boolean;
|
||||
radioSelection?: boolean;
|
||||
customEmptyMessage?: string;
|
||||
paginatorConfig?: IPaginatorConfig;
|
||||
customPaperHeight?: string;
|
||||
}
|
||||
|
||||
const borderColor = "#eaeaea";
|
||||
const borderColor = "#9c9c9c80";
|
||||
|
||||
const rowText = {
|
||||
fontWeight: 400,
|
||||
fontSize: 14,
|
||||
borderColor: borderColor,
|
||||
borderWidth: "0.5px",
|
||||
height: 40,
|
||||
transitionDuration: "0.3s",
|
||||
padding: "initial",
|
||||
paddingRight: 6,
|
||||
paddingLeft: 6,
|
||||
};
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
const styles = () =>
|
||||
createStyles({
|
||||
dialogContainer: {
|
||||
padding: "12px 26px 22px",
|
||||
@@ -107,10 +92,27 @@ const styles = (theme: Theme) =>
|
||||
overflow: "auto",
|
||||
flexDirection: "column",
|
||||
padding: "19px 38px",
|
||||
minHeight: "200px",
|
||||
boxShadow: "none",
|
||||
border: "#EAEDEE 1px solid",
|
||||
borderRadius: 3,
|
||||
minHeight: 200,
|
||||
overflowY: "scroll",
|
||||
|
||||
"&::-webkit-scrollbar": {
|
||||
width: 3,
|
||||
height: 3,
|
||||
},
|
||||
},
|
||||
defaultPaperHeight: {
|
||||
height: "calc(100vh - 205px)",
|
||||
},
|
||||
allTableSettings: {
|
||||
"& .MuiTableCell-sizeSmall:last-child": {
|
||||
paddingRight: "initial",
|
||||
},
|
||||
"& .MuiTableCell-body.MuiTableCell-sizeSmall:last-child": {
|
||||
paddingRight: 6,
|
||||
},
|
||||
},
|
||||
minTableHeader: {
|
||||
color: "#393939",
|
||||
@@ -118,13 +120,15 @@ const styles = (theme: Theme) =>
|
||||
"& th": {
|
||||
fontWeight: 700,
|
||||
fontSize: 14,
|
||||
paddingBottom: 15,
|
||||
borderColor: borderColor,
|
||||
borderColor: "#39393980",
|
||||
borderWidth: "0.5px",
|
||||
padding: "6px 0 10px",
|
||||
},
|
||||
},
|
||||
},
|
||||
rowUnselected: {
|
||||
...rowText,
|
||||
color: "#393939",
|
||||
},
|
||||
rowSelected: {
|
||||
...rowText,
|
||||
@@ -137,8 +141,12 @@ const styles = (theme: Theme) =>
|
||||
padding: "5px 38px",
|
||||
},
|
||||
checkBoxHeader: {
|
||||
width: 50,
|
||||
textAlign: "left",
|
||||
paddingRight: 10,
|
||||
"&.MuiTableCell-paddingCheckbox": {
|
||||
paddingBottom: 9,
|
||||
paddingBottom: 4,
|
||||
paddingLeft: 0,
|
||||
},
|
||||
},
|
||||
actionsContainer: {
|
||||
@@ -150,62 +158,149 @@ const styles = (theme: Theme) =>
|
||||
},
|
||||
checkBoxRow: {
|
||||
borderColor: borderColor,
|
||||
padding: "0 10px 0 0",
|
||||
},
|
||||
loadingBox: {
|
||||
paddingTop: "100px",
|
||||
paddingBottom: "100px",
|
||||
},
|
||||
rowElement: {
|
||||
userSelect: "none",
|
||||
|
||||
"&:hover": {
|
||||
backgroundColor: "#ececec",
|
||||
"@global": {
|
||||
".rowLine": {
|
||||
borderBottom: `1px solid ${borderColor}`,
|
||||
height: 40,
|
||||
color: "#393939",
|
||||
fontSize: 14,
|
||||
transitionDuration: 0.3,
|
||||
"&:focus": {
|
||||
outline: "initial",
|
||||
},
|
||||
"&:hover:not(.ReactVirtualized__Table__headerRow)": {
|
||||
userSelect: "none",
|
||||
backgroundColor: "#ececec",
|
||||
fontWeight: 600,
|
||||
"&.canClick": {
|
||||
cursor: "pointer",
|
||||
},
|
||||
},
|
||||
"& .selected": {
|
||||
color: "#081C42",
|
||||
fontWeight: 600,
|
||||
},
|
||||
},
|
||||
".headerItem": {
|
||||
userSelect: "none",
|
||||
fontWeight: 700,
|
||||
fontSize: 14,
|
||||
fontStyle: "initial",
|
||||
},
|
||||
".ReactVirtualized__Table__headerRow": {
|
||||
fontWeight: 700,
|
||||
fontSize: 14,
|
||||
borderColor: "#39393980",
|
||||
textTransform: "initial",
|
||||
},
|
||||
".optionsAlignment": {
|
||||
textAlign: "center",
|
||||
},
|
||||
".text-center": {
|
||||
textAlign: "center",
|
||||
},
|
||||
".text-right": {
|
||||
textAlign: "right",
|
||||
},
|
||||
},
|
||||
rowClickable: {
|
||||
cursor: "pointer",
|
||||
},
|
||||
...checkboxIcons,
|
||||
...radioIcons,
|
||||
});
|
||||
|
||||
// Function that renders Title Columns
|
||||
const titleColumnsMap = (columns: IColumns[]) => {
|
||||
return columns.map((column: IColumns, index: number) => {
|
||||
return (
|
||||
<TableCell
|
||||
key={`tbCT-${column.elementKey}-${index}`}
|
||||
className={column.globalClass}
|
||||
>
|
||||
{column.label}
|
||||
</TableCell>
|
||||
);
|
||||
});
|
||||
};
|
||||
const selectWidth = 45;
|
||||
|
||||
// Function that renders Rows
|
||||
const rowColumnsMap = (
|
||||
columns: IColumns[],
|
||||
itemData: any,
|
||||
classes: any,
|
||||
// Function to render elements in table
|
||||
const subRenderFunction = (
|
||||
rowData: any,
|
||||
column: IColumns,
|
||||
isSelected: boolean
|
||||
) => {
|
||||
return columns.map((column: IColumns, index: number) => {
|
||||
const itemElement = isString(itemData)
|
||||
? itemData
|
||||
: get(itemData, column.elementKey, null); // If the element is just a string, we render it as it is
|
||||
const renderConst = column.renderFullObject ? itemData : itemElement;
|
||||
const itemElement = isString(rowData)
|
||||
? rowData
|
||||
: get(rowData, column.elementKey, null); // If the element is just a string, we render it as it is
|
||||
const renderConst = column.renderFullObject ? rowData : itemElement;
|
||||
|
||||
const renderElement = column.renderFunction
|
||||
? column.renderFunction(renderConst)
|
||||
: renderConst; // If render function is set, we send the value to the function.
|
||||
const renderElement = column.renderFunction
|
||||
? column.renderFunction(renderConst)
|
||||
: renderConst; // If render function is set, we send the value to the function.
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<span className={isSelected ? "selected" : ""}>{renderElement}</span>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
// Function to calculate common column width for elements with no with size
|
||||
const calculateColumnRest = (
|
||||
columns: IColumns[],
|
||||
containerWidth: number,
|
||||
actionsWidth: number,
|
||||
hasSelect: boolean,
|
||||
hasActions: boolean
|
||||
) => {
|
||||
let initialValue = containerWidth;
|
||||
|
||||
if (hasSelect) {
|
||||
initialValue -= selectWidth;
|
||||
}
|
||||
|
||||
if (hasActions) {
|
||||
initialValue -= actionsWidth;
|
||||
}
|
||||
|
||||
let freeSpacing = columns.reduce((total, currValue) => {
|
||||
return currValue.width ? total - currValue.width : total;
|
||||
}, initialValue);
|
||||
|
||||
return freeSpacing / columns.filter((el) => !el.width).length;
|
||||
};
|
||||
|
||||
// Function that renders Columns in table
|
||||
const generateColumnsMap = (
|
||||
columns: IColumns[],
|
||||
containerWidth: number,
|
||||
actionsWidth: number,
|
||||
hasSelect: boolean,
|
||||
hasActions: boolean,
|
||||
selectedItems: string[],
|
||||
idField: string
|
||||
) => {
|
||||
const commonRestWidth = calculateColumnRest(
|
||||
columns,
|
||||
containerWidth,
|
||||
actionsWidth,
|
||||
hasSelect,
|
||||
hasActions
|
||||
);
|
||||
return columns.map((column: IColumns, index: number) => {
|
||||
return (
|
||||
<TableCell
|
||||
key={`tbRE-${column.elementKey}-${index}`}
|
||||
className={isSelected ? classes.rowSelected : classes.rowUnselected}
|
||||
>
|
||||
{renderElement}
|
||||
</TableCell>
|
||||
<Column
|
||||
key={`col-tb-${index.toString()}`}
|
||||
dataKey={column.elementKey}
|
||||
headerClassName={`titleHeader ${
|
||||
column.headerTextAlign ? `text-${column.headerTextAlign}` : ""
|
||||
}`}
|
||||
headerRenderer={() => <React.Fragment>{column.label}</React.Fragment>}
|
||||
className={
|
||||
column.contentTextAlign ? `text-${column.contentTextAlign}` : ""
|
||||
}
|
||||
cellRenderer={({ rowData }) => {
|
||||
const isSelected = selectedItems
|
||||
? selectedItems.includes(
|
||||
isString(rowData) ? rowData : rowData[idField]
|
||||
)
|
||||
: false;
|
||||
return subRenderFunction(rowData, column, isSelected);
|
||||
}}
|
||||
width={column.width || commonRestWidth}
|
||||
/>
|
||||
);
|
||||
});
|
||||
};
|
||||
@@ -237,6 +332,22 @@ const elementActions = (
|
||||
});
|
||||
};
|
||||
|
||||
// Function to calculate the options column width according elements inside
|
||||
const calculateOptionsSize = (containerWidth: number, totalOptions: number) => {
|
||||
const minContainerSize = 80;
|
||||
const sizeOptions = totalOptions * 45;
|
||||
|
||||
if (sizeOptions < minContainerSize) {
|
||||
return minContainerSize;
|
||||
}
|
||||
|
||||
if (sizeOptions > containerWidth) {
|
||||
return containerWidth;
|
||||
}
|
||||
|
||||
return sizeOptions;
|
||||
};
|
||||
|
||||
// Main function to render the Table Wrapper
|
||||
const TableWrapper = ({
|
||||
itemActions,
|
||||
@@ -248,10 +359,9 @@ const TableWrapper = ({
|
||||
selectedItems,
|
||||
idField,
|
||||
classes,
|
||||
stickyHeader = false,
|
||||
radioSelection = false,
|
||||
customEmptyMessage = "",
|
||||
paginatorConfig,
|
||||
customPaperHeight = "",
|
||||
}: TableWrapperProps) => {
|
||||
const findView = itemActions
|
||||
? itemActions.find((el) => el.type === "view")
|
||||
@@ -273,7 +383,13 @@ const TableWrapper = ({
|
||||
|
||||
return (
|
||||
<Grid item xs={12}>
|
||||
<Paper className={classes.paper}>
|
||||
<Paper
|
||||
className={`${classes.paper} ${
|
||||
customPaperHeight !== ""
|
||||
? customPaperHeight
|
||||
: classes.defaultPaperHeight
|
||||
}`}
|
||||
>
|
||||
{isLoading && (
|
||||
<Grid container className={classes.loadingBox}>
|
||||
<Grid item xs={12} style={{ textAlign: "center" }}>
|
||||
@@ -285,109 +401,133 @@ const TableWrapper = ({
|
||||
</Grid>
|
||||
)}
|
||||
{records && !isLoading && records.length > 0 ? (
|
||||
<Table size="small" stickyHeader={stickyHeader}>
|
||||
<TableHead className={classes.minTableHeader}>
|
||||
<TableRow>
|
||||
{onSelect && selectedItems && (
|
||||
<TableCell
|
||||
padding="checkbox"
|
||||
align="center"
|
||||
className={classes.checkBoxHeader}
|
||||
>
|
||||
Select
|
||||
</TableCell>
|
||||
)}
|
||||
{titleColumnsMap(columns)}
|
||||
{((itemActions && itemActions.length > 1) ||
|
||||
(itemActions &&
|
||||
itemActions.length === 1 &&
|
||||
itemActions[0].type !== "view")) && (
|
||||
<TableCell
|
||||
align="center"
|
||||
className={classes.actionsContainer}
|
||||
>
|
||||
Actions
|
||||
</TableCell>
|
||||
)}
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{records.map((record: any, index: number) => {
|
||||
const isSelected = selectedItems
|
||||
? selectedItems.includes(
|
||||
isString(record) ? record : record[idField]
|
||||
)
|
||||
: false;
|
||||
<AutoSizer>
|
||||
{({ width, height }: any) => {
|
||||
const optionsWidth = calculateOptionsSize(
|
||||
width,
|
||||
itemActions
|
||||
? itemActions.filter((el) => el.type !== "view").length
|
||||
: 0
|
||||
);
|
||||
const hasSelect: boolean = !!(onSelect && selectedItems);
|
||||
const hasOptions: boolean = !!(
|
||||
(itemActions && itemActions.length > 1) ||
|
||||
(itemActions &&
|
||||
itemActions.length === 1 &&
|
||||
itemActions[0].type !== "view")
|
||||
);
|
||||
return (
|
||||
<Table
|
||||
ref="Table"
|
||||
disableHeader={false}
|
||||
headerClassName={"headerItem"}
|
||||
headerHeight={40}
|
||||
height={height}
|
||||
noRowsRenderer={() => (
|
||||
<React.Fragment>
|
||||
{customEmptyMessage !== ""
|
||||
? customEmptyMessage
|
||||
: `There are no ${entityName} yet.`}
|
||||
</React.Fragment>
|
||||
)}
|
||||
overscanRowCount={10}
|
||||
rowHeight={40}
|
||||
width={width}
|
||||
rowCount={records.length}
|
||||
rowGetter={({ index }) => records[index]}
|
||||
onRowClick={({ rowData }) => {
|
||||
clickAction(rowData);
|
||||
}}
|
||||
rowClassName={`rowLine ${findView ? "canClick" : ""}`}
|
||||
>
|
||||
{hasSelect && (
|
||||
<Column
|
||||
headerRenderer={() => (
|
||||
<React.Fragment>Select</React.Fragment>
|
||||
)}
|
||||
dataKey={idField}
|
||||
width={selectWidth}
|
||||
cellRenderer={({ rowData }) => {
|
||||
const isSelected = selectedItems
|
||||
? selectedItems.includes(
|
||||
isString(rowData) ? rowData : rowData[idField]
|
||||
)
|
||||
: false;
|
||||
|
||||
return (
|
||||
<TableRow
|
||||
key={`tb-${entityName}-${index.toString()}`}
|
||||
className={`${findView ? classes.rowClickable : ""} ${
|
||||
classes.rowElement
|
||||
}`}
|
||||
onClick={() => {
|
||||
clickAction(record);
|
||||
}}
|
||||
>
|
||||
{onSelect && selectedItems && (
|
||||
<TableCell
|
||||
padding="checkbox"
|
||||
align="center"
|
||||
className={classes.checkBoxRow}
|
||||
>
|
||||
<Checkbox
|
||||
value={isString(record) ? record : record[idField]}
|
||||
color="primary"
|
||||
inputProps={{ "aria-label": "secondary checkbox" }}
|
||||
checked={isSelected}
|
||||
onChange={onSelect}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}}
|
||||
checkedIcon={
|
||||
<span
|
||||
className={
|
||||
radioSelection
|
||||
? classes.radioSelectedIcon
|
||||
: classes.checkedIcon
|
||||
}
|
||||
/>
|
||||
}
|
||||
icon={
|
||||
<span
|
||||
className={
|
||||
radioSelection
|
||||
? classes.radioUnselectedIcon
|
||||
: classes.unCheckedIcon
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
)}
|
||||
{rowColumnsMap(columns, record, classes, isSelected)}
|
||||
{((itemActions && itemActions.length > 1) ||
|
||||
(itemActions &&
|
||||
itemActions.length === 1 &&
|
||||
itemActions[0].type !== "view")) && (
|
||||
<TableCell
|
||||
align="center"
|
||||
className={classes.actionsContainer}
|
||||
>
|
||||
{elementActions(
|
||||
itemActions,
|
||||
record,
|
||||
return (
|
||||
<Checkbox
|
||||
value={
|
||||
isString(rowData) ? rowData : rowData[idField]
|
||||
}
|
||||
color="primary"
|
||||
inputProps={{
|
||||
"aria-label": "secondary checkbox",
|
||||
}}
|
||||
checked={isSelected}
|
||||
onChange={onSelect}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
checkedIcon={
|
||||
<span
|
||||
className={
|
||||
radioSelection
|
||||
? classes.radioSelectedIcon
|
||||
: classes.checkedIcon
|
||||
}
|
||||
/>
|
||||
}
|
||||
icon={
|
||||
<span
|
||||
className={
|
||||
radioSelection
|
||||
? classes.radioUnselectedIcon
|
||||
: classes.unCheckedIcon
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{generateColumnsMap(
|
||||
columns,
|
||||
width,
|
||||
optionsWidth,
|
||||
hasSelect,
|
||||
hasOptions,
|
||||
selectedItems || [],
|
||||
idField
|
||||
)}
|
||||
{hasOptions && (
|
||||
<Column
|
||||
headerRenderer={() => (
|
||||
<React.Fragment>Options</React.Fragment>
|
||||
)}
|
||||
dataKey={idField}
|
||||
width={optionsWidth}
|
||||
headerClassName="optionsAlignment"
|
||||
className="optionsAlignment"
|
||||
cellRenderer={({ rowData }) => {
|
||||
const isSelected = selectedItems
|
||||
? selectedItems.includes(
|
||||
isString(rowData) ? rowData : rowData[idField]
|
||||
)
|
||||
: false;
|
||||
return elementActions(
|
||||
itemActions || [],
|
||||
rowData,
|
||||
isSelected,
|
||||
idField
|
||||
)}
|
||||
</TableCell>
|
||||
)}
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Table>
|
||||
);
|
||||
}}
|
||||
</AutoSizer>
|
||||
) : (
|
||||
<React.Fragment>
|
||||
{!isLoading && (
|
||||
@@ -400,20 +540,6 @@ const TableWrapper = ({
|
||||
</React.Fragment>
|
||||
)}
|
||||
</Paper>
|
||||
{paginatorConfig && (
|
||||
<Grid item xs={12} className={classes.paginatorContainer}>
|
||||
<Table>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TablePagination
|
||||
{...paginatorConfig}
|
||||
className={classes.paginatorComponent}
|
||||
/>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -20,7 +20,6 @@ import Grid from "@material-ui/core/Grid";
|
||||
import { IElementValue, KVField } from "./types";
|
||||
import { modalBasic } from "../Common/FormComponents/common/styleLibrary";
|
||||
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||
import RadioGroupSelector from "../Common/FormComponents/RadioGroupSelector/RadioGroupSelector";
|
||||
import CSVMultiSelector from "../Common/FormComponents/CSVMultiSelector/CSVMultiSelector";
|
||||
import CommentBoxWrapper from "../Common/FormComponents/CommentBoxWrapper/CommentBoxWrapper";
|
||||
import FormSwitchWrapper from "../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
|
||||
@@ -79,6 +78,7 @@ const ConfTargetGeneric = ({
|
||||
});
|
||||
|
||||
setValueHolder(values);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [fields, defaultVals]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -100,7 +100,7 @@ const ConfTargetGeneric = ({
|
||||
|
||||
return (
|
||||
<FormSwitchWrapper
|
||||
indicatorLabel="On"
|
||||
indicatorLabels={["On", "Off"]}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = e.target.checked ? "true" : "false";
|
||||
setValueElement(field.name, value, item);
|
||||
|
||||
@@ -18,7 +18,6 @@ import React, { useState } from "react";
|
||||
import get from "lodash/get";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import { TextField } from "@material-ui/core";
|
||||
import InputAdornment from "@material-ui/core/InputAdornment";
|
||||
import SearchIcon from "@material-ui/icons/Search";
|
||||
@@ -63,7 +62,6 @@ const ConfigurationsList = ({ classes }: IListConfiguration) => {
|
||||
configuration_id: "",
|
||||
configuration_label: "",
|
||||
});
|
||||
const [error, setError] = useState("");
|
||||
const [filter, setFilter] = useState("");
|
||||
|
||||
const tableActions = [
|
||||
@@ -103,7 +101,6 @@ const ConfigurationsList = ({ classes }: IListConfiguration) => {
|
||||
<PageHeader label="Configurations List" />
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.container}>
|
||||
{error !== "" && <Grid container>{error}</Grid>}
|
||||
<Grid item xs={12} className={classes.actionsTray}>
|
||||
<TextField
|
||||
placeholder="Filter"
|
||||
|
||||
@@ -94,10 +94,9 @@ const panels = {
|
||||
|
||||
const WebhookPanel = ({ match, classes }: IWebhookPanel) => {
|
||||
const [addWebhookOpen, setAddWebhookOpen] = useState<boolean>(false);
|
||||
const [error, setError] = useState<string>("");
|
||||
const [filter, setFilter] = useState<string>("");
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const [webhooks, setWebhooks] = useState<IWebhook[]>([]);
|
||||
// const [webhooks, setWebhooks] = useState<IWebhook[]>([]);
|
||||
|
||||
const pathIn = get(match, "path", "");
|
||||
const panelToDisplay = pathIn.split("/");
|
||||
@@ -107,6 +106,8 @@ const WebhookPanel = ({ match, classes }: IWebhookPanel) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
const webhooks: IWebhook[] = [];
|
||||
|
||||
const filteredRecords: IWebhook[] = webhooks.filter((elementItem) =>
|
||||
elementItem.name.toLocaleLowerCase().includes(filter.toLocaleLowerCase())
|
||||
);
|
||||
@@ -137,7 +138,6 @@ const WebhookPanel = ({ match, classes }: IWebhookPanel) => {
|
||||
<Grid item xs={12}>
|
||||
<br />
|
||||
</Grid>
|
||||
{error !== "" && <Grid container>{error}</Grid>}
|
||||
<Grid item xs={12} className={classes.actionsTray}>
|
||||
<TextField
|
||||
placeholder="Filter"
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import { FormControlLabel, Switch } from "@material-ui/core";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||
import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector";
|
||||
@@ -144,7 +143,7 @@ const ConfMySql = ({ onChange, classes }: IConfMySqlProps) => {
|
||||
name="checkedB"
|
||||
onChange={switcherChangeEvt}
|
||||
value={"dnsString"}
|
||||
indicatorLabel={"On"}
|
||||
indicatorLabels={["On", "Off"]}
|
||||
/>
|
||||
</Grid>
|
||||
{useDsnString ? (
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import { FormControlLabel, Switch } from "@material-ui/core";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||
import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector";
|
||||
@@ -201,6 +200,8 @@ const ConfPostgres = ({ onChange, classes }: IConfPostgresProps) => {
|
||||
setUser(kv.get("user") ? kv.get("user") + "" : "");
|
||||
setPassword(kv.get("password") ? kv.get("password") + "" : "");
|
||||
setSslMode(kv.get("sslmode") ? kv.get("sslmode") + "" : " ");
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [useConnectionString]);
|
||||
|
||||
return (
|
||||
@@ -215,7 +216,7 @@ const ConfPostgres = ({ onChange, classes }: IConfPostgresProps) => {
|
||||
setUseConnectionString(e.target.checked);
|
||||
}}
|
||||
value={"manualString"}
|
||||
indicatorLabel={"On"}
|
||||
indicatorLabels={["On", "Off"]}
|
||||
/>
|
||||
</Grid>
|
||||
{useConnectionString ? (
|
||||
|
||||
@@ -16,27 +16,12 @@
|
||||
|
||||
import React, { useEffect } from "react";
|
||||
import clsx from "clsx";
|
||||
import {
|
||||
createStyles,
|
||||
StyledProps,
|
||||
Theme,
|
||||
withStyles,
|
||||
} from "@material-ui/core/styles";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import CssBaseline from "@material-ui/core/CssBaseline";
|
||||
import Drawer from "@material-ui/core/Drawer";
|
||||
import Box from "@material-ui/core/Box";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import Container from "@material-ui/core/Container";
|
||||
import Link from "@material-ui/core/Link";
|
||||
import history from "../../history";
|
||||
import {
|
||||
Redirect,
|
||||
Route,
|
||||
RouteComponentProps,
|
||||
Router,
|
||||
Switch,
|
||||
withRouter,
|
||||
} from "react-router-dom";
|
||||
import { Redirect, Route, Router, Switch } from "react-router-dom";
|
||||
import { connect } from "react-redux";
|
||||
import { AppState } from "../../store";
|
||||
import {
|
||||
@@ -44,7 +29,6 @@ import {
|
||||
serverNeedsRestart,
|
||||
setMenuOpen,
|
||||
} from "../../actions";
|
||||
import { ThemedComponentProps } from "@material-ui/core/styles/withTheme";
|
||||
import Buckets from "./Buckets/Buckets";
|
||||
import Policies from "./Policies/Policies";
|
||||
import Permissions from "./Permissions/Permissions";
|
||||
@@ -58,17 +42,15 @@ import ListNotificationEndpoints from "./NotificationEndopoints/ListNotification
|
||||
import ConfigurationsList from "./Configurations/ConfigurationPanels/ConfigurationsList";
|
||||
import { Button, LinearProgress } from "@material-ui/core";
|
||||
import WebhookPanel from "./Configurations/ConfigurationPanels/WebhookPanel";
|
||||
import Trace from "./Trace/Trace";
|
||||
import Logs from "./Logs/Logs";
|
||||
import Heal from "./Heal/Heal";
|
||||
import Watch from "./Watch/Watch";
|
||||
import ListTenants from "./Tenants/ListTenants/ListTenants";
|
||||
import { ISessionResponse } from "./types";
|
||||
import { saveSessionResponse } from "./actions";
|
||||
import TenantDetails from "./Tenants/TenantDetails/TenantDetails";
|
||||
import { clearSession } from "../../common/utils";
|
||||
import ObjectBrowser from "./ObjectBrowser/ObjectBrowser";
|
||||
import ListObjects from "./Buckets/ListBuckets/Objects/ListObjects/ListObjects";
|
||||
import ObjectDetails from "./Buckets/ListBuckets/Objects/ObjectDetails/ObjectDetails";
|
||||
import ObjectRouting from "./Buckets/ListBuckets/Objects/ListObjects/ObjectRouting";
|
||||
import License from "./License/License";
|
||||
|
||||
const drawerWidth = 245;
|
||||
@@ -147,6 +129,8 @@ const styles = (theme: Theme) =>
|
||||
container: {
|
||||
paddingBottom: theme.spacing(4),
|
||||
margin: 0,
|
||||
width: "100%",
|
||||
maxWidth: "initial",
|
||||
},
|
||||
paper: {
|
||||
padding: theme.spacing(2),
|
||||
@@ -176,7 +160,6 @@ interface IConsoleProps {
|
||||
setMenuOpen: typeof setMenuOpen;
|
||||
serverNeedsRestart: typeof serverNeedsRestart;
|
||||
serverIsLoading: typeof serverIsLoading;
|
||||
saveSessionResponse: typeof saveSessionResponse;
|
||||
session: ISessionResponse;
|
||||
}
|
||||
|
||||
@@ -187,24 +170,8 @@ const Console = ({
|
||||
isServerLoading,
|
||||
serverNeedsRestart,
|
||||
serverIsLoading,
|
||||
saveSessionResponse,
|
||||
session,
|
||||
}: IConsoleProps) => {
|
||||
useEffect(() => {
|
||||
api
|
||||
.invoke("GET", `/api/v1/session`)
|
||||
.then((res) => {
|
||||
saveSessionResponse(res);
|
||||
})
|
||||
.catch(() => {
|
||||
// if server returns 401 for /api/v1/session call invoke function will internally call clearSession()
|
||||
// and redirecto to window.location.href = "/"; and this code will be not reached
|
||||
// in case that not happen we clear session here and redirect as well
|
||||
clearSession();
|
||||
window.location.href = "/login";
|
||||
});
|
||||
}, [saveSessionResponse]);
|
||||
|
||||
const restartServer = () => {
|
||||
serverIsLoading(true);
|
||||
api
|
||||
@@ -247,8 +214,12 @@ const Console = ({
|
||||
path: "/object-browser",
|
||||
},
|
||||
{
|
||||
component: ListObjects,
|
||||
path: "/object-browser/:bucket?",
|
||||
component: ObjectRouting,
|
||||
path: "/object-browser/:bucket",
|
||||
},
|
||||
{
|
||||
component: ObjectRouting,
|
||||
path: "/object-browser/:bucket/*",
|
||||
},
|
||||
{
|
||||
component: Watch,
|
||||
@@ -266,14 +237,6 @@ const Console = ({
|
||||
component: Policies,
|
||||
path: "/policies",
|
||||
},
|
||||
{
|
||||
component: Trace,
|
||||
path: "/trace",
|
||||
},
|
||||
{
|
||||
component: Logs,
|
||||
path: "/logs",
|
||||
},
|
||||
{
|
||||
component: Heal,
|
||||
path: "/heal",
|
||||
@@ -319,7 +282,7 @@ const Console = ({
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{session.status == "ok" ? (
|
||||
{session.status === "ok" ? (
|
||||
<div className={classes.root}>
|
||||
<CssBaseline />
|
||||
<Drawer
|
||||
@@ -395,7 +358,6 @@ const connector = connect(mapState, {
|
||||
setMenuOpen,
|
||||
serverNeedsRestart,
|
||||
serverIsLoading,
|
||||
saveSessionResponse,
|
||||
});
|
||||
|
||||
export default connector(withStyles(styles)(Console));
|
||||
|
||||
@@ -20,9 +20,6 @@ import clsx from "clsx";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import Paper from "@material-ui/core/Paper";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import NetworkCheckIcon from "@material-ui/icons/NetworkCheck";
|
||||
import PieChartIcon from "@material-ui/icons/PieChart";
|
||||
import ViewHeadlineIcon from "@material-ui/icons/ViewHeadline";
|
||||
import { Usage } from "./types";
|
||||
import api from "../../../common/api";
|
||||
import { niceBytes } from "../../../common/utils";
|
||||
|
||||
@@ -27,7 +27,6 @@ import api from "../../../common/api";
|
||||
import UsersSelectors from "./UsersSelectors";
|
||||
import ModalWrapper from "../Common/ModalWrapper/ModalWrapper";
|
||||
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||
import RadioGroupSelector from "../Common/FormComponents/RadioGroupSelector/RadioGroupSelector";
|
||||
import FormSwitchWrapper from "../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
|
||||
|
||||
interface IGroupProps {
|
||||
@@ -180,7 +179,7 @@ const AddGroup = ({
|
||||
{selectedGroup !== null && (
|
||||
<div className={classes.floatingEnabled}>
|
||||
<FormSwitchWrapper
|
||||
indicatorLabel={"Enabled"}
|
||||
indicatorLabels={["Enabled", "Disabled"]}
|
||||
checked={groupEnabled}
|
||||
value={"group_enabled"}
|
||||
id="group-status"
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
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";
|
||||
@@ -258,20 +257,6 @@ const Groups = ({ classes }: IGroupsProps) => {
|
||||
records={filteredRecords}
|
||||
entityName="Groups"
|
||||
idField=""
|
||||
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,
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -20,7 +20,6 @@ import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import { LinearProgress } from "@material-ui/core";
|
||||
import Paper from "@material-ui/core/Paper";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import Title from "../../../common/Title";
|
||||
import { UsersList } from "../Users/types";
|
||||
import { usersSort } from "../../../utils/sortFunctions";
|
||||
import api from "../../../common/api";
|
||||
@@ -30,7 +29,7 @@ import SearchIcon from "@material-ui/icons/Search";
|
||||
import TableWrapper from "../Common/TableWrapper/TableWrapper";
|
||||
import {
|
||||
actionsTray,
|
||||
predefinedList,
|
||||
selectorsCommon,
|
||||
} from "../Common/FormComponents/common/styleLibrary";
|
||||
|
||||
interface IGroupsProps {
|
||||
@@ -106,6 +105,7 @@ const styles = (theme: Theme) =>
|
||||
},
|
||||
},
|
||||
...actionsTray,
|
||||
...selectorsCommon,
|
||||
});
|
||||
|
||||
const UsersSelectors = ({
|
||||
@@ -215,6 +215,7 @@ const UsersSelectors = ({
|
||||
records={filteredRecords}
|
||||
entityName="Users"
|
||||
idField="accessKey"
|
||||
customPaperHeight={classes.multiSelectTable}
|
||||
/>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
import { HorizontalBar } from "react-chartjs-2";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import {
|
||||
Button,
|
||||
Grid,
|
||||
Typography,
|
||||
TextField,
|
||||
Checkbox,
|
||||
} from "@material-ui/core";
|
||||
import { Button, Grid, TextField, InputBase } from "@material-ui/core";
|
||||
import { IMessageEvent, w3cwebsocket as W3CWebSocket } from "websocket";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import { wsProtocol } from "../../../utils/wsUtils";
|
||||
@@ -15,8 +9,13 @@ import { FormControl, MenuItem, Select } from "@material-ui/core";
|
||||
import { BucketList, Bucket } from "../Watch/types";
|
||||
import { HealStatus, colorH } from "./types";
|
||||
import { niceBytes } from "../../../common/utils";
|
||||
import { containerForHeader } from "../Common/FormComponents/common/styleLibrary";
|
||||
import {
|
||||
actionsTray,
|
||||
containerForHeader,
|
||||
searchField,
|
||||
} from "../Common/FormComponents/common/styleLibrary";
|
||||
import PageHeader from "../Common/PageHeader/PageHeader";
|
||||
import CheckboxWrapper from "../Common/FormComponents/CheckboxWrapper/CheckboxWrapper";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
@@ -35,31 +34,27 @@ const styles = (theme: Theme) =>
|
||||
borderBottom: "1px solid #dedede",
|
||||
},
|
||||
},
|
||||
actionsTray: {
|
||||
textAlign: "right",
|
||||
"& button": {
|
||||
marginLeft: 10,
|
||||
},
|
||||
graphContainer: {
|
||||
backgroundColor: "#fff",
|
||||
border: "#EAEDEE 1px solid",
|
||||
borderRadius: 3,
|
||||
padding: "19px 38px",
|
||||
},
|
||||
inputField: {
|
||||
background: "#FFFFFF",
|
||||
padding: 12,
|
||||
borderRadius: 5,
|
||||
marginLeft: 10,
|
||||
boxShadow: "0px 3px 6px #00000012",
|
||||
scanInfo: {
|
||||
marginTop: 20,
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
fieldContainer: {
|
||||
background: "#FFFFFF",
|
||||
padding: 0,
|
||||
borderRadius: 5,
|
||||
marginLeft: 10,
|
||||
textAlign: "left",
|
||||
minWidth: "206",
|
||||
boxShadow: "0px 3px 6px #00000012",
|
||||
scanData: {
|
||||
fontSize: 13,
|
||||
},
|
||||
lastElementWPadding: {
|
||||
paddingRight: "78",
|
||||
inlineCheckboxes: {
|
||||
display: "flex",
|
||||
justifyContent: "flex-start",
|
||||
},
|
||||
...actionsTray,
|
||||
...searchField,
|
||||
...containerForHeader(theme.spacing(4)),
|
||||
});
|
||||
|
||||
@@ -67,6 +62,26 @@ interface IHeal {
|
||||
classes: any;
|
||||
}
|
||||
|
||||
const SelectStyled = withStyles((theme: Theme) =>
|
||||
createStyles({
|
||||
root: {
|
||||
width: 450,
|
||||
lineHeight: 1,
|
||||
marginRight: 15,
|
||||
"label + &": {
|
||||
marginTop: theme.spacing(3),
|
||||
},
|
||||
"& .MuiSelect-select:focus": {
|
||||
backgroundColor: "transparent",
|
||||
},
|
||||
},
|
||||
input: {
|
||||
fontSize: 13,
|
||||
lineHeight: 15,
|
||||
},
|
||||
})
|
||||
)(InputBase);
|
||||
|
||||
const Heal = ({ classes }: IHeal) => {
|
||||
const [start, setStart] = useState(false);
|
||||
const [bucketName, setBucketName] = useState("Select Bucket");
|
||||
@@ -171,7 +186,7 @@ const Heal = ({ classes }: IHeal) => {
|
||||
};
|
||||
}
|
||||
}
|
||||
}, [start]);
|
||||
}, [start, bucketName, forceStart, forceStop, prefix, recursive]);
|
||||
|
||||
let data = {
|
||||
labels: ["Green", "Yellow", "Red", "Grey"],
|
||||
@@ -210,8 +225,8 @@ const Heal = ({ classes }: IHeal) => {
|
||||
onChange={(e) => {
|
||||
setBucketName(e.target.value as string);
|
||||
}}
|
||||
className={classes.fieldContainer}
|
||||
disabled={false}
|
||||
className={classes.searchField}
|
||||
input={<SelectStyled />}
|
||||
>
|
||||
<MenuItem value="" key={`select-bucket-name-default`}>
|
||||
Select Bucket
|
||||
@@ -228,7 +243,7 @@ const Heal = ({ classes }: IHeal) => {
|
||||
</FormControl>
|
||||
<TextField
|
||||
placeholder="Prefix"
|
||||
className={classes.inputField}
|
||||
className={classes.searchField}
|
||||
id="prefix-resource"
|
||||
label=""
|
||||
disabled={false}
|
||||
@@ -248,76 +263,75 @@ const Heal = ({ classes }: IHeal) => {
|
||||
>
|
||||
Start
|
||||
</Button>
|
||||
<Grid item xs={12}>
|
||||
<span>{"Recursive"}</span>
|
||||
<Checkbox
|
||||
name="recursive"
|
||||
id="recursive"
|
||||
value="recursive"
|
||||
color="primary"
|
||||
inputProps={{ "aria-label": "secondary checkbox" }}
|
||||
checked={recursive}
|
||||
onChange={(e) => {
|
||||
setRecursive(e.target.checked);
|
||||
}}
|
||||
disabled={false}
|
||||
/>
|
||||
<span>{"Force Start"}</span>
|
||||
<Checkbox
|
||||
name="recursive"
|
||||
id="recursive"
|
||||
value="recursive"
|
||||
color="primary"
|
||||
inputProps={{ "aria-label": "secondary checkbox" }}
|
||||
checked={forceStart}
|
||||
onChange={(e) => {
|
||||
setForceStart(e.target.checked);
|
||||
}}
|
||||
disabled={false}
|
||||
/>
|
||||
<span>{"Force Stop"}</span>
|
||||
<Checkbox
|
||||
name="recursive"
|
||||
id="recursive"
|
||||
value="recursive"
|
||||
color="primary"
|
||||
inputProps={{ "aria-label": "secondary checkbox" }}
|
||||
checked={forceStop}
|
||||
onChange={(e) => {
|
||||
setForceStop(e.target.checked);
|
||||
}}
|
||||
disabled={false}
|
||||
/>
|
||||
<span className={classes.lastElementWPadding}>{""}</span>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.inlineCheckboxes}>
|
||||
<CheckboxWrapper
|
||||
name="recursive"
|
||||
id="recursive"
|
||||
value="recursive"
|
||||
checked={recursive}
|
||||
onChange={(e) => {
|
||||
setRecursive(e.target.checked);
|
||||
}}
|
||||
disabled={false}
|
||||
label="Recursive"
|
||||
/>
|
||||
<CheckboxWrapper
|
||||
name="forceStart"
|
||||
id="forceStart"
|
||||
value="forceStart"
|
||||
checked={forceStart}
|
||||
onChange={(e) => {
|
||||
setForceStart(e.target.checked);
|
||||
}}
|
||||
disabled={false}
|
||||
label="Force Start"
|
||||
/>
|
||||
<CheckboxWrapper
|
||||
name="forceStop"
|
||||
id="forceStop"
|
||||
value="forceStop"
|
||||
checked={forceStop}
|
||||
onChange={(e) => {
|
||||
setForceStop(e.target.checked);
|
||||
}}
|
||||
disabled={false}
|
||||
label="Force Stop"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<br />
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.graphContainer}>
|
||||
<HorizontalBar
|
||||
data={data}
|
||||
width={80}
|
||||
height={30}
|
||||
options={{
|
||||
title: {
|
||||
display: true,
|
||||
text: "Item's Health Status [%]",
|
||||
fontSize: 20,
|
||||
},
|
||||
legend: {
|
||||
display: true,
|
||||
position: "right",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<Grid item xs={12} className={classes.scanInfo}>
|
||||
<div className={classes.scanData}>
|
||||
<strong>Size scanned:</strong> {hStatus.sizeScanned}
|
||||
</div>
|
||||
<div className={classes.scanData}>
|
||||
<strong>Objects healed:</strong> {hStatus.objectsHealed} /{" "}
|
||||
{hStatus.objectsScanned}
|
||||
</div>
|
||||
<div className={classes.scanData}>
|
||||
<strong>Healing time:</strong> {hStatus.healDuration}s
|
||||
</div>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<br />
|
||||
</Grid>
|
||||
<HorizontalBar
|
||||
data={data}
|
||||
width={100}
|
||||
height={30}
|
||||
options={{
|
||||
title: {
|
||||
display: true,
|
||||
text: "Item's Health Status [%]",
|
||||
fontSize: 20,
|
||||
},
|
||||
legend: {
|
||||
display: true,
|
||||
position: "right",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<Grid item xs={12}>
|
||||
<br />
|
||||
Size scanned: {hStatus.sizeScanned}
|
||||
<br />
|
||||
Objects healed: {hStatus.objectsHealed} / {hStatus.objectsScanned}
|
||||
<br />
|
||||
Healing time: {hStatus.healDuration}s
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
|
||||
@@ -19,16 +19,11 @@ import { connect } from "react-redux";
|
||||
import { NavLink } from "react-router-dom";
|
||||
import ListItem from "@material-ui/core/ListItem";
|
||||
import ListItemIcon from "@material-ui/core/ListItemIcon";
|
||||
import WebAssetIcon from "@material-ui/icons/WebAsset";
|
||||
import HealingIcon from "@material-ui/icons/Healing";
|
||||
import DescriptionIcon from "@material-ui/icons/Description";
|
||||
import FileCopyIcon from "@material-ui/icons/FileCopy";
|
||||
import Collapse from "@material-ui/core/Collapse";
|
||||
import ListItemText from "@material-ui/core/ListItemText";
|
||||
import List from "@material-ui/core/List";
|
||||
import { Divider, Typography, withStyles } from "@material-ui/core";
|
||||
import { ExitToApp } from "@material-ui/icons";
|
||||
import storage from "local-storage-fallback";
|
||||
import { Divider, withStyles } from "@material-ui/core";
|
||||
import { createStyles, Theme } from "@material-ui/core/styles";
|
||||
import history from "../../../history";
|
||||
import logo from "../../../icons/minio_console_logo.svg";
|
||||
@@ -48,13 +43,11 @@ import {
|
||||
LambdaNotificationsIcon,
|
||||
MirroringIcon,
|
||||
ServiceAccountsIcon,
|
||||
TraceIcon,
|
||||
UsersIcon,
|
||||
WarpIcon,
|
||||
} from "../../../icons";
|
||||
import { clearSession } from "../../../common/utils";
|
||||
import HealIcon from "../../../icons/HealIcon";
|
||||
import ConsoleIcon from "../../../icons/ConsoleIcon";
|
||||
import LicenseIcon from "../../../icons/LicenseIcon";
|
||||
import LogoutIcon from "../../../icons/LogoutIcon";
|
||||
|
||||
@@ -247,14 +240,6 @@ const Menu = ({ userLoggedIn, classes, pages }: IMenuProps) => {
|
||||
name: "IAM Policies",
|
||||
icon: <IAMPoliciesIcon />,
|
||||
},
|
||||
{
|
||||
group: "Tools",
|
||||
type: "item",
|
||||
component: NavLink,
|
||||
to: "/logs",
|
||||
name: "Logs",
|
||||
icon: <ConsoleIcon />,
|
||||
},
|
||||
{
|
||||
group: "Tools",
|
||||
type: "item",
|
||||
@@ -263,14 +248,6 @@ const Menu = ({ userLoggedIn, classes, pages }: IMenuProps) => {
|
||||
name: "Watch",
|
||||
icon: <WatchIcon />,
|
||||
},
|
||||
{
|
||||
group: "Tools",
|
||||
type: "item",
|
||||
component: NavLink,
|
||||
to: "/trace",
|
||||
name: "Trace",
|
||||
icon: <TraceIcon />,
|
||||
},
|
||||
{
|
||||
group: "Tools",
|
||||
type: "item",
|
||||
@@ -362,7 +339,7 @@ const Menu = ({ userLoggedIn, classes, pages }: IMenuProps) => {
|
||||
(menuItem: any) => menuItem.type !== "title"
|
||||
);
|
||||
|
||||
if (countableElements.length == 0) {
|
||||
if (countableElements.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -429,6 +406,7 @@ const Menu = ({ userLoggedIn, classes, pages }: IMenuProps) => {
|
||||
);
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
})}
|
||||
<Divider />
|
||||
|
||||
@@ -62,6 +62,7 @@ const styles = (theme: Theme) =>
|
||||
height: "80px",
|
||||
},
|
||||
lambdaNotif: {
|
||||
backgroundColor: "#fff",
|
||||
border: "#393939 1px solid",
|
||||
borderRadius: 5,
|
||||
width: 101,
|
||||
@@ -289,7 +290,7 @@ const AddNotificationEndpoint = ({
|
||||
<div className={classes.iconContainer}>
|
||||
{withLogos.map((item) => {
|
||||
return (
|
||||
<a
|
||||
<button
|
||||
key={`icon-${item.targetTitle}`}
|
||||
className={classes.lambdaNotif}
|
||||
onClick={() => {
|
||||
@@ -301,7 +302,7 @@ const AddNotificationEndpoint = ({
|
||||
className={classes.logoButton}
|
||||
alt={item.targetTitle}
|
||||
/>
|
||||
</a>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -20,7 +20,6 @@ import { TextField } from "@material-ui/core";
|
||||
import { red } from "@material-ui/core/colors";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import Button from "@material-ui/core/Button";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import InputAdornment from "@material-ui/core/InputAdornment";
|
||||
import SearchIcon from "@material-ui/icons/Search";
|
||||
import { MinTablePaginationActions } from "../../../common/MinTablePaginationActions";
|
||||
@@ -206,27 +205,6 @@ const ListNotificationEndpoints = ({ classes }: IListNotificationEndpoints) => {
|
||||
records={filteredRecords}
|
||||
entityName="Notification Endpoints"
|
||||
idField="service_name"
|
||||
paginatorConfig={{
|
||||
rowsPerPageOptions: [5, 10, 25],
|
||||
colSpan: 3,
|
||||
count: totalRecords,
|
||||
rowsPerPage: rowsPerPage,
|
||||
page: page,
|
||||
SelectProps: {
|
||||
inputProps: { "aria-label": "rows per page" },
|
||||
native: true,
|
||||
},
|
||||
onChangePage: (event: unknown, newPage: number) => {
|
||||
setPage(newPage);
|
||||
},
|
||||
onChangeRowsPerPage: (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
const rPP = parseInt(event.target.value, 10);
|
||||
setRowsPerPage(rPP);
|
||||
},
|
||||
ActionsComponent: MinTablePaginationActions,
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { withRouter } from "react-router-dom";
|
||||
import { connect } from "react-redux";
|
||||
import get from "lodash/get";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import AddBucket from "../Buckets/ListBuckets/AddBucket";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
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";
|
||||
@@ -28,13 +28,16 @@ import { CreateIcon } from "../../../icons";
|
||||
import { niceBytes } from "../../../common/utils";
|
||||
import { MinTablePaginationActions } from "../../../common/MinTablePaginationActions";
|
||||
import { Bucket, BucketList } from "../Buckets/types";
|
||||
import TableWrapper from "../Common/TableWrapper/TableWrapper";
|
||||
import api from "../../../common/api";
|
||||
import history from "../../../history";
|
||||
import {
|
||||
actionsTray,
|
||||
objectBrowserCommon,
|
||||
searchField,
|
||||
} from "../Common/FormComponents/common/styleLibrary";
|
||||
import { addRoute, resetRoutesList } from "./actions";
|
||||
import BrowserBreadcrumbs from "./BrowserBreadcrumbs";
|
||||
import TableWrapper from "../Common/TableWrapper/TableWrapper";
|
||||
import AddBucket from "../Buckets/ListBuckets/AddBucket";
|
||||
import api from "../../../common/api";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
@@ -68,20 +71,50 @@ const styles = (theme: Theme) =>
|
||||
},
|
||||
usedSpaceCol: {
|
||||
width: 150,
|
||||
textAlign: "right",
|
||||
},
|
||||
subTitleLabel: {
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
},
|
||||
bucketName: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
},
|
||||
iconBucket: {
|
||||
backgroundImage: "url(/images/ob_bucket_clear.svg)",
|
||||
backgroundRepeat: "no-repeat",
|
||||
backgroundPosition: "center center",
|
||||
width: 16,
|
||||
height: 40,
|
||||
marginRight: 10,
|
||||
},
|
||||
"@global": {
|
||||
".rowLine:hover .iconBucketElm": {
|
||||
backgroundImage: "url(/images/ob_bucket_filled.svg)",
|
||||
},
|
||||
},
|
||||
browsePaper: {
|
||||
height: "calc(100vh - 280px)",
|
||||
},
|
||||
...actionsTray,
|
||||
...searchField,
|
||||
...objectBrowserCommon,
|
||||
});
|
||||
|
||||
interface IBrowseBucketsProps {
|
||||
classes: any;
|
||||
addRoute: (path: string, label: string, type: string) => any;
|
||||
resetRoutesList: (doVar: boolean) => any;
|
||||
match: any;
|
||||
}
|
||||
|
||||
const BrowseBuckets = ({ classes }: IBrowseBucketsProps) => {
|
||||
const BrowseBuckets = ({
|
||||
classes,
|
||||
match,
|
||||
addRoute,
|
||||
resetRoutesList,
|
||||
}: IBrowseBucketsProps) => {
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [page, setPage] = useState<number>(0);
|
||||
const [rowsPerPage, setRowsPerPage] = useState<number>(10);
|
||||
@@ -92,15 +125,17 @@ const BrowseBuckets = ({ classes }: IBrowseBucketsProps) => {
|
||||
|
||||
const offset = page * rowsPerPage;
|
||||
|
||||
useEffect(() => {
|
||||
resetRoutesList(true);
|
||||
}, [match]);
|
||||
|
||||
useEffect(() => {
|
||||
if (loading) {
|
||||
api
|
||||
.invoke("GET", `/api/v1/buckets?offset=${offset}&limit=${rowsPerPage}`)
|
||||
.then((res: BucketList) => {
|
||||
const buckets = get(res, "buckets", []);
|
||||
|
||||
setLoading(false);
|
||||
setRecords(buckets);
|
||||
setRecords(res.buckets || []);
|
||||
setError("");
|
||||
// if we get 0 results, and page > 0 , go down 1 page
|
||||
if (
|
||||
@@ -119,21 +154,22 @@ const BrowseBuckets = ({ classes }: IBrowseBucketsProps) => {
|
||||
setError(err);
|
||||
});
|
||||
}
|
||||
}, [loading]);
|
||||
}, [loading, offset, rowsPerPage, page]);
|
||||
|
||||
const closeAddModalAndRefresh = () => {
|
||||
const closeAddModalAndRefresh = (refresh: boolean) => {
|
||||
setAddScreenOpen(false);
|
||||
setLoading(false);
|
||||
|
||||
if (refresh) {
|
||||
setLoading(true);
|
||||
}
|
||||
};
|
||||
|
||||
const filteredRecords = records
|
||||
.filter((b: Bucket) => {
|
||||
if (filterBuckets === "") {
|
||||
return true;
|
||||
}
|
||||
return b.name.indexOf(filterBuckets) >= 0;
|
||||
})
|
||||
.slice(offset, offset + rowsPerPage);
|
||||
const filteredRecords = records.filter((b: Bucket) => {
|
||||
if (filterBuckets === "") {
|
||||
return true;
|
||||
}
|
||||
return b.name.indexOf(filterBuckets) >= 0;
|
||||
});
|
||||
|
||||
const handleChangePage = (event: unknown, newPage: number) => {
|
||||
setPage(newPage);
|
||||
@@ -147,6 +183,22 @@ const BrowseBuckets = ({ classes }: IBrowseBucketsProps) => {
|
||||
setRowsPerPage(rPP);
|
||||
};
|
||||
|
||||
const handleViewChange = (idElement: string) => {
|
||||
const currentPath = get(match, "url", "/object-browser");
|
||||
const newPath = `${currentPath}/${idElement}`;
|
||||
|
||||
addRoute(newPath, idElement, "path");
|
||||
};
|
||||
|
||||
const renderBucket = (bucketName: string) => {
|
||||
return (
|
||||
<div className={classes.bucketName}>
|
||||
<div className={`${classes.iconBucket} iconBucketElm`} />
|
||||
<span>{bucketName}</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{addScreenOpen && (
|
||||
@@ -156,10 +208,24 @@ const BrowseBuckets = ({ classes }: IBrowseBucketsProps) => {
|
||||
/>
|
||||
)}
|
||||
<Grid container>
|
||||
<Grid item xs={2} className={classes.subTitleLabel}>
|
||||
<Typography variant="h6">Buckets</Typography>
|
||||
<Grid item xs={12} className={classes.obTitleSection}>
|
||||
<div>
|
||||
<BrowserBreadcrumbs />
|
||||
</div>
|
||||
<div>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
startIcon={<CreateIcon />}
|
||||
onClick={() => {
|
||||
setAddScreenOpen(true);
|
||||
}}
|
||||
>
|
||||
Create Bucket
|
||||
</Button>
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs={10} className={classes.actionsTray}>
|
||||
<Grid item xs={12} className={classes.actionsTray}>
|
||||
<TextField
|
||||
placeholder="Search Buckets"
|
||||
className={classes.searchField}
|
||||
@@ -177,16 +243,6 @@ const BrowseBuckets = ({ classes }: IBrowseBucketsProps) => {
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
startIcon={<CreateIcon />}
|
||||
onClick={() => {
|
||||
setAddScreenOpen(true);
|
||||
}}
|
||||
>
|
||||
Add Bucket
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<br />
|
||||
@@ -195,35 +251,34 @@ const BrowseBuckets = ({ classes }: IBrowseBucketsProps) => {
|
||||
{error !== "" && <span className={classes.errorBlock}>{error}</span>}
|
||||
<TableWrapper
|
||||
itemActions={[
|
||||
{ type: "view", to: `/object-browser`, sendOnlyId: true },
|
||||
{
|
||||
type: "view",
|
||||
sendOnlyId: true,
|
||||
onClick: handleViewChange,
|
||||
},
|
||||
]}
|
||||
columns={[
|
||||
{ label: "Name", elementKey: "name" },
|
||||
{
|
||||
label: "Name",
|
||||
elementKey: "name",
|
||||
renderFunction: renderBucket,
|
||||
},
|
||||
{
|
||||
label: "Used Space",
|
||||
elementKey: "size",
|
||||
renderFunction: niceBytes,
|
||||
globalClass: classes.usedSpaceCol,
|
||||
rowClass: classes.usedSpaceCol,
|
||||
width: 100,
|
||||
contentTextAlign: "right",
|
||||
headerTextAlign: "right",
|
||||
},
|
||||
]}
|
||||
isLoading={loading}
|
||||
records={filteredRecords}
|
||||
entityName="Buckets"
|
||||
idField="name"
|
||||
paginatorConfig={{
|
||||
rowsPerPageOptions: [5, 10, 25],
|
||||
colSpan: 3,
|
||||
count: filteredRecords.length,
|
||||
rowsPerPage: rowsPerPage,
|
||||
page: page,
|
||||
SelectProps: {
|
||||
inputProps: { "aria-label": "rows per page" },
|
||||
native: true,
|
||||
},
|
||||
onChangePage: handleChangePage,
|
||||
onChangeRowsPerPage: handleChangeRowsPerPage,
|
||||
ActionsComponent: MinTablePaginationActions,
|
||||
}}
|
||||
customPaperHeight={classes.browsePaper}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
@@ -231,4 +286,11 @@ const BrowseBuckets = ({ classes }: IBrowseBucketsProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(BrowseBuckets);
|
||||
const mapDispatchToProps = {
|
||||
addRoute,
|
||||
resetRoutesList,
|
||||
};
|
||||
|
||||
const connector = connect(null, mapDispatchToProps);
|
||||
|
||||
export default withRouter(connector(withStyles(styles)(BrowseBuckets)));
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user