Compare commits

...

63 Commits

Author SHA1 Message Date
Minio Trusted
16647b88e9 update to v0.7.4 2021-05-27 16:32:21 -07:00
Daniel Valdivia
59c4ac6336 Add Sync, Bandwidth and Health Check Period to replication set (#771)
* Add Sync, Bandwidth and Health Check Period to replication set

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

* Update Columns

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

* Add Prefix and Tags

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

* Last fields

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2021-05-27 16:25:00 -07:00
Minio Trusted
49f0b83613 instead of go get use 'go install' 2021-05-26 10:54:27 -07:00
Alex
622f9ed3cd Added URl routing for tabs in buckets (#769)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>

Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2021-05-25 16:16:15 -07:00
Daniel Valdivia
213d7589c6 Latest Assets (#768)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2021-05-24 14:10:12 -07:00
Minio Trusted
0a4f02bd83 update to v0.7.2 2021-05-24 11:53:05 -07:00
Alex
db9b61677c 20 seconds timeout removal (#767)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
Co-authored-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2021-05-24 11:48:41 -07:00
Daniel Valdivia
003eaaea76 Group bucket users and policies under access tab. Rename ViewBuckets to BucketDetails (#766)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2021-05-24 11:11:39 -07:00
Alex
d8350625f3 Added routes to tab selection in storage (#761)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2021-05-21 15:40:39 -07:00
Daniel Valdivia
6b2043c832 Dashboard widgets async (#762)
* Make Widgets load asynchronously

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

* Added loading spinners to all widgets

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2021-05-21 10:24:16 -07:00
Daniel Valdivia
87cb36c944 Fix PVC list so it's only tenant PVCs. Fix NPE on pod listing. (#764) 2021-05-21 07:55:53 -07:00
Alex
59d4ebc109 Fixed issue with graphs that are not showing series correctly (#763)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2021-05-20 17:42:39 -07:00
Lenin Alevski
6eabff3d96 Add support for custom KES image in tenant (#759)
Signed-off-by: Lenin Alevski <alevsk.8772@gmail.com>
2021-05-20 12:31:57 -07:00
adfost
1267f989b2 fixing duplicated usernames (#760) 2021-05-20 12:33:18 -05:00
Daniel Valdivia
2895804e0f Make list of policies on UserDetails clickable. Fix Warnings. Add latest assets (#758)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2021-05-20 09:45:53 -07:00
adfost
c2171fafde User policies (#744)
* adding policy users and new UI page

* Prettier + aligment

Co-authored-by: Adam Stafford <adam@minio.io>
2021-05-19 15:18:59 -07:00
Daniel Valdivia
b0f1f88b5b Remove Excessive Logging. Add missing labels for metrics. (#753)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2021-05-18 09:06:31 -07:00
Daniel Valdivia
8917f415cc Line Break for Tenant Details (#751)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2021-05-17 14:16:03 -07:00
Alex
40aca3da79 Changed Labels for storage section (#750)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2021-05-17 11:52:20 -07:00
Daniel Valdivia
cf27e20bf2 Add the current state to tenant details. Fix Enable/Disable Encryption (#749)
* Add the current state to tenant details

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

* Fix the Enable

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

* Linting

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2021-05-17 11:29:11 -07:00
Daniel Valdivia
3b10eb58ea Update View Bucket screen (#746)
Also add a few refresh screen buttons and remove duplicate titles

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2021-05-14 17:05:02 -07:00
Lenin Alevski
98b4012dde Change bucket encryption configuration UI (#745)
Replace checkbox with pencil icon component to open the bucket
encryption configuration

Signed-off-by: Lenin Alevski <alevsk.8772@gmail.com>
2021-05-14 15:54:14 -07:00
Daniel Valdivia
2769ba145a Add features box to tenant details (#738)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2021-05-14 17:04:29 -05:00
Alex
9c5a788dae Added PVCs section & direct CSI panel (#742)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2021-05-14 13:20:36 -07:00
Alex
a06636035a Added sync icon to get information button (#743)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2021-05-14 10:13:24 -07:00
Daniel Valdivia
1808027fa1 Latest Assets only (#741)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2021-05-13 10:15:31 -07:00
Alex
3ac22d48d5 More Widgets fixes (#739)
* Fix the Prometheus queries

Signed-off-by: Daniel Valdivia <hola@danielvaldivia.com>

* Add missing steps

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

* Enabled missing axis & fixed labels

Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
Co-authored-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2021-05-12 17:52:21 -07:00
Daniel Valdivia
288bf01dd8 Permanently enable ILM (#740)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2021-05-12 16:32:15 -07:00
dependabot[bot]
d546f05e11 Bump hosted-git-info from 2.8.8 to 2.8.9 in /portal-ui (#736)
Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.8 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.8...v2.8.9)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Alex <33497058+bexsoft@users.noreply.github.com>
2021-05-12 16:08:29 -07:00
Alex
5c73137d60 Fixed Console Widgets to match grafana information (#737)
* Fixed Console Widgets to match grafana information

* Fix the Prometheus queries

Signed-off-by: Daniel Valdivia <hola@danielvaldivia.com>

* Add missing steps

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

* adjust interval

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

* Fixed inconsistence with backend names

* Reimplemented step calc to avoid issues on multime times request

Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
Co-authored-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2021-05-12 13:35:14 -07:00
Daniel Valdivia
1daec71271 Update Console Prometheus Widgets (#731)
Signed-off-by: Daniel Valdivia <hola@danielvaldivia.com>
2021-05-10 20:12:15 -07:00
Minio Trusted
3a519cdcfa update to v0.7.1 2021-05-10 19:11:30 -07:00
Daniel Valdivia
a2dce5fa9f Show error when editing tenant Yaml (#733)
* Show error when editing tenant Yaml

Also adds error line when we prepareError()

Signed-off-by: Daniel Valdivia <hola@danielvaldivia.com>

* make certain metadata fields editable

Signed-off-by: Daniel Valdivia <hola@danielvaldivia.com>
2021-05-10 19:08:22 -07:00
Daniel Valdivia
3a7da72919 Fix NodeSelector Screen (#732)
This makes it so the node selector logic is different from podAffinity

Signed-off-by: Daniel Valdivia <hola@danielvaldivia.com>
2021-05-10 17:34:54 -07:00
dependabot[bot]
4f0752c9fc Bump url-parse from 1.4.7 to 1.5.1 in /portal-ui (#728)
Bumps [url-parse](https://github.com/unshiftio/url-parse) from 1.4.7 to 1.5.1.
- [Release notes](https://github.com/unshiftio/url-parse/releases)
- [Commits](https://github.com/unshiftio/url-parse/compare/1.4.7...1.5.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Alex <33497058+bexsoft@users.noreply.github.com>
2021-05-10 16:18:53 -07:00
Daniel Valdivia
59d074c7a9 Allow to edit Tenant YAML (#727) 2021-05-10 17:27:52 -05:00
Daniel Valdivia
c5a8ad3168 Remove duplicated logic (#730)
We were adding the users secrets twice, this consolidates the logic so it's only once and we don't do it if external IDPs are configured

Signed-off-by: Daniel Valdivia <hola@danielvaldivia.com>
2021-05-10 11:31:56 -07:00
Daniel Valdivia
b86a992a33 Fix bug when adding multiple built-in users (#729)
There was a problem with the root credentials being added as a user, and the name of the built in users had collisions with the root credentials

Signed-off-by: Daniel Valdivia <hola@danielvaldivia.com>
2021-05-10 10:56:10 -07:00
Daniel Valdivia
24410e7c85 Make user details a page (#726) 2021-05-08 00:00:29 -07:00
Ravind Kumar
ffb3362f79 Update Console metrics dashboard (#724) 2021-05-07 20:59:25 -05:00
Lenin Alevski
f5beb90608 Hide users tab from bucket view when LDAP is enabled (#719) 2021-05-07 17:48:03 -07:00
Alex
cc02b21632 Fixed missing object in swagger (#725)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2021-05-07 14:14:54 -07:00
adfost
281f8d553a Adding list of pods (#715)
* changing delete button

* committing so I can swich branches

* adding pods

* showing only pods with given tenant

* pull request fixes

* changing pod selection algorithm

* changed the pods API

* Delete admin.json

* Update portal-ui/src/screens/Console/Tenants/TenantDetails/TenantDetails.tsx

Co-authored-by: Alex <33497058+bexsoft@users.noreply.github.com>

* Update portal-ui/src/screens/Console/Tenants/TenantDetails/TenantDetails.tsx

Co-authored-by: Alex <33497058+bexsoft@users.noreply.github.com>

Co-authored-by: Lenin Alevski <alevsk.8772@gmail.com>
Co-authored-by: Adam Stafford <adam@minio.io>
Co-authored-by: Alex <33497058+bexsoft@users.noreply.github.com>
2021-05-06 18:57:14 -07:00
Daniel Valdivia
cc52e267eb Build assets automatically (#721) 2021-05-05 17:24:21 -05:00
Alex
7fdc02aec8 Returned multi user list in tenant created modal (#718)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
2021-05-05 14:33:55 -05:00
Minio Trusted
29e1af3363 update to v0.7.0 2021-05-05 11:24:26 -07:00
Daniel Valdivia
8a635fc0d7 Make Log Search and Prometheus images configurable (#717)
Three new fields were added to let users customize the docker images for log search and prometheus

Signed-off-by: Daniel Valdivia <hola@danielvaldivia.com>
2021-05-04 14:46:10 -07:00
Alex
35da684ec9 Added direct-csi API support to console (#710) 2021-05-04 11:56:33 -05:00
Daniel Valdivia
8cfa41eb53 Make Tabs Scrollable (#714)
This makes so tab components are scrollable if the resolution on the screen demands it

Signed-off-by: Daniel Valdivia <hola@danielvaldivia.com>
2021-05-03 13:19:35 -07:00
Alex
08e40fe632 Fixed issue with namespace not returning error (#709)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>

Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2021-05-03 08:38:20 -07:00
Alex
0b0cb785b5 Fixed small issues & removed warnings in console (#711) 2021-04-27 21:55:16 -07:00
Daniel Valdivia
5838606789 Improvements to Built-In users (#708) 2021-04-27 13:07:25 -07:00
Alex
38f95e3b28 Added affinity support to tenant add screen (#706) 2021-04-26 18:40:09 -07:00
Daniel Valdivia
0c90785ed0 Remove printing of tenant yaml (#705)
Signed-off-by: Daniel Valdivia <hola@danielvaldivia.com>

Co-authored-by: Alex <33497058+bexsoft@users.noreply.github.com>
2021-04-26 10:35:45 -07:00
Alex
62d762318f Tiers & lifecycle implementation (#638) 2021-04-24 14:31:47 -07:00
adfost
097e6e9825 changing delete button (#704)
Co-authored-by: Lenin Alevski <alevsk.8772@gmail.com>
2021-04-23 15:56:06 -07:00
Alex
9e35db0642 Added validation for single tenant in namespace (#701)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>

Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2021-04-23 13:38:02 -07:00
Lenin Alevski
3b55d63211 Attaching subnet license to existing tenants fails (#702)
Uses the right tenant namespace to update console secrets instead of the
wrong operator namespace

Signed-off-by: Lenin Alevski <alevsk.8772@gmail.com>
2021-04-23 12:58:37 -07:00
Alex
2981e63797 Fixes an issue with empty logsearch & prometheus configurations (#703) 2021-04-22 20:54:17 -07:00
adfost
ca742b781f Adding key creation in tenant wizard. (#697)
Signed-off-by: Adam Stafford <adam@minio.io>

Co-authored-by: Adam Stafford <adamstafford@MacBook-Pro-van-Adam-2.local>
2021-04-22 14:18:14 -07:00
dependabot[bot]
d60cac0122 Bump ssri from 6.0.1 to 6.0.2 in /portal-ui (#698)
Bumps [ssri](https://github.com/npm/ssri) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/npm/ssri/releases)
- [Changelog](https://github.com/npm/ssri/blob/v6.0.2/CHANGELOG.md)
- [Commits](https://github.com/npm/ssri/compare/v6.0.1...v6.0.2)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Alex <33497058+bexsoft@users.noreply.github.com>
2021-04-20 23:59:09 -07:00
Alex
62745e9ff2 Added log search & prometheus extra params configuration (#700) 2021-04-20 23:39:14 -07:00
Alex
c81da22e8a Added storage class selector to add pool modal (#699)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2021-04-19 18:26:22 -07:00
263 changed files with 25487 additions and 4349 deletions

View File

@@ -28,12 +28,14 @@ WORKDIR /go/src/github.com/minio/console/
ENV CGO_ENABLED=0
COPY --from=uilayer /app/build /go/src/github.com/minio/console/portal-ui/build
RUN go build -ldflags "-w -s" -a -o console ./cmd/console
FROM scratch
MAINTAINER MinIO Development "dev@min.io"
EXPOSE 9090
COPY --from=golayer /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=golayer /go/src/github.com/minio/console/console .

View File

@@ -55,7 +55,7 @@ docker pull minio/console
### Build from source
```
GO111MODULE=on go get github.com/minio/console/cmd/console
GO111MODULE=on go install github.com/minio/console/cmd/console@latest
```
> You will need a working Go environment. Therefore, please follow [How to install Go](https://golang.org/doc/install).
> Minimum version required is go1.16

13
go.mod
View File

@@ -18,19 +18,20 @@ require (
github.com/minio/cli v1.22.0
github.com/minio/direct-csi v1.2.8
github.com/minio/kes v0.11.0
github.com/minio/mc v0.0.0-20210301162250-f9d36f9b5243
github.com/minio/minio v0.0.0-20210301203133-e8d8dfa3ae8f
github.com/minio/minio-go/v7 v7.0.10
github.com/minio/operator v0.0.0-20210317030027-207337abe7fd
github.com/minio/mc v0.0.0-20210422171734-4eae7ec7ed25
github.com/minio/minio v0.0.0-20210423185853-cbfdf97abf9f
github.com/minio/minio-go/v7 v7.0.11-0.20210407221404-ba867dba7ee1
github.com/minio/operator v0.0.0-20210419212754-93a9239fd18b
github.com/minio/operator/logsearchapi v0.0.0-20210201110528-753019b838b4
github.com/minio/selfupdate v0.3.1
github.com/mitchellh/go-homedir v1.1.0
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
github.com/rs/xid v1.2.1
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-20201124201722-c8d3bf9c5392
golang.org/x/net v0.0.0-20201216054612-986b41b23924
golang.org/x/crypto v0.0.0-20210415154028-4f45737414dc
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
gopkg.in/yaml.v2 v2.3.0
k8s.io/api v0.20.2

113
go.sum
View File

@@ -9,6 +9,7 @@ cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxK
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
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=
@@ -55,6 +56,7 @@ github.com/Azure/go-autorest v14.1.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSW
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
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.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
github.com/Azure/go-autorest/autorest v0.10.2/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
@@ -119,6 +121,7 @@ github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdc
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE=
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=
@@ -126,6 +129,7 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/apex/log v1.1.4/go.mod h1:AlpoD9aScyQfJDVHmLMEcx4oU6LqzkWp4Mg9GdAcEvQ=
@@ -375,6 +379,7 @@ github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf
github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs=
github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI=
github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk=
github.com/go-openapi/loads v0.19.5 h1:jZVYWawIQiA1NBnHla28ktg6hrcfTHsCE+3QLVRBIls=
github.com/go-openapi/loads v0.19.5/go.mod h1:dswLCAdonkRufe/gSUC3gN8nTSaB9uaS2es0x5/IbjY=
github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
@@ -410,6 +415,7 @@ github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfT
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo=
github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
github.com/go-openapi/validate v0.19.10 h1:tG3SZ5DC5KF4cyt7nqLVcQXGj5A7mpaYkAcNPlDK+Yk=
github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbNMAuKvKB+IaGx8=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
@@ -468,8 +474,9 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
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/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
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=
@@ -536,8 +543,9 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
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=
@@ -568,6 +576,7 @@ github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
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/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
@@ -788,6 +797,7 @@ github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaR
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
@@ -795,8 +805,9 @@ github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0
github.com/klauspost/compress v1.10.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.7 h1:0hzRabrMN4tSTvMfnL3SCv1ZGeAP23ynzodBgaHeMeg=
github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.12 h1:famVnQVu7QwryBN4jNseQdUKES71ZAOnB6UQQJPZvqk=
github.com/klauspost/compress v1.11.12/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/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
@@ -833,12 +844,15 @@ 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.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.4.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8=
github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g=
github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
@@ -899,26 +913,27 @@ github.com/minio/controller-tools v0.4.7/go.mod h1:xES4iNis9dGrLQuP6nquTZZNg2T0/
github.com/minio/direct-csi v1.2.8 h1:jOpefwTGZYUIzouz5McSQ8EqeXO7Qu5aCJIwstbc6vs=
github.com/minio/direct-csi v1.2.8/go.mod h1:+Zw8NjMQ5rQqySezan6G9DsQjHSHQCPWJli3v9dP80o=
github.com/minio/highwayhash v1.0.0/go.mod h1:xQboMTeM9nY9v/LlAOxFctujiv5+Aq2hR5dxBpaMbdc=
github.com/minio/highwayhash v1.0.1 h1:dZ6IIu8Z14VlC0VpfKofAhCy74wu/Qb5gcn52yWoz/0=
github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=
github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
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-20210301162250-f9d36f9b5243 h1:V0EoJ/I/p86J8FH2zuOSTsTzNzDXQX4xZKvBwBLS/Qk=
github.com/minio/mc v0.0.0-20210301162250-f9d36f9b5243/go.mod h1:nkHp/atLUKkhML5YGfvaDDFqlcBmuii7s9Dbk3ulB1Q=
github.com/minio/mc v0.0.0-20210422171734-4eae7ec7ed25 h1:HrVywZfBwMUS6fQMdaOgyD5XJEMnwd7fAaR99oy5mow=
github.com/minio/mc v0.0.0-20210422171734-4eae7ec7ed25/go.mod h1:0mEfTTrQEZJXPvi9dNQWRlRplsmSmH+Z5h6G/2N3F/0=
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
github.com/minio/md5-simd v1.1.1 h1:9ojcLbuZ4gXbB2sX53MKn8JUZ0sB/2wfwsEcRw+I08U=
github.com/minio/md5-simd v1.1.1/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
github.com/minio/minio v0.0.0-20210110213705-828602d672f7/go.mod h1:fp/MFzOSx+MgC/b1epAX6ZLXvBP+zaemt7cV98+UsUg=
github.com/minio/minio v0.0.0-20210128013121-e79829b5b368/go.mod h1:6jySvEwvfCfr9SphRrAb+TMtEXRgRJ4sb79UKFJWmFM=
github.com/minio/minio v0.0.0-20210301081546-0b9c17443eb8/go.mod h1:E7ngQWKJdbRG9dqHZ86lnhGS0RxqtEJTnWDEM/P9BQs=
github.com/minio/minio v0.0.0-20210301203133-e8d8dfa3ae8f h1:dAFaii7oqV0Mu9rUNfsgKdE10aZADSgIXoK5saLVeOE=
github.com/minio/minio v0.0.0-20210301203133-e8d8dfa3ae8f/go.mod h1:E7ngQWKJdbRG9dqHZ86lnhGS0RxqtEJTnWDEM/P9BQs=
github.com/minio/minio v0.0.0-20210421185923-38a9f87a560e/go.mod h1:XNPkjbDN/j7cNOoaE0TefFKeDycjJVkYTGRJlD6I9EI=
github.com/minio/minio v0.0.0-20210423185853-cbfdf97abf9f h1:2IVnOLvfO2HY9n82nHKhLcxVbCPFsVvSCzO33rAgd7w=
github.com/minio/minio v0.0.0-20210423185853-cbfdf97abf9f/go.mod h1:RDrFSTbgdNK7uLIZZqfx93L973cEj6EecG2OGfOeUp8=
github.com/minio/minio-go/v7 v7.0.7-0.20201217170524-3baf9ea06f7c/go.mod h1:pEZBUa+L2m9oECoIA6IcSK8bv/qggtQVLovjeKK5jYc=
github.com/minio/minio-go/v7 v7.0.8-0.20210127003153-c40722862654/go.mod h1:pEZBUa+L2m9oECoIA6IcSK8bv/qggtQVLovjeKK5jYc=
github.com/minio/minio-go/v7 v7.0.10 h1:1oUKe4EOPUEhw2qnPQaPsJ0lmVTYLFu03SiItauXs94=
github.com/minio/minio-go/v7 v7.0.10/go.mod h1:td4gW1ldOsj1PbSNS+WYK43j+P1XVhX/8W8awaYlBFo=
github.com/minio/operator v0.0.0-20210317030027-207337abe7fd h1:ibM7ebC9WdtgJh6p3mqbU0W1vpoFXqJgTHDBKJWGRQI=
github.com/minio/operator v0.0.0-20210317030027-207337abe7fd/go.mod h1:1Bpqm6g8f30YeePauZfSet7EWrWeyqu1eJhY5/4sn28=
github.com/minio/minio-go/v7 v7.0.11-0.20210302210017-6ae69c73ce78/go.mod h1:mTh2uJuAbEqdhMVl6CMIIZLUeiMiWtJR4JB8/5g2skw=
github.com/minio/minio-go/v7 v7.0.11-0.20210407221404-ba867dba7ee1 h1:x0jnjGGnb0PaewBIH9dbTaLJUNVKYoQOjjdqwz9PwdQ=
github.com/minio/minio-go/v7 v7.0.11-0.20210407221404-ba867dba7ee1/go.mod h1:mTh2uJuAbEqdhMVl6CMIIZLUeiMiWtJR4JB8/5g2skw=
github.com/minio/operator v0.0.0-20210419212754-93a9239fd18b h1:3TV7FQpciS08+66ydlSPHSU96hMUjt1696xW6NrAcmk=
github.com/minio/operator v0.0.0-20210419212754-93a9239fd18b/go.mod h1:kPcdt1W5H4gBMzrH1Pz1LHkCD5QQDDwkU62MyYg3O8M=
github.com/minio/operator/logsearchapi v0.0.0-20210201110528-753019b838b4 h1:7HNd0WPMFcQzQbgPs7VQJfiXVm8xjuxnS3/1yi4twwM=
github.com/minio/operator/logsearchapi v0.0.0-20210201110528-753019b838b4/go.mod h1:ngzK3RurLvshJ4XmJ6eP4WTOIc9Vu1HQNq0Hm6XOZmw=
github.com/minio/selfupdate v0.3.1 h1:BWEFSNnrZVMUWXbXIgLDNDjbejkmpAmZvy/nCz1HlEs=
@@ -929,6 +944,7 @@ github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy
github.com/minio/simdjson-go v0.1.5/go.mod h1:oKURrZZEBtqObgJrSjN1Ln2n9MJj2icuBTkeJzZnvSI=
github.com/minio/simdjson-go v0.2.0/go.mod h1:JPUSkRykfSPS+AhO0YPA1h0l5vY7NqrF4zel2b12wxc=
github.com/minio/simdjson-go v0.2.1/go.mod h1:JPUSkRykfSPS+AhO0YPA1h0l5vY7NqrF4zel2b12wxc=
github.com/minio/sio v0.2.1 h1:NjzKiIMSMcHediVQR0AFVx2tp7Wxh9tKPfDI3kH7aHQ=
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=
@@ -976,8 +992,9 @@ github.com/nats-io/jwt v1.1.0/go.mod h1:n3cvmLfBfnpV4JJRN7lRYCyZnw48ksGsbThGXEk4
github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
github.com/nats-io/nats-server/v2 v2.1.9 h1:Sxr2zpaapgpBT9ElTxTVe62W+qjnhPcKY/8W5cnA/Qk=
github.com/nats-io/nats-server/v2 v2.1.9/go.mod h1:9qVyoewoYXzG1ME9ox0HwkkzyYvnlBDugfR4Gg/8uHU=
github.com/nats-io/nats-streaming-server v0.19.0 h1:NVYusu6kcMxRBj1wOWRdXBUHf1bzkJQbsHovsg+Fr1o=
github.com/nats-io/nats-streaming-server v0.19.0/go.mod h1:oqrRqpMg84aiPDyroTornjVWNYJKh+6ozh2Mgt8dslE=
github.com/nats-io/nats-streaming-server v0.21.1 h1:jb/osnXmFJtKDS9DFghDjX82v1NT9IhaoR/r6s6toNg=
github.com/nats-io/nats-streaming-server v0.21.1/go.mod h1:2W8QfNVOtcFpmf0bRiwuLtRb0/hkX4NuOxPOFNOThVQ=
github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
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=
@@ -988,8 +1005,9 @@ github.com/nats-io/nkeys v0.2.0 h1:WXKF7diOaPU9cJdLD7nuzwasQy9vT1tBqzXZZf3AMJM=
github.com/nats-io/nkeys v0.2.0/go.mod h1:XdZpAbhgyyODYqjTawOnIOI7VlbKSarI9Gfy1tqEu/s=
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/nats-io/stan.go v0.7.0 h1:sMVHD9RkxPOl6PJfDVBQd+gbxWkApeYl6GrH+10msO4=
github.com/nats-io/stan.go v0.7.0/go.mod h1:Ci6mUIpGQTjl++MqK2XzkWI/0vF+Bl72uScx7ejSYmU=
github.com/nats-io/stan.go v0.8.3 h1:XyemjL9vAeGHooHn5RQy+ngljd8AVSM2l65Jdnpv4rI=
github.com/nats-io/stan.go v0.8.3/go.mod h1:Ejm8bbHnMTSptU6uNMAVuxeapMJYBB/Ml3ej6z4GoSY=
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
github.com/ncw/directio v1.0.5 h1:JSUBhdjEvVaJvOoyPAbcW0fnd0tvRXD76wEfZ1KcQz4=
github.com/ncw/directio v1.0.5/go.mod h1:rX/pKEYkOXBGOggmcyJeJGloCkleSvphPx2eV3t6ROk=
@@ -1050,6 +1068,7 @@ github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bA
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
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.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ=
github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
@@ -1074,6 +1093,9 @@ github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSg
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU=
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.44.1/go.mod h1:3WYi4xqXxGGXWDdQIITnLNmuDzO5n6wYva9spVhR4fg=
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.46.0/go.mod h1:3WYi4xqXxGGXWDdQIITnLNmuDzO5n6wYva9spVhR4fg=
github.com/prometheus-operator/prometheus-operator/pkg/client v0.46.0/go.mod h1:k4BrWlVQQsvBiTcDnKEMgyh/euRxyxgrHdur/ZX/sdA=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
@@ -1106,8 +1128,9 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4=
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=
github.com/quasilyte/go-ruleguard v0.1.2-0.20200318202121-b00d7a75d3d8/go.mod h1:CGFX09Ci3pq9QZdj86B+VGIdNj4VyCo2iPOGS9esB/k=
@@ -1166,8 +1189,9 @@ github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU=
github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
@@ -1230,7 +1254,10 @@ github.com/tetafro/godot v0.3.7/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQx
github.com/tetafro/godot v0.4.2/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0=
github.com/tidwall/gjson v1.3.5/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
github.com/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI=
github.com/tidwall/gjson v1.6.8 h1:CTmXMClGYPAmln7652e69B7OLXfTi5ABcPPwjIWUv7w=
github.com/tidwall/gjson v1.6.8/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI=
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
github.com/tidwall/match v1.0.3 h1:FQUVvBImDutD8wJLN6c5eMzWtjgONK9MwIBCOrUJKeE=
github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tidwall/pretty v1.0.2 h1:Z7S3cePv9Jwm1KwS0513MRaoUe3S01WPbLNV40pwWZU=
@@ -1238,6 +1265,7 @@ github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhV
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.3 h1:3giwAkmtaEDLSV0MdO1lDLuPgklgPzmk8H9+So2BVfA=
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=
@@ -1267,6 +1295,7 @@ github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOV
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a h1:0R4NLDRDZX6JcmhJgXi5E4b8Wg84ihbmUKp/GvSPEzc=
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/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
github.com/willf/bloom v2.0.3+incompatible/go.mod h1:MmAltL9pDMNTrvUkxdg0k0q5I0suxmuwp3KbyrZLOZ8=
@@ -1367,8 +1396,10 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392 h1:xYJJ3S178yv++9zXV/hnr29plCAGO9vAFG9dorqaFQc=
golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210415154028-4f45737414dc h1:+q90ECDSAQirdykUN6sPEiBXBsp8Csjcca8Oy7bgLTA=
golang.org/x/crypto v0.0.0-20210415154028-4f45737414dc/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
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=
@@ -1401,8 +1432,9 @@ 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/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=
golang.org/x/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1451,8 +1483,9 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201216054612-986b41b23924 h1:QsnDpLLOKwHBBDa8nDws4DYNc/ryVW2vCpxCs09d4PY=
golang.org/x/net v0.0.0-20201216054612-986b41b23924/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
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=
@@ -1471,6 +1504,7 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/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-20180816055513-1c9583448a9c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1513,6 +1547,7 @@ golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1535,6 +1570,7 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1542,8 +1578,10 @@ golang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M=
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -1572,6 +1610,7 @@ golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190221204921-83362c3779f5/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -1635,6 +1674,7 @@ golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjs
golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200331202046-9d5940d49312/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200410194907-79a7a3126eef/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/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -1645,13 +1685,16 @@ golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200616195046-dc31b401abb5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20201105001634-bc3cf281b174/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210115202250-e0d201561e39/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.1-0.20210201201750-4d4ee958a9b7 h1:/wdPW261t381NDQd8TBo63/FyvACfLICwtH8wMRoHJQ=
golang.org/x/tools v0.1.1-0.20210201201750-4d4ee958a9b7/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1819,41 +1862,53 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh
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/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=
honnef.co/go/tools v0.0.1-2020.1.5/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.6 h1:W18jzjh8mfPez+AwGLxmOImucz/IFjpNlrKVnaj2YVc=
honnef.co/go/tools v0.0.1-2020.1.6/go.mod h1:pyyisuGw24ruLjrr1ddx39WE0y9OooInRzEYLhQB2YY=
k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI=
k8s.io/api v0.17.4/go.mod h1:5qxx6vjmwUVG2nHQTKGlLts8Tbok8PzHl4vHtVFuZCA=
k8s.io/api v0.18.3/go.mod h1:UOaMwERbqJMfeeeHc8XJKawj4P9TgDRnViIqqBeH2QA=
k8s.io/api v0.19.2/go.mod h1:IQpK0zFQ1xc5iNIQPqzgoOwuFugaYHK4iCknlAQP9nI=
k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
k8s.io/api v0.20.2 h1:y/HR22XDZY3pniu9hIFDLpUCPq2w5eQ6aV/VFQ7uJMw=
k8s.io/api v0.20.2/go.mod h1:d7n6Ehyzx+S+cE3VhTGfVNNqtGc/oL9DCdYYahlurV8=
k8s.io/apiextensions-apiserver v0.18.3/go.mod h1:TMsNGs7DYpMXd+8MOCX8KzPOCx8fnZMoIGB24m03+JE=
k8s.io/apiextensions-apiserver v0.20.1/go.mod h1:ntnrZV+6a3dB504qwC5PN/Yg9PBiDNt1EVqbW2kORVk=
k8s.io/apiextensions-apiserver v0.20.2/go.mod h1:F6TXp389Xntt+LUq3vw6HFOLttPa0V8821ogLGwb6Zs=
k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
k8s.io/apimachinery v0.17.1-beta.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
k8s.io/apimachinery v0.17.4/go.mod h1:gxLnyZcGNdZTCLnq3fgzyg2A5BVCHTNDFrw8AmuJ+0g=
k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
k8s.io/apimachinery v0.19.2/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA=
k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
k8s.io/apimachinery v0.20.2 h1:hFx6Sbt1oG0n6DZ+g4bFt5f6BoMkOjKWsQFu077M3Vg=
k8s.io/apimachinery v0.20.2/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
k8s.io/apiserver v0.17.4/go.mod h1:5ZDQ6Xr5MNBxyi3iUZXS84QOhZl+W7Oq2us/29c0j9I=
k8s.io/apiserver v0.18.3/go.mod h1:tHQRmthRPLUtwqsOnJJMoI8SW3lnoReZeE861lH8vUw=
k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
k8s.io/apiserver v0.20.2/go.mod h1:2nKd93WyMhZx4Hp3RfgH2K5PhwyTrprrkWYnI7id7jA=
k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k=
k8s.io/client-go v0.17.4/go.mod h1:ouF6o5pz3is8qU0/qYL2RnoxOPqgfuidYLowytyLJmc=
k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw=
k8s.io/client-go v0.19.2/go.mod h1:S5wPhCqyDNAlzM9CnEdgTGV4OqhsW3jGO1UM1epwfJA=
k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=
k8s.io/client-go v0.20.2 h1:uuf+iIAbfnCSw8IGAv/Rg0giM+2bOzHLOsbbrwrdhNQ=
k8s.io/client-go v0.20.2/go.mod h1:kH5brqWqp7HDxUFKoEgiI4v8G1xzbe9giaCenUWJzgE=
k8s.io/cloud-provider v0.17.4/go.mod h1:XEjKDzfD+b9MTLXQFlDGkk6Ho8SGMpaU8Uugx/KNK9U=
k8s.io/code-generator v0.17.2/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s=
k8s.io/code-generator v0.18.3/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
k8s.io/code-generator v0.20.1/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg=
k8s.io/code-generator v0.20.2/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg=
k8s.io/code-generator v0.20.4/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg=
k8s.io/component-base v0.17.0/go.mod h1:rKuRAokNMY2nn2A6LP/MiwpoaMRHpfRnrPaUJJj1Yoc=
k8s.io/component-base v0.17.4/go.mod h1:5BRqHMbbQPm2kKu35v3G+CpVq4K0RJKC7TRioF0I9lE=
k8s.io/component-base v0.18.3/go.mod h1:bp5GzGR0aGkYEfTj+eTY0AN/vXTgkJdQXjNTTVUaa3k=
k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk=
k8s.io/component-base v0.20.2/go.mod h1:pzFtCiwe/ASD0iV7ySMu8SYVJjCapNM9bjvk7ptpKh0=
k8s.io/csi-translation-lib v0.17.4/go.mod h1:CsxmjwxEI0tTNMzffIAcgR9lX4wOh6AKHdxQrT7L0oo=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
@@ -1865,10 +1920,14 @@ k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/klog/v2 v2.4.0 h1:7+X0fUguPyrKEC4WjH8iGDg3laWgMo5tMnRTIGTTxGQ=
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o=
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd h1:sOHNzJIkytDF6qadMNKhhDRpc6ODik8lVC6nOur7B2c=
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
k8s.io/legacy-cloud-providers v0.17.4/go.mod h1:FikRNoD64ECjkxO36gkDgJeiQWwyZTuBkhu+yxOc1Js=
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
@@ -1885,6 +1944,7 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
sigs.k8s.io/controller-runtime v0.8.0 h1:s0dYdo7lQgJiAf+alP82PRwbz+oAqL3oSyMQ18XRDOc=
sigs.k8s.io/controller-runtime v0.8.0/go.mod h1:v9Lbj5oX443uR7GXYY46E0EE2o7k2YxQ58GxVNeXSW4=
@@ -1892,6 +1952,9 @@ sigs.k8s.io/controller-tools v0.5.0/go.mod h1:JTsstrMpxs+9BUj6eGuAaEb6SDSPTeVtUy
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU=
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18=
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2 h1:YHQV7Dajm86OuqnIR6zAelnDWBRjo+YhYV9PmGrh1s8=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 314 KiB

View File

@@ -15,7 +15,7 @@ spec:
serviceAccountName: console-sa
containers:
- name: console
image: minio/console:v0.6.8
image: minio/console:v0.7.4
imagePullPolicy: "IfNotPresent"
args:
- server

View File

@@ -15,7 +15,7 @@ spec:
serviceAccountName: console-sa
containers:
- name: console
image: minio/console:v0.6.8
image: minio/console:v0.7.4
imagePullPolicy: "IfNotPresent"
env:
- name: CONSOLE_OPERATOR_MODE

View File

@@ -0,0 +1,93 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// AddBucketLifecycle add bucket lifecycle
//
// swagger:model addBucketLifecycle
type AddBucketLifecycle struct {
// Non required, toggle to disable or enable rule
Disable bool `json:"disable,omitempty"`
// Non required, toggle to disable or enable rule
ExpiredObjectDeleteMarker bool `json:"expired_object_delete_marker,omitempty"`
// Required in case of expiry_days or transition fields are not set. it defines an expiry date for ILM
ExpiryDate string `json:"expiry_date,omitempty"`
// Required in case of expiry_date or transition fields are not set. it defines an expiry days for ILM
ExpiryDays int32 `json:"expiry_days,omitempty"`
// Non required, can be set in case of expiration is enabled
NoncurrentversionExpirationDays int32 `json:"noncurrentversion_expiration_days,omitempty"`
// Non required, can be set in case of transition is enabled
NoncurrentversionTransitionDays int32 `json:"noncurrentversion_transition_days,omitempty"`
// Non required, can be set in case of transition is enabled
NoncurrentversionTransitionStorageClass string `json:"noncurrentversion_transition_storage_class,omitempty"`
// Non required field, it matches a prefix to perform ILM operations on it
Prefix string `json:"prefix,omitempty"`
// Required only in case of transition is set. it refers to a tier
StorageClass string `json:"storage_class,omitempty"`
// Non required field, tags to match ILM files
Tags string `json:"tags,omitempty"`
// Required in case of transition_days or expiry fields are not set. it defines a transition date for ILM
TransitionDate string `json:"transition_date,omitempty"`
// Required in case of transition_date or expiry fields are not set. it defines a transition days for ILM
TransitionDays int32 `json:"transition_days,omitempty"`
}
// Validate validates this add bucket lifecycle
func (m *AddBucketLifecycle) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *AddBucketLifecycle) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *AddBucketLifecycle) UnmarshalBinary(b []byte) error {
var res AddBucketLifecycle
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -0,0 +1,97 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// BucketLifecycleResponse bucket lifecycle response
//
// swagger:model bucketLifecycleResponse
type BucketLifecycleResponse struct {
// lifecycle
Lifecycle []*ObjectBucketLifecycle `json:"lifecycle"`
}
// Validate validates this bucket lifecycle response
func (m *BucketLifecycleResponse) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateLifecycle(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *BucketLifecycleResponse) validateLifecycle(formats strfmt.Registry) error {
if swag.IsZero(m.Lifecycle) { // not required
return nil
}
for i := 0; i < len(m.Lifecycle); i++ {
if swag.IsZero(m.Lifecycle[i]) { // not required
continue
}
if m.Lifecycle[i] != nil {
if err := m.Lifecycle[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("lifecycle" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// MarshalBinary interface implementation
func (m *BucketLifecycleResponse) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *BucketLifecycleResponse) UnmarshalBinary(b []byte) error {
var res BucketLifecycleResponse
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -36,31 +36,49 @@ import (
// swagger:model bucketReplicationRule
type BucketReplicationRule struct {
// bandwidth
Bandwidth string `json:"bandwidth,omitempty"`
// delete marker replication
DeleteMarkerReplication *BucketReplicationRuleMarker `json:"delete_marker_replication,omitempty"`
DeleteMarkerReplication bool `json:"delete_marker_replication,omitempty"`
// deletes replication
DeletesReplication bool `json:"deletes_replication,omitempty"`
// destination
Destination *BucketReplicationDestination `json:"destination,omitempty"`
// health check period
HealthCheckPeriod int64 `json:"healthCheckPeriod,omitempty"`
// id
ID string `json:"id,omitempty"`
// metadata replication
MetadataReplication bool `json:"metadata_replication,omitempty"`
// prefix
Prefix string `json:"prefix,omitempty"`
// priority
Priority int32 `json:"priority,omitempty"`
// status
// Enum: [Enabled Disabled]
Status string `json:"status,omitempty"`
// sync mode
// Enum: [async sync]
SyncMode *string `json:"syncMode,omitempty"`
// tags
Tags string `json:"tags,omitempty"`
}
// Validate validates this bucket replication rule
func (m *BucketReplicationRule) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateDeleteMarkerReplication(formats); err != nil {
res = append(res, err)
}
if err := m.validateDestination(formats); err != nil {
res = append(res, err)
}
@@ -69,30 +87,16 @@ func (m *BucketReplicationRule) Validate(formats strfmt.Registry) error {
res = append(res, err)
}
if err := m.validateSyncMode(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *BucketReplicationRule) validateDeleteMarkerReplication(formats strfmt.Registry) error {
if swag.IsZero(m.DeleteMarkerReplication) { // not required
return nil
}
if m.DeleteMarkerReplication != nil {
if err := m.DeleteMarkerReplication.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("delete_marker_replication")
}
return err
}
}
return nil
}
func (m *BucketReplicationRule) validateDestination(formats strfmt.Registry) error {
if swag.IsZero(m.Destination) { // not required
@@ -154,6 +158,49 @@ func (m *BucketReplicationRule) validateStatus(formats strfmt.Registry) error {
return nil
}
var bucketReplicationRuleTypeSyncModePropEnum []interface{}
func init() {
var res []string
if err := json.Unmarshal([]byte(`["async","sync"]`), &res); err != nil {
panic(err)
}
for _, v := range res {
bucketReplicationRuleTypeSyncModePropEnum = append(bucketReplicationRuleTypeSyncModePropEnum, v)
}
}
const (
// BucketReplicationRuleSyncModeAsync captures enum value "async"
BucketReplicationRuleSyncModeAsync string = "async"
// BucketReplicationRuleSyncModeSync captures enum value "sync"
BucketReplicationRuleSyncModeSync string = "sync"
)
// prop value enum
func (m *BucketReplicationRule) validateSyncModeEnum(path, location string, value string) error {
if err := validate.EnumCase(path, location, value, bucketReplicationRuleTypeSyncModePropEnum, true); err != nil {
return err
}
return nil
}
func (m *BucketReplicationRule) validateSyncMode(formats strfmt.Registry) error {
if swag.IsZero(m.SyncMode) { // not required
return nil
}
// value enum
if err := m.validateSyncModeEnum("syncMode", "body", *m.SyncMode); err != nil {
return err
}
return nil
}
// MarshalBinary interface implementation
func (m *BucketReplicationRule) MarshalBinary() ([]byte, error) {
if m == nil {

View File

@@ -1,117 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// BucketReplicationRuleMarker bucket replication rule marker
//
// swagger:model bucketReplicationRuleMarker
type BucketReplicationRuleMarker struct {
// status
// Enum: [Enabled Disabled]
Status string `json:"status,omitempty"`
}
// Validate validates this bucket replication rule marker
func (m *BucketReplicationRuleMarker) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateStatus(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
var bucketReplicationRuleMarkerTypeStatusPropEnum []interface{}
func init() {
var res []string
if err := json.Unmarshal([]byte(`["Enabled","Disabled"]`), &res); err != nil {
panic(err)
}
for _, v := range res {
bucketReplicationRuleMarkerTypeStatusPropEnum = append(bucketReplicationRuleMarkerTypeStatusPropEnum, v)
}
}
const (
// BucketReplicationRuleMarkerStatusEnabled captures enum value "Enabled"
BucketReplicationRuleMarkerStatusEnabled string = "Enabled"
// BucketReplicationRuleMarkerStatusDisabled captures enum value "Disabled"
BucketReplicationRuleMarkerStatusDisabled string = "Disabled"
)
// prop value enum
func (m *BucketReplicationRuleMarker) validateStatusEnum(path, location string, value string) error {
if err := validate.EnumCase(path, location, value, bucketReplicationRuleMarkerTypeStatusPropEnum, true); err != nil {
return err
}
return nil
}
func (m *BucketReplicationRuleMarker) validateStatus(formats strfmt.Registry) error {
if swag.IsZero(m.Status) { // not required
return nil
}
// value enum
if err := m.validateStatusEnum("status", "body", m.Status); err != nil {
return err
}
return nil
}
// MarshalBinary interface implementation
func (m *BucketReplicationRuleMarker) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *BucketReplicationRuleMarker) UnmarshalBinary(b []byte) error {
var res BucketReplicationRuleMarker
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -23,6 +23,8 @@ package models
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
@@ -39,6 +41,12 @@ type CreateRemoteBucket struct {
// Min Length: 3
AccessKey *string `json:"accessKey"`
// bandwidth
Bandwidth int64 `json:"bandwidth,omitempty"`
// health check period
HealthCheckPeriod int32 `json:"healthCheckPeriod,omitempty"`
// region
Region string `json:"region,omitempty"`
@@ -51,6 +59,10 @@ type CreateRemoteBucket struct {
// Required: true
SourceBucket *string `json:"sourceBucket"`
// sync mode
// Enum: [async sync]
SyncMode *string `json:"syncMode,omitempty"`
// target bucket
// Required: true
TargetBucket *string `json:"targetBucket"`
@@ -76,6 +88,10 @@ func (m *CreateRemoteBucket) Validate(formats strfmt.Registry) error {
res = append(res, err)
}
if err := m.validateSyncMode(formats); err != nil {
res = append(res, err)
}
if err := m.validateTargetBucket(formats); err != nil {
res = append(res, err)
}
@@ -125,6 +141,49 @@ func (m *CreateRemoteBucket) validateSourceBucket(formats strfmt.Registry) error
return nil
}
var createRemoteBucketTypeSyncModePropEnum []interface{}
func init() {
var res []string
if err := json.Unmarshal([]byte(`["async","sync"]`), &res); err != nil {
panic(err)
}
for _, v := range res {
createRemoteBucketTypeSyncModePropEnum = append(createRemoteBucketTypeSyncModePropEnum, v)
}
}
const (
// CreateRemoteBucketSyncModeAsync captures enum value "async"
CreateRemoteBucketSyncModeAsync string = "async"
// CreateRemoteBucketSyncModeSync captures enum value "sync"
CreateRemoteBucketSyncModeSync string = "sync"
)
// prop value enum
func (m *CreateRemoteBucket) validateSyncModeEnum(path, location string, value string) error {
if err := validate.EnumCase(path, location, value, createRemoteBucketTypeSyncModePropEnum, true); err != nil {
return err
}
return nil
}
func (m *CreateRemoteBucket) validateSyncMode(formats strfmt.Registry) error {
if swag.IsZero(m.SyncMode) { // not required
return nil
}
// value enum
if err := m.validateSyncModeEnum("syncMode", "body", *m.SyncMode); err != nil {
return err
}
return nil
}
func (m *CreateRemoteBucket) validateTargetBucket(formats strfmt.Registry) error {
if err := validate.Required("targetBucket", "body", m.TargetBucket); err != nil {

View File

@@ -84,6 +84,9 @@ type CreateTenantRequest struct {
// labels
Labels map[string]string `json:"labels,omitempty"`
// log search configuration
LogSearchConfiguration *LogSearchConfiguration `json:"logSearchConfiguration,omitempty"`
// mounth path
MounthPath string `json:"mounth_path,omitempty"`
@@ -100,6 +103,9 @@ type CreateTenantRequest struct {
// Required: true
Pools []*Pool `json:"pools"`
// prometheus configuration
PrometheusConfiguration *PrometheusConfiguration `json:"prometheusConfiguration,omitempty"`
// secret key
SecretKey string `json:"secret_key,omitempty"`
@@ -127,6 +133,10 @@ func (m *CreateTenantRequest) Validate(formats strfmt.Registry) error {
res = append(res, err)
}
if err := m.validateLogSearchConfiguration(formats); err != nil {
res = append(res, err)
}
if err := m.validateName(formats); err != nil {
res = append(res, err)
}
@@ -139,6 +149,10 @@ func (m *CreateTenantRequest) Validate(formats strfmt.Registry) error {
res = append(res, err)
}
if err := m.validatePrometheusConfiguration(formats); err != nil {
res = append(res, err)
}
if err := m.validateTLS(formats); err != nil {
res = append(res, err)
}
@@ -221,6 +235,24 @@ func (m *CreateTenantRequest) validateImageRegistry(formats strfmt.Registry) err
return nil
}
func (m *CreateTenantRequest) validateLogSearchConfiguration(formats strfmt.Registry) error {
if swag.IsZero(m.LogSearchConfiguration) { // not required
return nil
}
if m.LogSearchConfiguration != nil {
if err := m.LogSearchConfiguration.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("logSearchConfiguration")
}
return err
}
}
return nil
}
func (m *CreateTenantRequest) validateName(formats strfmt.Registry) error {
if err := validate.Required("name", "body", m.Name); err != nil {
@@ -268,6 +300,24 @@ func (m *CreateTenantRequest) validatePools(formats strfmt.Registry) error {
return nil
}
func (m *CreateTenantRequest) validatePrometheusConfiguration(formats strfmt.Registry) error {
if swag.IsZero(m.PrometheusConfiguration) { // not required
return nil
}
if m.PrometheusConfiguration != nil {
if err := m.PrometheusConfiguration.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("prometheusConfiguration")
}
return err
}
}
return nil
}
func (m *CreateTenantRequest) validateTLS(formats strfmt.Registry) error {
if swag.IsZero(m.TLS) { // not required

View File

@@ -23,6 +23,8 @@ package models
// Editing this file might prove futile when you re-run the swagger generate command
import (
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
@@ -34,7 +36,7 @@ import (
type CreateTenantResponse struct {
// console
Console *CreateTenantResponseConsole `json:"console,omitempty"`
Console []*TenantResponseItem `json:"console"`
}
// Validate validates this create tenant response
@@ -57,13 +59,20 @@ func (m *CreateTenantResponse) validateConsole(formats strfmt.Registry) error {
return nil
}
if m.Console != nil {
if err := m.Console.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("console")
}
return err
for i := 0; i < len(m.Console); i++ {
if swag.IsZero(m.Console[i]) { // not required
continue
}
if m.Console[i] != nil {
if err := m.Console[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("console" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
@@ -86,38 +95,3 @@ func (m *CreateTenantResponse) UnmarshalBinary(b []byte) error {
*m = res
return nil
}
// CreateTenantResponseConsole create tenant response console
//
// swagger:model CreateTenantResponseConsole
type CreateTenantResponseConsole struct {
// access key
AccessKey string `json:"access_key,omitempty"`
// secret key
SecretKey string `json:"secret_key,omitempty"`
}
// Validate validates this create tenant response console
func (m *CreateTenantResponseConsole) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *CreateTenantResponseConsole) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *CreateTenantResponseConsole) UnmarshalBinary(b []byte) error {
var res CreateTenantResponseConsole
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -0,0 +1,66 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// CsiFormatErrorResponse csi format error response
//
// swagger:model csiFormatErrorResponse
type CsiFormatErrorResponse struct {
// drive
Drive string `json:"drive,omitempty"`
// error
Error string `json:"error,omitempty"`
// node
Node string `json:"node,omitempty"`
}
// Validate validates this csi format error response
func (m *CsiFormatErrorResponse) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *CsiFormatErrorResponse) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *CsiFormatErrorResponse) UnmarshalBinary(b []byte) error {
var res CsiFormatErrorResponse
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -49,6 +49,9 @@ type EncryptionConfiguration struct {
// image
Image string `json:"image,omitempty"`
// replicas
Replicas string `json:"replicas,omitempty"`
// server
Server *KeyPairConfiguration `json:"server,omitempty"`
@@ -77,6 +80,8 @@ func (m *EncryptionConfiguration) UnmarshalJSON(raw []byte) error {
Image string `json:"image,omitempty"`
Replicas string `json:"replicas,omitempty"`
Server *KeyPairConfiguration `json:"server,omitempty"`
Vault *VaultConfiguration `json:"vault,omitempty"`
@@ -95,6 +100,8 @@ func (m *EncryptionConfiguration) UnmarshalJSON(raw []byte) error {
m.Image = dataAO1.Image
m.Replicas = dataAO1.Replicas
m.Server = dataAO1.Server
m.Vault = dataAO1.Vault
@@ -122,6 +129,8 @@ func (m EncryptionConfiguration) MarshalJSON() ([]byte, error) {
Image string `json:"image,omitempty"`
Replicas string `json:"replicas,omitempty"`
Server *KeyPairConfiguration `json:"server,omitempty"`
Vault *VaultConfiguration `json:"vault,omitempty"`
@@ -137,6 +146,8 @@ func (m EncryptionConfiguration) MarshalJSON() ([]byte, error) {
dataAO1.Image = m.Image
dataAO1.Replicas = m.Replicas
dataAO1.Server = m.Server
dataAO1.Vault = m.Vault

View File

@@ -0,0 +1,66 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// ExpirationResponse expiration response
//
// swagger:model expirationResponse
type ExpirationResponse struct {
// date
Date string `json:"date,omitempty"`
// days
Days int64 `json:"days,omitempty"`
// delete marker
DeleteMarker bool `json:"delete_marker,omitempty"`
}
// Validate validates this expiration response
func (m *ExpirationResponse) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *ExpirationResponse) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *ExpirationResponse) UnmarshalBinary(b []byte) error {
var res ExpirationResponse
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -0,0 +1,99 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// FormatConfiguration format configuration
//
// swagger:model formatConfiguration
type FormatConfiguration struct {
// drives
// Required: true
// Min Length: 1
Drives []string `json:"drives"`
// force
// Required: true
Force *bool `json:"force"`
}
// Validate validates this format configuration
func (m *FormatConfiguration) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateDrives(formats); err != nil {
res = append(res, err)
}
if err := m.validateForce(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *FormatConfiguration) validateDrives(formats strfmt.Registry) error {
if err := validate.Required("drives", "body", m.Drives); err != nil {
return err
}
return nil
}
func (m *FormatConfiguration) validateForce(formats strfmt.Registry) error {
if err := validate.Required("force", "body", m.Force); err != nil {
return err
}
return nil
}
// MarshalBinary interface implementation
func (m *FormatConfiguration) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *FormatConfiguration) UnmarshalBinary(b []byte) error {
var res FormatConfiguration
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -0,0 +1,97 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// FormatDirectCSIDrivesResponse format direct c s i drives response
//
// swagger:model formatDirectCSIDrivesResponse
type FormatDirectCSIDrivesResponse struct {
// format issues list
FormatIssuesList []*CsiFormatErrorResponse `json:"formatIssuesList"`
}
// Validate validates this format direct c s i drives response
func (m *FormatDirectCSIDrivesResponse) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateFormatIssuesList(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *FormatDirectCSIDrivesResponse) validateFormatIssuesList(formats strfmt.Registry) error {
if swag.IsZero(m.FormatIssuesList) { // not required
return nil
}
for i := 0; i < len(m.FormatIssuesList); i++ {
if swag.IsZero(m.FormatIssuesList[i]) { // not required
continue
}
if m.FormatIssuesList[i] != nil {
if err := m.FormatIssuesList[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("formatIssuesList" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// MarshalBinary interface implementation
func (m *FormatDirectCSIDrivesResponse) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *FormatDirectCSIDrivesResponse) UnmarshalBinary(b []byte) error {
var res FormatDirectCSIDrivesResponse
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -23,6 +23,8 @@ package models
// Editing this file might prove futile when you re-run the swagger generate command
import (
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
@@ -37,6 +39,9 @@ type IdpConfiguration struct {
// active directory
ActiveDirectory *IdpConfigurationActiveDirectory `json:"active_directory,omitempty"`
// keys
Keys []*IdpConfigurationKeysItems0 `json:"keys"`
// oidc
Oidc *IdpConfigurationOidc `json:"oidc,omitempty"`
}
@@ -49,6 +54,10 @@ func (m *IdpConfiguration) Validate(formats strfmt.Registry) error {
res = append(res, err)
}
if err := m.validateKeys(formats); err != nil {
res = append(res, err)
}
if err := m.validateOidc(formats); err != nil {
res = append(res, err)
}
@@ -77,6 +86,31 @@ func (m *IdpConfiguration) validateActiveDirectory(formats strfmt.Registry) erro
return nil
}
func (m *IdpConfiguration) validateKeys(formats strfmt.Registry) error {
if swag.IsZero(m.Keys) { // not required
return nil
}
for i := 0; i < len(m.Keys); i++ {
if swag.IsZero(m.Keys[i]) { // not required
continue
}
if m.Keys[i] != nil {
if err := m.Keys[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("keys" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *IdpConfiguration) validateOidc(formats strfmt.Registry) error {
if swag.IsZero(m.Oidc) { // not required
@@ -213,6 +247,74 @@ func (m *IdpConfigurationActiveDirectory) UnmarshalBinary(b []byte) error {
return nil
}
// IdpConfigurationKeysItems0 idp configuration keys items0
//
// swagger:model IdpConfigurationKeysItems0
type IdpConfigurationKeysItems0 struct {
// access key
// Required: true
AccessKey *string `json:"access_key"`
// secret key
// Required: true
SecretKey *string `json:"secret_key"`
}
// Validate validates this idp configuration keys items0
func (m *IdpConfigurationKeysItems0) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateAccessKey(formats); err != nil {
res = append(res, err)
}
if err := m.validateSecretKey(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *IdpConfigurationKeysItems0) validateAccessKey(formats strfmt.Registry) error {
if err := validate.Required("access_key", "body", m.AccessKey); err != nil {
return err
}
return nil
}
func (m *IdpConfigurationKeysItems0) validateSecretKey(formats strfmt.Registry) error {
if err := validate.Required("secret_key", "body", m.SecretKey); err != nil {
return err
}
return nil
}
// MarshalBinary interface implementation
func (m *IdpConfigurationKeysItems0) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *IdpConfigurationKeysItems0) UnmarshalBinary(b []byte) error {
var res IdpConfigurationKeysItems0
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}
// IdpConfigurationOidc idp configuration oidc
//
// swagger:model IdpConfigurationOidc

63
models/lifecycle_tag.go Normal file
View File

@@ -0,0 +1,63 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// LifecycleTag lifecycle tag
//
// swagger:model lifecycleTag
type LifecycleTag struct {
// key
Key string `json:"key,omitempty"`
// value
Value string `json:"value,omitempty"`
}
// Validate validates this lifecycle tag
func (m *LifecycleTag) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *LifecycleTag) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *LifecycleTag) UnmarshalBinary(b []byte) error {
var res LifecycleTag
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -0,0 +1,97 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// ListPVCsResponse list p v cs response
//
// swagger:model listPVCsResponse
type ListPVCsResponse struct {
// pvcs
Pvcs []*PvcsListResponse `json:"pvcs"`
}
// Validate validates this list p v cs response
func (m *ListPVCsResponse) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validatePvcs(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *ListPVCsResponse) validatePvcs(formats strfmt.Registry) error {
if swag.IsZero(m.Pvcs) { // not required
return nil
}
for i := 0; i < len(m.Pvcs); i++ {
if swag.IsZero(m.Pvcs[i]) { // not required
continue
}
if m.Pvcs[i] != nil {
if err := m.Pvcs[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("pvcs" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// MarshalBinary interface implementation
func (m *ListPVCsResponse) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *ListPVCsResponse) UnmarshalBinary(b []byte) error {
var res ListPVCsResponse
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -0,0 +1,69 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// LogSearchConfiguration log search configuration
//
// swagger:model logSearchConfiguration
type LogSearchConfiguration struct {
// image
Image string `json:"image,omitempty"`
// postgres image
PostgresImage string `json:"postgres_image,omitempty"`
// storage class
StorageClass string `json:"storageClass,omitempty"`
// storage size
StorageSize *float64 `json:"storageSize,omitempty"`
}
// Validate validates this log search configuration
func (m *LogSearchConfiguration) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *LogSearchConfiguration) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *LogSearchConfiguration) UnmarshalBinary(b []byte) error {
var res LogSearchConfiguration
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -23,6 +23,7 @@ package models
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"strconv"
"github.com/go-openapi/errors"
@@ -41,19 +42,44 @@ type MultiBucketReplication struct {
// Min Length: 3
AccessKey *string `json:"accessKey"`
// bandwidth
Bandwidth int64 `json:"bandwidth,omitempty"`
// buckets relation
// Required: true
// Min Length: 1
BucketsRelation []*MultiBucketsRelation `json:"bucketsRelation"`
// health check period
HealthCheckPeriod int32 `json:"healthCheckPeriod,omitempty"`
// prefix
Prefix string `json:"prefix,omitempty"`
// region
Region string `json:"region,omitempty"`
// replicate delete markers
ReplicateDeleteMarkers bool `json:"replicateDeleteMarkers,omitempty"`
// replicate deletes
ReplicateDeletes bool `json:"replicateDeletes,omitempty"`
// replicate metadata
ReplicateMetadata bool `json:"replicateMetadata,omitempty"`
// secret key
// Required: true
// Min Length: 8
SecretKey *string `json:"secretKey"`
// sync mode
// Enum: [async sync]
SyncMode *string `json:"syncMode,omitempty"`
// tags
Tags string `json:"tags,omitempty"`
// target URL
// Required: true
TargetURL *string `json:"targetURL"`
@@ -75,6 +101,10 @@ func (m *MultiBucketReplication) Validate(formats strfmt.Registry) error {
res = append(res, err)
}
if err := m.validateSyncMode(formats); err != nil {
res = append(res, err)
}
if err := m.validateTargetURL(formats); err != nil {
res = append(res, err)
}
@@ -136,6 +166,49 @@ func (m *MultiBucketReplication) validateSecretKey(formats strfmt.Registry) erro
return nil
}
var multiBucketReplicationTypeSyncModePropEnum []interface{}
func init() {
var res []string
if err := json.Unmarshal([]byte(`["async","sync"]`), &res); err != nil {
panic(err)
}
for _, v := range res {
multiBucketReplicationTypeSyncModePropEnum = append(multiBucketReplicationTypeSyncModePropEnum, v)
}
}
const (
// MultiBucketReplicationSyncModeAsync captures enum value "async"
MultiBucketReplicationSyncModeAsync string = "async"
// MultiBucketReplicationSyncModeSync captures enum value "sync"
MultiBucketReplicationSyncModeSync string = "sync"
)
// prop value enum
func (m *MultiBucketReplication) validateSyncModeEnum(path, location string, value string) error {
if err := validate.EnumCase(path, location, value, multiBucketReplicationTypeSyncModePropEnum, true); err != nil {
return err
}
return nil
}
func (m *MultiBucketReplication) validateSyncMode(formats strfmt.Registry) error {
if swag.IsZero(m.SyncMode) { // not required
return nil
}
// value enum
if err := m.validateSyncModeEnum("syncMode", "body", *m.SyncMode); err != nil {
return err
}
return nil
}
func (m *MultiBucketReplication) validateTargetURL(formats strfmt.Registry) error {
if err := validate.Required("targetURL", "body", m.TargetURL); err != nil {

View File

@@ -0,0 +1,156 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// ObjectBucketLifecycle object bucket lifecycle
//
// swagger:model objectBucketLifecycle
type ObjectBucketLifecycle struct {
// expiration
Expiration *ExpirationResponse `json:"expiration,omitempty"`
// id
ID string `json:"id,omitempty"`
// prefix
Prefix string `json:"prefix,omitempty"`
// status
Status string `json:"status,omitempty"`
// tags
Tags []*LifecycleTag `json:"tags"`
// transition
Transition *TransitionResponse `json:"transition,omitempty"`
}
// Validate validates this object bucket lifecycle
func (m *ObjectBucketLifecycle) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateExpiration(formats); err != nil {
res = append(res, err)
}
if err := m.validateTags(formats); err != nil {
res = append(res, err)
}
if err := m.validateTransition(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *ObjectBucketLifecycle) validateExpiration(formats strfmt.Registry) error {
if swag.IsZero(m.Expiration) { // not required
return nil
}
if m.Expiration != nil {
if err := m.Expiration.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("expiration")
}
return err
}
}
return nil
}
func (m *ObjectBucketLifecycle) validateTags(formats strfmt.Registry) error {
if swag.IsZero(m.Tags) { // not required
return nil
}
for i := 0; i < len(m.Tags); i++ {
if swag.IsZero(m.Tags[i]) { // not required
continue
}
if m.Tags[i] != nil {
if err := m.Tags[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("tags" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *ObjectBucketLifecycle) validateTransition(formats strfmt.Registry) error {
if swag.IsZero(m.Transition) { // not required
return nil
}
if m.Transition != nil {
if err := m.Transition.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("transition")
}
return err
}
}
return nil
}
// MarshalBinary interface implementation
func (m *ObjectBucketLifecycle) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *ObjectBucketLifecycle) UnmarshalBinary(b []byte) error {
var res ObjectBucketLifecycle
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -0,0 +1,66 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// PrometheusConfiguration prometheus configuration
//
// swagger:model prometheusConfiguration
type PrometheusConfiguration struct {
// image
Image string `json:"image,omitempty"`
// storage class
StorageClass string `json:"storageClass,omitempty"`
// storage size
StorageSize *float64 `json:"storageSize,omitempty"`
}
// Validate validates this prometheus configuration
func (m *PrometheusConfiguration) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *PrometheusConfiguration) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *PrometheusConfiguration) UnmarshalBinary(b []byte) error {
var res PrometheusConfiguration
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -0,0 +1,78 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// PvcsListResponse pvcs list response
//
// swagger:model pvcsListResponse
type PvcsListResponse struct {
// age
Age string `json:"age,omitempty"`
// capacity
Capacity string `json:"capacity,omitempty"`
// name
Name string `json:"name,omitempty"`
// namespace
Namespace string `json:"namespace,omitempty"`
// status
Status string `json:"status,omitempty"`
// storage class
StorageClass string `json:"storageClass,omitempty"`
// volume
Volume string `json:"volume,omitempty"`
}
// Validate validates this pvcs list response
func (m *PvcsListResponse) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *PvcsListResponse) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *PvcsListResponse) UnmarshalBinary(b []byte) error {
var res PvcsListResponse
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -41,6 +41,12 @@ type RemoteBucket struct {
// Min Length: 3
AccessKey *string `json:"accessKey"`
// bandwidth
Bandwidth int64 `json:"bandwidth,omitempty"`
// health check period
HealthCheckPeriod int64 `json:"healthCheckPeriod,omitempty"`
// remote a r n
// Required: true
RemoteARN *string `json:"remoteARN"`
@@ -60,6 +66,9 @@ type RemoteBucket struct {
// status
Status string `json:"status,omitempty"`
// sync mode
SyncMode string `json:"syncMode,omitempty"`
// target bucket
TargetBucket string `json:"targetBucket,omitempty"`

View File

@@ -50,12 +50,27 @@ type Tenant struct {
// enable prometheus
EnablePrometheus bool `json:"enable_prometheus,omitempty"`
// encryption enabled
EncryptionEnabled bool `json:"encryptionEnabled,omitempty"`
// endpoints
Endpoints *TenantEndpoints `json:"endpoints,omitempty"`
// idp ad enabled
IdpAdEnabled bool `json:"idpAdEnabled,omitempty"`
// idp oic enabled
IdpOicEnabled bool `json:"idpOicEnabled,omitempty"`
// image
Image string `json:"image,omitempty"`
// log enabled
LogEnabled bool `json:"logEnabled,omitempty"`
// monitoring enabled
MonitoringEnabled bool `json:"monitoringEnabled,omitempty"`
// name
Name string `json:"name,omitempty"`

96
models/tenant_pod.go Normal file
View File

@@ -0,0 +1,96 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// TenantPod tenant pod
//
// swagger:model tenantPod
type TenantPod struct {
// name
// Required: true
Name *string `json:"name"`
// node
Node string `json:"node,omitempty"`
// pod IP
PodIP string `json:"podIP,omitempty"`
// restarts
Restarts int64 `json:"restarts,omitempty"`
// status
Status string `json:"status,omitempty"`
// time created
TimeCreated int64 `json:"timeCreated,omitempty"`
}
// Validate validates this tenant pod
func (m *TenantPod) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateName(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *TenantPod) validateName(formats strfmt.Registry) error {
if err := validate.Required("name", "body", m.Name); err != nil {
return err
}
return nil
}
// MarshalBinary interface implementation
func (m *TenantPod) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *TenantPod) UnmarshalBinary(b []byte) error {
var res TenantPod
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -0,0 +1,63 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// TenantResponseItem tenant response item
//
// swagger:model tenantResponseItem
type TenantResponseItem struct {
// access key
AccessKey string `json:"access_key,omitempty"`
// secret key
SecretKey string `json:"secret_key,omitempty"`
}
// Validate validates this tenant response item
func (m *TenantResponseItem) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *TenantResponseItem) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *TenantResponseItem) UnmarshalBinary(b []byte) error {
var res TenantResponseItem
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

60
models/tenant_y_a_m_l.go Normal file
View File

@@ -0,0 +1,60 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// TenantYAML tenant y a m l
//
// swagger:model tenantYAML
type TenantYAML struct {
// yaml
Yaml string `json:"yaml,omitempty"`
}
// Validate validates this tenant y a m l
func (m *TenantYAML) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *TenantYAML) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *TenantYAML) UnmarshalBinary(b []byte) error {
var res TenantYAML
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

198
models/tier.go Normal file
View File

@@ -0,0 +1,198 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// Tier tier
//
// swagger:model tier
type Tier struct {
// azure
Azure *TierAzure `json:"azure,omitempty"`
// gcs
Gcs *TierGcs `json:"gcs,omitempty"`
// s3
S3 *TierS3 `json:"s3,omitempty"`
// type
// Enum: [s3 gcs azure unsupported]
Type string `json:"type,omitempty"`
}
// Validate validates this tier
func (m *Tier) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateAzure(formats); err != nil {
res = append(res, err)
}
if err := m.validateGcs(formats); err != nil {
res = append(res, err)
}
if err := m.validateS3(formats); err != nil {
res = append(res, err)
}
if err := m.validateType(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *Tier) validateAzure(formats strfmt.Registry) error {
if swag.IsZero(m.Azure) { // not required
return nil
}
if m.Azure != nil {
if err := m.Azure.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("azure")
}
return err
}
}
return nil
}
func (m *Tier) validateGcs(formats strfmt.Registry) error {
if swag.IsZero(m.Gcs) { // not required
return nil
}
if m.Gcs != nil {
if err := m.Gcs.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("gcs")
}
return err
}
}
return nil
}
func (m *Tier) validateS3(formats strfmt.Registry) error {
if swag.IsZero(m.S3) { // not required
return nil
}
if m.S3 != nil {
if err := m.S3.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("s3")
}
return err
}
}
return nil
}
var tierTypeTypePropEnum []interface{}
func init() {
var res []string
if err := json.Unmarshal([]byte(`["s3","gcs","azure","unsupported"]`), &res); err != nil {
panic(err)
}
for _, v := range res {
tierTypeTypePropEnum = append(tierTypeTypePropEnum, v)
}
}
const (
// TierTypeS3 captures enum value "s3"
TierTypeS3 string = "s3"
// TierTypeGcs captures enum value "gcs"
TierTypeGcs string = "gcs"
// TierTypeAzure captures enum value "azure"
TierTypeAzure string = "azure"
// TierTypeUnsupported captures enum value "unsupported"
TierTypeUnsupported string = "unsupported"
)
// prop value enum
func (m *Tier) validateTypeEnum(path, location string, value string) error {
if err := validate.EnumCase(path, location, value, tierTypeTypePropEnum, true); err != nil {
return err
}
return nil
}
func (m *Tier) validateType(formats strfmt.Registry) error {
if swag.IsZero(m.Type) { // not required
return nil
}
// value enum
if err := m.validateTypeEnum("type", "body", m.Type); err != nil {
return err
}
return nil
}
// MarshalBinary interface implementation
func (m *Tier) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *Tier) UnmarshalBinary(b []byte) error {
var res Tier
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

78
models/tier_azure.go Normal file
View File

@@ -0,0 +1,78 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// TierAzure tier azure
//
// swagger:model tier_azure
type TierAzure struct {
// accountkey
Accountkey string `json:"accountkey,omitempty"`
// accountname
Accountname string `json:"accountname,omitempty"`
// bucket
Bucket string `json:"bucket,omitempty"`
// endpoint
Endpoint string `json:"endpoint,omitempty"`
// name
Name string `json:"name,omitempty"`
// prefix
Prefix string `json:"prefix,omitempty"`
// region
Region string `json:"region,omitempty"`
}
// Validate validates this tier azure
func (m *TierAzure) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *TierAzure) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *TierAzure) UnmarshalBinary(b []byte) error {
var res TierAzure
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -0,0 +1,66 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// TierCredentialsRequest tier credentials request
//
// swagger:model tierCredentialsRequest
type TierCredentialsRequest struct {
// access key
AccessKey string `json:"access_key,omitempty"`
// a base64 encoded value
Creds string `json:"creds,omitempty"`
// secret key
SecretKey string `json:"secret_key,omitempty"`
}
// Validate validates this tier credentials request
func (m *TierCredentialsRequest) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *TierCredentialsRequest) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *TierCredentialsRequest) UnmarshalBinary(b []byte) error {
var res TierCredentialsRequest
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

75
models/tier_gcs.go Normal file
View File

@@ -0,0 +1,75 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// TierGcs tier gcs
//
// swagger:model tier_gcs
type TierGcs struct {
// bucket
Bucket string `json:"bucket,omitempty"`
// creds
Creds string `json:"creds,omitempty"`
// endpoint
Endpoint string `json:"endpoint,omitempty"`
// name
Name string `json:"name,omitempty"`
// prefix
Prefix string `json:"prefix,omitempty"`
// region
Region string `json:"region,omitempty"`
}
// Validate validates this tier gcs
func (m *TierGcs) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *TierGcs) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *TierGcs) UnmarshalBinary(b []byte) error {
var res TierGcs
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -0,0 +1,97 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// TierListResponse tier list response
//
// swagger:model tierListResponse
type TierListResponse struct {
// items
Items []*Tier `json:"items"`
}
// Validate validates this tier list response
func (m *TierListResponse) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateItems(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *TierListResponse) validateItems(formats strfmt.Registry) error {
if swag.IsZero(m.Items) { // not required
return nil
}
for i := 0; i < len(m.Items); i++ {
if swag.IsZero(m.Items[i]) { // not required
continue
}
if m.Items[i] != nil {
if err := m.Items[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("items" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// MarshalBinary interface implementation
func (m *TierListResponse) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *TierListResponse) UnmarshalBinary(b []byte) error {
var res TierListResponse
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

81
models/tier_s3.go Normal file
View File

@@ -0,0 +1,81 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// TierS3 tier s3
//
// swagger:model tier_s3
type TierS3 struct {
// accesskey
Accesskey string `json:"accesskey,omitempty"`
// bucket
Bucket string `json:"bucket,omitempty"`
// endpoint
Endpoint string `json:"endpoint,omitempty"`
// name
Name string `json:"name,omitempty"`
// prefix
Prefix string `json:"prefix,omitempty"`
// region
Region string `json:"region,omitempty"`
// secretkey
Secretkey string `json:"secretkey,omitempty"`
// storageclass
Storageclass string `json:"storageclass,omitempty"`
}
// Validate validates this tier s3
func (m *TierS3) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *TierS3) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *TierS3) UnmarshalBinary(b []byte) error {
var res TierS3
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -0,0 +1,66 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// TransitionResponse transition response
//
// swagger:model transitionResponse
type TransitionResponse struct {
// date
Date string `json:"date,omitempty"`
// days
Days int64 `json:"days,omitempty"`
// storage class
StorageClass string `json:"storage_class,omitempty"`
}
// Validate validates this transition response
func (m *TransitionResponse) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *TransitionResponse) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *TransitionResponse) UnmarshalBinary(b []byte) error {
var res TransitionResponse
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -0,0 +1,63 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// UpdateBucketLifecycle update bucket lifecycle
//
// swagger:model updateBucketLifecycle
type UpdateBucketLifecycle struct {
// disable
Disable bool `json:"disable,omitempty"`
// tags
Tags string `json:"tags,omitempty"`
}
// Validate validates this update bucket lifecycle
func (m *UpdateBucketLifecycle) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *UpdateBucketLifecycle) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *UpdateBucketLifecycle) UnmarshalBinary(b []byte) error {
var res UpdateBucketLifecycle
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -39,7 +39,7 @@ type User struct {
MemberOf []string `json:"memberOf"`
// policy
Policy string `json:"policy,omitempty"`
Policy []string `json:"policy"`
// status
Status string `json:"status,omitempty"`

View File

@@ -35,6 +35,9 @@ import (
// swagger:model widget
type Widget struct {
// id
ID int32 `json:"id,omitempty"`
// options
Options *WidgetOptions `json:"options,omitempty"`

222
models/widget_details.go Normal file
View File

@@ -0,0 +1,222 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// WidgetDetails widget details
//
// swagger:model widgetDetails
type WidgetDetails struct {
// id
ID int32 `json:"id,omitempty"`
// options
Options *WidgetDetailsOptions `json:"options,omitempty"`
// targets
Targets []*ResultTarget `json:"targets"`
// title
Title string `json:"title,omitempty"`
// type
Type string `json:"type,omitempty"`
}
// Validate validates this widget details
func (m *WidgetDetails) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateOptions(formats); err != nil {
res = append(res, err)
}
if err := m.validateTargets(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *WidgetDetails) validateOptions(formats strfmt.Registry) error {
if swag.IsZero(m.Options) { // not required
return nil
}
if m.Options != nil {
if err := m.Options.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("options")
}
return err
}
}
return nil
}
func (m *WidgetDetails) validateTargets(formats strfmt.Registry) error {
if swag.IsZero(m.Targets) { // not required
return nil
}
for i := 0; i < len(m.Targets); i++ {
if swag.IsZero(m.Targets[i]) { // not required
continue
}
if m.Targets[i] != nil {
if err := m.Targets[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("targets" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// MarshalBinary interface implementation
func (m *WidgetDetails) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *WidgetDetails) UnmarshalBinary(b []byte) error {
var res WidgetDetails
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}
// WidgetDetailsOptions widget details options
//
// swagger:model WidgetDetailsOptions
type WidgetDetailsOptions struct {
// reduce options
ReduceOptions *WidgetDetailsOptionsReduceOptions `json:"reduceOptions,omitempty"`
}
// Validate validates this widget details options
func (m *WidgetDetailsOptions) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateReduceOptions(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *WidgetDetailsOptions) validateReduceOptions(formats strfmt.Registry) error {
if swag.IsZero(m.ReduceOptions) { // not required
return nil
}
if m.ReduceOptions != nil {
if err := m.ReduceOptions.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("options" + "." + "reduceOptions")
}
return err
}
}
return nil
}
// MarshalBinary interface implementation
func (m *WidgetDetailsOptions) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *WidgetDetailsOptions) UnmarshalBinary(b []byte) error {
var res WidgetDetailsOptions
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}
// WidgetDetailsOptionsReduceOptions widget details options reduce options
//
// swagger:model WidgetDetailsOptionsReduceOptions
type WidgetDetailsOptionsReduceOptions struct {
// calcs
Calcs []string `json:"calcs"`
}
// Validate validates this widget details options reduce options
func (m *WidgetDetailsOptionsReduceOptions) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *WidgetDetailsOptionsReduceOptions) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *WidgetDetailsOptionsReduceOptions) UnmarshalBinary(b []byte) error {
var res WidgetDetailsOptionsReduceOptions
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

10
node_modules/.yarn-integrity generated vendored Normal file
View File

@@ -0,0 +1,10 @@
{
"systemParams": "darwin-x64-88",
"modulesFolders": [],
"flags": [],
"linkedModules": [],
"topLevelPatterns": [],
"lockfileEntries": {},
"files": [],
"artifacts": {}
}

View File

@@ -22,29 +22,41 @@ import (
// endpoints definition
var (
configuration = "/settings"
users = "/users"
groups = "/groups"
iamPolicies = "/policies"
dashboard = "/dashboard"
profiling = "/profiling"
buckets = "/buckets"
bucketsDetail = "/buckets/:bucketName"
serviceAccounts = "/account"
changePassword = "/account/change-password"
tenants = "/tenants"
tenantsDetail = "/namespaces/:tenantNamespace/tenants/:tenantName"
remoteBuckets = "/remote-buckets"
replication = "/replication"
objectBrowser = "/object-browser/:bucket/*"
objectBrowserBucket = "/object-browser/:bucket"
mainObjectBrowser = "/object-browser"
license = "/license"
watch = "/watch"
heal = "/heal"
trace = "/trace"
logs = "/logs"
healthInfo = "/health-info"
configuration = "/settings"
users = "/users"
usersDetail = "/users/:userName"
groups = "/groups"
iamPolicies = "/policies"
policiesDetail = "/policies/:policyName"
dashboard = "/dashboard"
profiling = "/profiling"
buckets = "/buckets"
bucketsDetail = "/buckets/:bucketName"
bucketsDetailSummary = "/buckets/:bucketName/summary"
bucketsDetailEvents = "/buckets/:bucketName/events"
bucketsDetailReplication = "/buckets/:bucketName/replication"
bucketsDetailLifecycle = "/buckets/:bucketName/lifecycle"
bucketsDetailAccess = "/buckets/:bucketName/access"
bucketsDetailAccessPolicies = "/buckets/:bucketName/access/policies"
bucketsDetailAccessUsers = "/buckets/:bucketName/access/users"
serviceAccounts = "/account"
changePassword = "/account/change-password"
tenants = "/tenants"
tenantsDetail = "/namespaces/:tenantNamespace/tenants/:tenantName"
storage = "/storage"
storageVolumes = "/storage/volumes"
storageDrives = "/storage/drives"
remoteBuckets = "/remote-buckets"
replication = "/replication"
objectBrowser = "/object-browser/:bucket/*"
objectBrowserBucket = "/object-browser/:bucket"
mainObjectBrowser = "/object-browser"
license = "/license"
watch = "/watch"
heal = "/heal"
trace = "/trace"
logs = "/logs"
healthInfo = "/health-info"
)
type ConfigurationActionSet struct {
@@ -173,6 +185,11 @@ var tenantsActionSet = ConfigurationActionSet{
actions: iampolicy.NewActionSet(),
}
var storageActionSet = ConfigurationActionSet{
actionTypes: iampolicy.NewActionSet(),
actions: iampolicy.NewActionSet(),
}
var remoteBucketsActionSet = ConfigurationActionSet{
actionTypes: iampolicy.NewActionSet(
iampolicy.AllAdminActions,
@@ -266,34 +283,46 @@ var displayRules = map[string]func() bool{
// 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,
buckets: bucketsActionSet,
bucketsDetail: bucketsActionSet,
serviceAccounts: serviceAccountsActionSet,
changePassword: changePasswordActionSet,
remoteBuckets: remoteBucketsActionSet,
replication: replicationActionSet,
objectBrowser: objectBrowserActionSet,
mainObjectBrowser: objectBrowserActionSet,
objectBrowserBucket: objectBrowserActionSet,
license: licenseActionSet,
watch: watchActionSet,
heal: healActionSet,
trace: traceActionSet,
logs: logsActionSet,
healthInfo: healthInfoActionSet,
configuration: configurationActionSet,
users: usersActionSet,
usersDetail: usersActionSet,
groups: groupsActionSet,
iamPolicies: iamPoliciesActionSet,
policiesDetail: iamPoliciesActionSet,
dashboard: dashboardActionSet,
profiling: profilingActionSet,
buckets: bucketsActionSet,
bucketsDetail: bucketsActionSet,
bucketsDetailSummary: bucketsActionSet,
bucketsDetailEvents: bucketsActionSet,
bucketsDetailReplication: bucketsActionSet,
bucketsDetailLifecycle: bucketsActionSet,
bucketsDetailAccess: bucketsActionSet,
bucketsDetailAccessPolicies: bucketsActionSet,
bucketsDetailAccessUsers: bucketsActionSet,
serviceAccounts: serviceAccountsActionSet,
changePassword: changePasswordActionSet,
remoteBuckets: remoteBucketsActionSet,
replication: replicationActionSet,
objectBrowser: objectBrowserActionSet,
mainObjectBrowser: objectBrowserActionSet,
objectBrowserBucket: objectBrowserActionSet,
license: licenseActionSet,
watch: watchActionSet,
heal: healActionSet,
trace: traceActionSet,
logs: logsActionSet,
healthInfo: healthInfoActionSet,
}
// operatorRules contains the mapping between endpoints and ActionSets for operator only mode
var operatorRules = map[string]ConfigurationActionSet{
tenants: tenantsActionSet,
tenantsDetail: tenantsActionSet,
license: licenseActionSet,
tenants: tenantsActionSet,
tenantsDetail: tenantsActionSet,
storage: storageActionSet,
storageDrives: storageActionSet,
storageVolumes: storageActionSet,
license: licenseActionSet,
}
// operatorOnly ENV variable

View File

@@ -63,7 +63,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
"admin:ListUserPolicies",
},
},
want: 6,
want: 7,
},
{
name: "all admin endpoints",
@@ -72,7 +72,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
"admin:*",
},
},
want: 19,
want: 21,
},
{
name: "all s3 endpoints",
@@ -81,7 +81,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
"s3:*",
},
},
want: 7,
want: 14,
},
{
name: "all admin and s3 endpoints",
@@ -91,7 +91,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
"s3:*",
},
},
want: 21,
want: 30,
},
{
name: "Console User - default endpoints",
@@ -116,7 +116,7 @@ func TestOperatorOnlyEndpoints(t *testing.T) {
"admin:*",
},
},
want: 3,
want: 6,
},
{
name: "Operator Only - all s3 endpoints",
@@ -125,7 +125,7 @@ func TestOperatorOnlyEndpoints(t *testing.T) {
"s3:*",
},
},
want: 3,
want: 6,
},
{
name: "Operator Only - all admin and s3 endpoints",
@@ -135,14 +135,14 @@ func TestOperatorOnlyEndpoints(t *testing.T) {
"s3:*",
},
},
want: 3,
want: 6,
},
{
name: "Operator Only - default endpoints",
args: args{
[]string{},
},
want: 3,
want: 6,
},
}
@@ -177,7 +177,7 @@ func TestGetActionsStringFromPolicy(t *testing.T) {
args: args{
policy: &iampolicy.AdminDiagnostics,
},
want: 7,
want: 8,
},
}
for _, tt := range tests {

BIN
portal-ui/build/amazon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@@ -1,25 +1,25 @@
{
"files": {
"main.css": "/static/css/main.a19f3d53.chunk.css",
"main.js": "/static/js/main.a8ae7284.chunk.js",
"main.js.map": "/static/js/main.a8ae7284.chunk.js.map",
"main.js": "/static/js/main.f0e70269.chunk.js",
"main.js.map": "/static/js/main.f0e70269.chunk.js.map",
"runtime-main.js": "/static/js/runtime-main.f48e99e5.js",
"runtime-main.js.map": "/static/js/runtime-main.f48e99e5.js.map",
"static/css/2.f324abd6.chunk.css": "/static/css/2.f324abd6.chunk.css",
"static/js/2.26e254ca.chunk.js": "/static/js/2.26e254ca.chunk.js",
"static/js/2.26e254ca.chunk.js.map": "/static/js/2.26e254ca.chunk.js.map",
"static/css/2.76b14b73.chunk.css": "/static/css/2.76b14b73.chunk.css",
"static/js/2.59d83018.chunk.js": "/static/js/2.59d83018.chunk.js",
"static/js/2.59d83018.chunk.js.map": "/static/js/2.59d83018.chunk.js.map",
"index.html": "/index.html",
"static/css/2.f324abd6.chunk.css.map": "/static/css/2.f324abd6.chunk.css.map",
"static/css/2.76b14b73.chunk.css.map": "/static/css/2.76b14b73.chunk.css.map",
"static/css/main.a19f3d53.chunk.css.map": "/static/css/main.a19f3d53.chunk.css.map",
"static/js/2.26e254ca.chunk.js.LICENSE.txt": "/static/js/2.26e254ca.chunk.js.LICENSE.txt",
"static/js/2.59d83018.chunk.js.LICENSE.txt": "/static/js/2.59d83018.chunk.js.LICENSE.txt",
"static/media/minio_console_logo.0837460e.svg": "/static/media/minio_console_logo.0837460e.svg",
"static/media/minio_operator_logo.1312b7c9.svg": "/static/media/minio_operator_logo.1312b7c9.svg"
},
"entrypoints": [
"static/js/runtime-main.f48e99e5.js",
"static/css/2.f324abd6.chunk.css",
"static/js/2.26e254ca.chunk.js",
"static/css/2.76b14b73.chunk.css",
"static/js/2.59d83018.chunk.js",
"static/css/main.a19f3d53.chunk.css",
"static/js/main.a8ae7284.chunk.js"
"static/js/main.f0e70269.chunk.js"
]
}

BIN
portal-ui/build/azure.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

BIN
portal-ui/build/gcs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="MinIO Console"/><link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700;900&display=swap" rel="stylesheet"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="manifest" href="/manifest.json"/><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#3a4e54"/><title>MinIO Console</title><link href="/static/css/2.f324abd6.chunk.css" rel="stylesheet"><link href="/static/css/main.a19f3d53.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,l,i=r[0],a=r[1],p=r[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var a=t[i];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var i=this["webpackJsonpportal-ui"]=this["webpackJsonpportal-ui"]||[],a=i.push.bind(i);i.push=r,i=i.slice();for(var p=0;p<i.length;p++)r(i[p]);var f=a;t()}([])</script><script src="/static/js/2.26e254ca.chunk.js"></script><script src="/static/js/main.a8ae7284.chunk.js"></script></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="MinIO Console"/><link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700;900&display=swap" rel="stylesheet"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="manifest" href="/manifest.json"/><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#3a4e54"/><title>MinIO Console</title><link href="/static/css/2.76b14b73.chunk.css" rel="stylesheet"><link href="/static/css/main.a19f3d53.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,l,i=r[0],a=r[1],p=r[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var a=t[i];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var i=this["webpackJsonpportal-ui"]=this["webpackJsonpportal-ui"]||[],a=i.push.bind(i);i.push=r,i=i.slice();for(var p=0;p<i.length;p++)r(i[p]);var f=a;t()}([])</script><script src="/static/js/2.59d83018.chunk.js"></script><script src="/static/js/main.f0e70269.chunk.js"></script></body></html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

@@ -1,2 +1,2 @@
.ReactVirtualized__Table__headerRow{font-weight:700;text-transform:uppercase}.ReactVirtualized__Table__headerRow,.ReactVirtualized__Table__row{display:flex;flex-direction:row;align-items:center}.ReactVirtualized__Table__headerTruncatedText{display:inline-block;max-width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.ReactVirtualized__Table__headerColumn,.ReactVirtualized__Table__rowColumn{margin-right:10px;min-width:0}.ReactVirtualized__Table__rowColumn{text-overflow:ellipsis;white-space:nowrap}.ReactVirtualized__Table__headerColumn:first-of-type,.ReactVirtualized__Table__rowColumn:first-of-type{margin-left:10px}.ReactVirtualized__Table__sortableHeaderColumn{cursor:pointer}.ReactVirtualized__Table__sortableHeaderIconContainer{display:flex;align-items:center}.ReactVirtualized__Table__sortableHeaderIcon{flex:0 0 24px;height:1em;width:1em;fill:currentColor}.react-grid-layout{position:relative;transition:height .2s ease}.react-grid-item{transition:all .2s ease;transition-property:left,top}.react-grid-item img{pointer-events:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.react-grid-item.cssTransforms{transition-property:transform}.react-grid-item.resizing{z-index:1;will-change:width,height}.react-grid-item.react-draggable-dragging{transition:none;z-index:3;will-change:transform}.react-grid-item.dropping{visibility:hidden}.react-grid-item.react-grid-placeholder{background:red;opacity:.2;transition-duration:.1s;z-index:2;-webkit-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.react-grid-item>.react-resizable-handle{position:absolute;width:20px;height:20px}.react-grid-item>.react-resizable-handle:after{content:"";position:absolute;right:3px;bottom:3px;width:5px;height:5px;border-right:2px solid rgba(0,0,0,.4);border-bottom:2px solid rgba(0,0,0,.4)}.react-resizable-hide>.react-resizable-handle{display:none}.react-grid-item>.react-resizable-handle.react-resizable-handle-sw{bottom:0;left:0;cursor:sw-resize;transform:rotate(90deg)}.react-grid-item>.react-resizable-handle.react-resizable-handle-se{bottom:0;right:0;cursor:se-resize}.react-grid-item>.react-resizable-handle.react-resizable-handle-nw{top:0;left:0;cursor:nw-resize;transform:rotate(180deg)}.react-grid-item>.react-resizable-handle.react-resizable-handle-ne{top:0;right:0;cursor:ne-resize;transform:rotate(270deg)}.react-grid-item>.react-resizable-handle.react-resizable-handle-e,.react-grid-item>.react-resizable-handle.react-resizable-handle-w{top:50%;margin-top:-10px;cursor:ew-resize}.react-grid-item>.react-resizable-handle.react-resizable-handle-w{left:0;transform:rotate(135deg)}.react-grid-item>.react-resizable-handle.react-resizable-handle-e{right:0;transform:rotate(315deg)}.react-grid-item>.react-resizable-handle.react-resizable-handle-n,.react-grid-item>.react-resizable-handle.react-resizable-handle-s{left:50%;margin-left:-10px;cursor:ns-resize}.react-grid-item>.react-resizable-handle.react-resizable-handle-n{top:0;transform:rotate(225deg)}.react-grid-item>.react-resizable-handle.react-resizable-handle-s{bottom:0;transform:rotate(45deg)}.react-resizable{position:relative}.react-resizable-handle{position:absolute;width:20px;height:20px;background-repeat:no-repeat;background-origin:content-box;box-sizing:border-box;background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOiNmZmZmZmYwMCIgd2lkdGg9IjYiIGhlaWdodD0iNiI+PHBhdGggZD0iTTYgNkgwVjQuMmg0LjJWMEg2djZ6IiBvcGFjaXR5PSIuMzAyIi8+PC9zdmc+");background-position:100% 100%;padding:0 3px 3px 0}.react-resizable-handle-sw{bottom:0;left:0;cursor:sw-resize;transform:rotate(90deg)}.react-resizable-handle-se{bottom:0;right:0;cursor:se-resize}.react-resizable-handle-nw{top:0;left:0;cursor:nw-resize;transform:rotate(180deg)}.react-resizable-handle-ne{top:0;right:0;cursor:ne-resize;transform:rotate(270deg)}.react-resizable-handle-e,.react-resizable-handle-w{top:50%;margin-top:-10px;cursor:ew-resize}.react-resizable-handle-w{left:0;transform:rotate(135deg)}.react-resizable-handle-e{right:0;transform:rotate(315deg)}.react-resizable-handle-n,.react-resizable-handle-s{left:50%;margin-left:-10px;cursor:ns-resize}.react-resizable-handle-n{top:0;transform:rotate(225deg)}.react-resizable-handle-s{bottom:0;transform:rotate(45deg)}
/*# sourceMappingURL=2.f324abd6.chunk.css.map */
/*# sourceMappingURL=2.76b14b73.chunk.css.map */

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -29,7 +29,7 @@
"codemirror": "^5.52.2",
"history": "^4.10.1",
"local-storage-fallback": "^4.1.1",
"lodash": "^4.17.19",
"lodash": "^4.17.21",
"moment": "^2.29.1",
"react": "17.0.1",
"react-app-rewire-hot-loader": "^2.0.1",
@@ -78,7 +78,7 @@
},
"proxy": "http://localhost:9090/",
"devDependencies": {
"prettier": "2.2.1",
"prettier": "2.3.0",
"typescript": "^4.1.3"
}
}

BIN
portal-ui/public/amazon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

BIN
portal-ui/public/azure.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

BIN
portal-ui/public/gcs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

@@ -14,6 +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 { ILabelKeyPair } from "../screens/Console/Tenants/types";
export interface ITenantsObject {
tenants: ITenant[];
}
@@ -54,6 +56,8 @@ export interface ITenantCreator {
enable_tls: boolean;
access_key: string;
secret_key: string;
access_keys: string[];
secret_keys: string[];
image: string;
console_image: string;
expose_minio: boolean;
@@ -66,6 +70,9 @@ export interface ITenantCreator {
idp?: IIDPConfiguration;
annotations?: Object;
image_registry?: ImageRegistry;
logSearchConfiguration?: LogSearchConfiguration;
prometheusConfiguration?: PrometheusConfiguration;
affinity?: AffinityConfiguration;
}
export interface ImageRegistry {
@@ -91,7 +98,8 @@ export interface ITenantUsage {
}
export interface IAffinityModel {
podAntiAffinity: IPodAntiAffinityModel;
podAntiAffinity?: IPodAntiAffinityModel;
nodeAffinity?: INodeAffinityModel;
}
export interface IPodAntiAffinityModel {
@@ -107,6 +115,18 @@ export interface IPodAffinityTermLabelSelector {
matchExpressions: IMatchExpressionItem[];
}
export interface INodeAffinityModel {
requiredDuringSchedulingIgnoredDuringExecution: INodeAffinityTerms;
}
export interface INodeAffinityTerms {
nodeSelectorTerms: INodeAffinityLabelsSelector[];
}
export interface INodeAffinityLabelsSelector {
matchExpressions: object[];
}
export interface IMatchExpressionItem {
key: string;
operator: string;
@@ -339,3 +359,22 @@ export interface IErasureCodeCalc {
defaultEC: string;
storageFactors: IStorageFactors[];
}
export interface LogSearchConfiguration {
storageClass?: string;
storageSize?: number;
image: string;
postgres_image: string;
}
export interface PrometheusConfiguration {
storageClass?: string;
storageSize?: number;
image: string;
}
export interface AffinityConfiguration {
affinityType: "default" | "nodeSelector" | "none";
nodeSelectorLabels?: ILabelKeyPair[];
withPodAntiAffinity?: boolean;
}

View File

@@ -422,9 +422,19 @@ export const generatePoolName = (pools: IPool[]) => {
};
// seconds / minutes /hours / Days / Years calculator
export const niceDays = (secondsValue: string) => {
export const niceDays = (secondsValue: string, timeVariant: string = "s") => {
let seconds = parseFloat(secondsValue);
switch (timeVariant) {
case "ns":
seconds = Math.floor(seconds * 0.000000001);
break;
case "ms":
seconds = Math.floor(seconds * 0.001);
break;
default:
}
const days = Math.floor(seconds / (3600 * 24));
seconds -= days * 3600 * 24;

View File

@@ -0,0 +1,29 @@
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React from "react";
import { SvgIcon } from "@material-ui/core";
const SyncIcon = () => {
return (
<SvgIcon>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z"></path>
</svg>
</SvgIcon>
);
};
export default SyncIcon;

View File

@@ -101,18 +101,13 @@ const Account = ({
const [filter, setFilter] = useState<string>("");
const [addScreenOpen, setAddScreenOpen] = useState<boolean>(false);
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
const [selectedServiceAccount, setSelectedServiceAccount] = useState<
string | null
>(null);
const [selectedServiceAccount, setSelectedServiceAccount] =
useState<string | null>(null);
const [showNewCredentials, setShowNewCredentials] = useState<boolean>(false);
const [
newServiceAccount,
setNewServiceAccount,
] = useState<NewServiceAccount | null>(null);
const [
changePasswordModalOpen,
setChangePasswordModalOpen,
] = useState<boolean>(false);
const [newServiceAccount, setNewServiceAccount] =
useState<NewServiceAccount | null>(null);
const [changePasswordModalOpen, setChangePasswordModalOpen] =
useState<boolean>(false);
useEffect(() => {
fetchRecords();

View File

@@ -64,9 +64,8 @@ const AddServiceAccount = ({
}: IAddServiceAccountProps) => {
const [addSending, setAddSending] = useState<boolean>(false);
const [policyDefinition, setPolicyDefinition] = useState<string>("");
const [isRestrictedByPolicy, setIsRestrictedByPolicy] = useState<boolean>(
false
);
const [isRestrictedByPolicy, setIsRestrictedByPolicy] =
useState<boolean>(false);
useEffect(() => {
if (addSending) {

View File

@@ -0,0 +1,166 @@
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useEffect, useState, Fragment } from "react";
import { connect } from "react-redux";
import { AppState } from "../../../../store";
import { setErrorSnackMessage } from "../../../../actions";
import Tabs from "@material-ui/core/Tabs";
import Tab from "@material-ui/core/Tab";
import { Paper } from "@material-ui/core";
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
import { TabPanel } from "../../../shared/tabs";
import { Policy } from "../../Policies/types";
import { ISessionResponse } from "../../types";
import { User } from "../../Users/types";
import api from "../../../../common/api";
import history from "../../../../history";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
const styles = (theme: Theme) => createStyles({});
const mapState = (state: AppState) => ({
session: state.console.session,
});
const connector = connect(mapState, { setErrorSnackMessage });
function a11yProps(index: any) {
return {
id: `simple-tab-${index}`,
"aria-controls": `simple-tabpanel-${index}`,
};
}
interface IAccessDetailsProps {
session: ISessionResponse;
setErrorSnackMessage: typeof setErrorSnackMessage;
classes: any;
match: any;
}
const AccessDetails = ({
classes,
match,
setErrorSnackMessage,
session,
}: IAccessDetailsProps) => {
const [curTab, setCurTab] = useState<number>(0);
const [loadingPolicies, setLoadingPolicies] = useState<boolean>(true);
const [bucketPolicy, setBucketPolicy] = useState<Policy[]>([]);
const [loadingUsers, setLoadingUsers] = useState<boolean>(true);
const [bucketUsers, setBucketUsers] = useState<User[]>([]);
const bucketName = match.params["bucketName"];
const usersEnabled = session.pages?.indexOf("/users") > -1;
const PolicyActions = [
{
type: "view",
onClick: (policy: any) => {
history.push(`/policies/${policy.name}`);
},
},
];
const userTableActions = [
{
type: "view",
onClick: (user: any) => {
history.push(`/users/${user}`);
},
},
];
useEffect(() => {
if (loadingUsers && usersEnabled) {
api
.invoke("GET", `/api/v1/bucket-users/${bucketName}`)
.then((res: any) => {
setBucketUsers(res);
setLoadingUsers(false);
})
.catch((err: any) => {
setErrorSnackMessage(err);
setLoadingUsers(false);
});
}
}, [loadingUsers, setErrorSnackMessage, bucketName, usersEnabled]);
useEffect(() => {
if (loadingPolicies) {
api
.invoke("GET", `/api/v1/bucket-policy/${bucketName}`)
.then((res: any) => {
setBucketPolicy(res.policies);
setLoadingPolicies(false);
})
.catch((err: any) => {
setErrorSnackMessage(err);
setLoadingPolicies(false);
});
}
}, [loadingPolicies, setErrorSnackMessage, bucketName]);
return (
<Fragment>
<br />
<Paper>
<Tabs
value={curTab}
onChange={(e: React.ChangeEvent<{}>, newValue: number) => {
setCurTab(newValue);
}}
indicatorColor="primary"
textColor="primary"
aria-label="cluster-tabs"
variant="scrollable"
scrollButtons="auto"
>
<Tab label="Policies" {...a11yProps(0)} />
{usersEnabled && <Tab label="Users" {...a11yProps(1)} />}
</Tabs>
<TabPanel index={0} value={curTab}>
<TableWrapper
noBackground={true}
itemActions={PolicyActions}
columns={[{ label: "Name", elementKey: "name" }]}
isLoading={loadingPolicies}
records={bucketPolicy}
entityName="Policies"
idField="name"
/>
</TabPanel>
{usersEnabled && (
<TabPanel index={1} value={curTab}>
<TableWrapper
noBackground={true}
itemActions={userTableActions}
columns={[{ label: "User", elementKey: "accessKey" }]}
isLoading={loadingUsers}
records={bucketUsers}
entityName="Users"
idField="accessKey"
/>
</TabPanel>
)}
</Paper>
</Fragment>
);
};
export default withStyles(styles)(connector(AccessDetails));

View File

@@ -0,0 +1,469 @@
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useState, useEffect, Fragment } from "react";
import get from "lodash/get";
import { connect } from "react-redux";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
import { Button, LinearProgress } from "@material-ui/core";
import Grid from "@material-ui/core/Grid";
import { modalBasic } from "../../Common/FormComponents/common/styleLibrary";
import { setModalErrorSnackMessage } from "../../../../actions";
import {
ITierResponse,
ITierElement,
} from "../../Configurations/TiersConfiguration/types";
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
import api from "../../../../common/api";
import DateSelector from "../../Common/FormComponents/DateSelector/DateSelector";
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
import QueryMultiSelector from "../../Common/FormComponents/QueryMultiSelector/QueryMultiSelector";
import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector";
interface IReplicationModal {
open: boolean;
closeModalAndRefresh: (refresh: boolean) => any;
classes: any;
bucketName: string;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
interface ITiersDropDown {
label: string;
value: string;
}
const styles = (theme: Theme) =>
createStyles({
minTableHeader: {
color: "#393939",
"& tr": {
"& th": {
fontWeight: "bold",
},
},
},
buttonContainer: {
textAlign: "right",
},
...modalBasic,
});
const AddLifecycleModal = ({
open,
closeModalAndRefresh,
classes,
bucketName,
setModalErrorSnackMessage,
}: IReplicationModal) => {
const [loadingTiers, setLoadingTiers] = useState<boolean>(true);
const [tiersList, setTiersList] = useState<ITiersDropDown[]>([]);
const [addLoading, setAddLoading] = useState(false);
const [prefix, setPrefix] = useState("");
const [tags, setTags] = useState<string>("");
const [storageClass, setStorageClass] = useState("");
const [NCTransitionSC, setNCTransitionSC] = useState("");
const [expiredObjectDM, setExpiredObjectDM] = useState<boolean>(false);
const [NCExpirationDays, setNCExpirationDays] = useState<string>("0");
const [NCTransitionDays, setNCTransitionDays] = useState<string>("0");
const [ilmType, setIlmType] = useState<string>("expiry");
const [expiryType, setExpiryType] = useState<string>("date");
const [expiryDays, setExpiryDays] = useState<string>("0");
const [expiryDate, setExpiryDate] = useState<string>("");
const [transitionDays, setTransitionDays] = useState<string>("0");
const [transitionDate, setTransitionDate] = useState<string>("");
const [transitionType, setTransitionType] = useState<string>("date");
const [isFormValid, setIsFormValid] = useState<boolean>(false);
useEffect(() => {
if (loadingTiers) {
api
.invoke("GET", `/api/v1/admin/tiers`)
.then((res: ITierResponse) => {
const tiersList: ITierElement[] | null = get(res, "items", []);
if (tiersList !== null && tiersList.length >= 1) {
const objList = tiersList.map((tier: ITierElement) => {
const tierType = tier.type;
const value = get(tier, `${tierType}.name`, "");
return { label: value, value: value };
});
setTiersList(objList);
if (objList.length > 0) {
setStorageClass(objList[0].value);
}
}
setLoadingTiers(false);
})
.catch((err) => {
setLoadingTiers(false);
});
}
}, [loadingTiers]);
useEffect(() => {
let valid = true;
if (ilmType === "expiry") {
if (expiryType === "date" && expiryDate === "") {
valid = false;
}
if (expiryType === "days" && parseInt(expiryDays) < 1) {
valid = false;
}
} else {
if (transitionType === "date" && transitionDate === "") {
valid = false;
}
if (transitionType === "days" && parseInt(transitionDays) < 1) {
valid = false;
}
if (storageClass === "") {
valid = false;
}
}
setIsFormValid(valid);
}, [
ilmType,
expiryType,
expiryDate,
expiryDays,
transitionType,
transitionDate,
transitionDays,
storageClass,
]);
const addRecord = () => {
let rules = {};
if (ilmType === "expiry") {
let expiry = {};
if (expiryType === "date") {
expiry = {
expiry_date: `${expiryDate}T23:59:59Z`,
};
} else {
expiry = {
expiry_days: parseInt(expiryDays),
};
}
rules = {
...expiry,
noncurrentversion_expiration_days: parseInt(NCExpirationDays),
};
} else {
let transition = {};
if (transitionType === "date") {
transition = {
transition_date: `${transitionDate}T23:59:59Z`,
};
} else {
transition = {
transition_days: parseInt(transitionDays),
};
}
rules = {
...transition,
noncurrentversion_transition_days: parseInt(NCTransitionDays),
noncurrentversion_transition_storage_class: NCTransitionSC,
storage_class: storageClass,
};
}
const lifecycleInsert = {
prefix,
tags,
expired_object_delete_marker: expiredObjectDM,
...rules,
};
api
.invoke(
"POST",
`/api/v1/buckets/${bucketName}/lifecycle`,
lifecycleInsert
)
.then(() => {
setAddLoading(false);
closeModalAndRefresh(true);
})
.catch((err) => {
setAddLoading(false);
setModalErrorSnackMessage(err);
});
};
return (
<ModalWrapper
modalOpen={open}
onClose={() => {
closeModalAndRefresh(false);
}}
title="Add Lifecycle Rule"
>
{loadingTiers && (
<Grid container className={classes.loadingBox}>
<Grid item xs={12}>
<LinearProgress />
</Grid>
</Grid>
)}
{!loadingTiers && (
<form
noValidate
autoComplete="off"
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
setAddLoading(true);
addRecord();
}}
>
<Grid container>
<Grid item xs={12} className={classes.formScrollable}>
<h3>Lifecycle Configuration</h3>
<Grid item xs={12}>
<RadioGroupSelector
currentSelection={ilmType}
id="quota_type"
name="quota_type"
label="ILM Rule"
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
setIlmType(e.target.value as string);
}}
selectorOptions={[
{ value: "expiry", label: "Expiry" },
{ value: "transition", label: "Transition" },
]}
/>
</Grid>
{ilmType === "expiry" ? (
<Fragment>
<Grid item xs={12}>
<RadioGroupSelector
currentSelection={expiryType}
id="expiryType"
name="expiryType"
label="Expiry Type"
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
setExpiryType(e.target.value as string);
}}
selectorOptions={[
{ value: "date", label: "Date" },
{ value: "days", label: "Days" },
]}
/>
</Grid>
<Grid item xs={12}>
{expiryType === "date" ? (
<DateSelector
id="expiry_date"
label="Expiry Date"
value={expiryDate}
borderBottom={true}
onDateChange={(date: string, isValid: boolean) => {
if (isValid) {
setExpiryDate(date);
}
}}
/>
) : (
<InputBoxWrapper
type="number"
id="expiry_days"
name="expiry_days"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setExpiryDays(e.target.value);
}}
label="Expiry Days"
value={expiryDays}
min="0"
/>
)}
</Grid>
<Grid item xs={12}>
<InputBoxWrapper
type="number"
id="noncurrentversion_expiration_days"
name="noncurrentversion_expiration_days"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setNCExpirationDays(e.target.value);
}}
label="Non-current Expiration Days"
value={NCExpirationDays}
min="0"
/>
</Grid>
</Fragment>
) : (
<Fragment>
<Grid item xs={12}>
<RadioGroupSelector
currentSelection={transitionType}
id="transitionType"
name="transitionType"
label="Transition Type"
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
setTransitionType(e.target.value as string);
}}
selectorOptions={[
{ value: "date", label: "Date" },
{ value: "days", label: "Days" },
]}
/>
</Grid>
<Grid item xs={12}>
{transitionType === "date" ? (
<DateSelector
id="transition_date"
label="Transition Date"
value={transitionDate}
borderBottom={true}
onDateChange={(date: string, isValid: boolean) => {
if (isValid) {
setTransitionDate(date);
}
}}
/>
) : (
<InputBoxWrapper
type="number"
id="transition_days"
name="transition_days"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setTransitionDays(e.target.value);
}}
label="Transition Days"
value={transitionDays}
min="0"
/>
)}
</Grid>
<Grid item xs={12}>
<InputBoxWrapper
type="number"
id="noncurrentversion_transition_days"
name="noncurrentversion_transition_days"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setNCTransitionDays(e.target.value);
}}
label="Non-current Transition Days"
value={NCTransitionDays}
min="0"
/>
</Grid>
<Grid item xs={12}>
<InputBoxWrapper
id="noncurrentversion_t_SC"
name="noncurrentversion_t_SC"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setNCTransitionSC(e.target.value);
}}
placeholder="Set Non-current Version Transition Storage Class"
label="Non-current Version Transition Storage Class"
value={NCTransitionSC}
/>
</Grid>
<Grid item xs={12}>
<SelectWrapper
label="Storage Class"
id="storage_class"
name="storage_class"
value={storageClass}
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
setStorageClass(e.target.value as string);
}}
options={tiersList}
/>
</Grid>
</Fragment>
)}
<h3>File Configuration</h3>
<Grid item xs={12}>
<InputBoxWrapper
id="prefix"
name="prefix"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setPrefix(e.target.value);
}}
label="Prefix"
value={prefix}
/>
</Grid>
<Grid item xs={12}>
<QueryMultiSelector
name="tags"
label="Tags"
elements={""}
onChange={(vl: string) => {
setTags(vl);
}}
keyPlaceholder="Tag Key"
valuePlaceholder="Tag Value"
withBorder
/>
</Grid>
<Grid item xs={12}>
<FormSwitchWrapper
value="expired_delete_marker"
id="expired_delete_marker"
name="expired_delete_marker"
checked={expiredObjectDM}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setExpiredObjectDM(event.target.checked);
}}
label={"Expired Object Delete Marker"}
indicatorLabels={["On", "Off"]}
/>
</Grid>
</Grid>
<Grid item xs={12} className={classes.buttonContainer}>
<Button
type="submit"
variant="contained"
color="primary"
disabled={addLoading || !isFormValid}
>
Save
</Button>
</Grid>
{addLoading && (
<Grid item xs={12}>
<LinearProgress />
</Grid>
)}
</Grid>
</form>
)}
</ModalWrapper>
);
};
const connector = connect(null, {
setModalErrorSnackMessage,
});
export default withStyles(styles)(connector(AddLifecycleModal));

View File

@@ -0,0 +1,401 @@
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useState } from "react";
import { connect } from "react-redux";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
import { Button, LinearProgress } from "@material-ui/core";
import get from "lodash/get";
import Grid from "@material-ui/core/Grid";
import { modalBasic } from "../../Common/FormComponents/common/styleLibrary";
import { BulkReplicationResponse } from "../types";
import { setModalErrorSnackMessage } from "../../../../actions";
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
import api from "../../../../common/api";
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import { getBytes, k8sfactorForDropdown } from "../../../../common/utils";
import QueryMultiSelector from "../../Common/FormComponents/QueryMultiSelector/QueryMultiSelector";
interface IReplicationModal {
open: boolean;
closeModalAndRefresh: () => any;
classes: any;
bucketName: string;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
const styles = (theme: Theme) =>
createStyles({
minTableHeader: {
color: "#393939",
"& tr": {
"& th": {
fontWeight: "bold",
},
},
},
buttonContainer: {
textAlign: "right",
},
multiContainer: {
display: "flex",
alignItems: "center" as const,
justifyContent: "flex-start" as const,
},
...modalBasic,
});
const AddReplicationModal = ({
open,
closeModalAndRefresh,
classes,
bucketName,
setModalErrorSnackMessage,
}: IReplicationModal) => {
const [addLoading, setAddLoading] = useState<boolean>(false);
const [accessKey, setAccessKey] = useState<string>("");
const [secretKey, setSecretKey] = useState<string>("");
const [targetURL, setTargetURL] = useState<string>("");
const [targetStorageClass, setTargetStorageClass] = useState<string>("");
const [prefix, setPrefix] = useState<string>("");
const [targetBucket, setTargetBucket] = useState<string>("");
const [region, setRegion] = useState<string>("");
const [useTLS, setUseTLS] = useState<boolean>(true);
const [repDeleteMarker, setRepDeleteMarker] = useState<boolean>(true);
const [repDelete, setRepDelete] = useState<boolean>(true);
const [repMetadata, setRepMetadata] = useState<boolean>(true);
const [tags, setTags] = useState<string>("");
const [replicationMode, setReplicationMode] = useState<string>("async");
const [bandwidthScalar, setBandwidthScalar] = useState<string>("100");
const [bandwidthUnit, setBandwidthUnit] = useState<string>("Gi");
const [healthCheck, setHealthCheck] = useState<string>("60");
const addRecord = () => {
const replicate = [
{
originBucket: bucketName,
destinationBucket: targetBucket,
},
];
const hc = parseInt(healthCheck);
const endURL = `${useTLS ? "https://" : "http://"}${targetURL}`;
const remoteBucketsInfo = {
accessKey: accessKey,
secretKey: secretKey,
targetURL: endURL,
region: region,
bucketsRelation: replicate,
syncMode: replicationMode,
bandwidth:
replicationMode === "async"
? parseInt(getBytes(bandwidthScalar, bandwidthUnit, true))
: 0,
healthCheckPeriod: hc,
prefix: prefix,
tags: tags,
replicateDeleteMarkers: repDeleteMarker,
replicateDeletes: repDelete,
replicateMetadata: repMetadata,
};
api
.invoke("POST", "/api/v1/buckets-replication", remoteBucketsInfo)
.then((response: BulkReplicationResponse) => {
setAddLoading(false);
const states = get(response, "replicationState", []);
if (states.length > 0) {
const itemVal = states[0];
setAddLoading(false);
if (itemVal.errorString && itemVal.errorString !== "") {
setModalErrorSnackMessage(itemVal.errorString);
return;
}
closeModalAndRefresh();
return;
}
setModalErrorSnackMessage("No changes applied");
})
.catch((err) => {
setAddLoading(false);
setModalErrorSnackMessage(err);
});
};
return (
<ModalWrapper
modalOpen={open}
onClose={() => {
closeModalAndRefresh();
}}
title="Set Bucket Replication"
>
<form
noValidate
autoComplete="off"
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
setAddLoading(true);
addRecord();
}}
>
<Grid container>
<Grid item xs={12} className={classes.formScrollable}>
<Grid item xs={12}>
<InputBoxWrapper
id="targetURL"
name="targetURL"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setTargetURL(e.target.value);
}}
placeholder="play.min.io"
label="Target URL"
value={targetURL}
/>
</Grid>
<Grid item xs={12}>
<FormSwitchWrapper
checked={useTLS}
id="useTLS"
name="useTLS"
label="Use TLS"
onChange={(e) => {
setUseTLS(e.target.checked);
}}
value="yes"
/>
</Grid>
<Grid item xs={12}>
<InputBoxWrapper
id="accessKey"
name="accessKey"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setAccessKey(e.target.value);
}}
label="Access Key"
value={accessKey}
/>
</Grid>
<Grid item xs={12}>
<InputBoxWrapper
id="secretKey"
name="secretKey"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setSecretKey(e.target.value);
}}
label="Secret Key"
value={secretKey}
/>
</Grid>
<Grid item xs={12}>
<InputBoxWrapper
id="targetBucket"
name="targetBucket"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setTargetBucket(e.target.value);
}}
label="Target Bucket"
value={targetBucket}
/>
</Grid>
<Grid item xs={12}>
<InputBoxWrapper
id="region"
name="region"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setRegion(e.target.value);
}}
label="Region"
value={region}
/>
</Grid>
<Grid item xs={12}>
<SelectWrapper
id="replication_mode"
name="replication_mode"
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
setReplicationMode(e.target.value as string);
}}
label="Replication Mode"
value={replicationMode}
options={[
{ label: "Asynchronous", value: "async" },
{ label: "Synchronous", value: "sync" },
]}
/>
</Grid>
{replicationMode === "async" && (
<Grid item xs={12}>
<div className={classes.multiContainer}>
<div>
<InputBoxWrapper
type="number"
id="bandwidth_scalar"
name="bandwidth_scalar"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setBandwidthScalar(e.target.value as string);
}}
label="Bandwidth"
value={bandwidthScalar}
min="0"
/>
</div>
<div className={classes.sizeFactorContainer}>
<SelectWrapper
label={"Unit"}
id="bandwidth_unit"
name="bandwidth_unit"
value={bandwidthUnit}
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
setBandwidthUnit(e.target.value as string);
}}
options={k8sfactorForDropdown()}
/>
</div>
</div>
</Grid>
)}
<Grid item xs={12}>
<InputBoxWrapper
id="healthCheck"
name="healthCheck"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setHealthCheck(e.target.value as string);
}}
label="Health Check Duration"
value={healthCheck}
/>
</Grid>
<h3>Object Filters</h3>
<Grid item xs={12}>
<InputBoxWrapper
id="prefix"
name="prefix"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setPrefix(e.target.value);
}}
placeholder="prefix"
label="Prefix"
value={prefix}
/>
</Grid>
<Grid item xs={12}>
<QueryMultiSelector
name="tags"
label="Tags"
elements={""}
onChange={(vl: string) => {
setTags(vl);
}}
keyPlaceholder="Tag Key"
valuePlaceholder="Tag Value"
withBorder
/>
</Grid>
<h3>Storage Configuration</h3>
<Grid item xs={12}>
<InputBoxWrapper
id="storageClass"
name="storageClass"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setTargetStorageClass(e.target.value);
}}
placeholder="STANDARD_IA,REDUCED_REDUNDANCY etc"
label="Storage Class"
value={targetStorageClass}
/>
</Grid>
<h3>Replication Options</h3>
<Grid item xs={12}>
<FormSwitchWrapper
checked={repDeleteMarker}
id="deleteMarker"
name="deleteMarker"
label="Delete Marker"
onChange={(e) => {
console.log(e);
console.log(e.target.checked);
setRepDeleteMarker(e.target.checked);
}}
value={repDeleteMarker}
description={"Replicate soft deletes"}
/>
</Grid>
<Grid item xs={12}>
<FormSwitchWrapper
checked={repDelete}
id="repDelete"
name="repDelete"
label="Deletes"
onChange={(e) => {
setRepDelete(e.target.checked);
}}
value={repDelete}
description={"Replicate versioned deletes"}
/>
</Grid>
{/*TODO: This will be enabled later on when we update the dependency on mc*/}
{/*<Grid item xs={12}>*/}
{/* <FormSwitchWrapper*/}
{/* checked={repMetadata}*/}
{/* id="repMetadata"*/}
{/* name="repMeta"*/}
{/* label="Replicate Metadata"*/}
{/* onChange={(e) => {*/}
{/* setRepMetadata(e.target.checked);*/}
{/* }}*/}
{/* value={repMetadata}*/}
{/* description={"Replicate object metadata"}*/}
{/* />*/}
{/*</Grid>*/}
</Grid>
<Grid item xs={12} className={classes.buttonContainer}>
<Button
type="submit"
variant="contained"
color="primary"
disabled={addLoading}
>
Save
</Button>
</Grid>
{addLoading && (
<Grid item xs={12}>
<LinearProgress />
</Grid>
)}
</Grid>
</form>
</ModalWrapper>
);
};
const connector = connect(null, {
setModalErrorSnackMessage,
});
export default withStyles(styles)(connector(AddReplicationModal));

View File

@@ -0,0 +1,335 @@
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useEffect, useState } from "react";
import { Redirect, Route, Router, Switch } from "react-router-dom";
import { connect } from "react-redux";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
import Grid from "@material-ui/core/Grid";
import Tabs from "@material-ui/core/Tabs";
import Tab from "@material-ui/core/Tab";
import api from "../../../../common/api";
import { HasPermissionResponse } from "../types";
import {
actionsTray,
buttonsStyles,
containerForHeader,
hrClass,
searchField,
} from "../../Common/FormComponents/common/styleLibrary";
import { setErrorSnackMessage } from "../../../../actions";
import { setBucketDetailsTab } from "../actions";
import { AppState } from "../../../../store";
import { ISessionResponse } from "../../types";
import PageHeader from "../../Common/PageHeader/PageHeader";
import AccessDetailsPanel from "./AccessDetailsPanel";
import BucketSummaryPanel from "./BucketSummaryPanel";
import BucketEventsPanel from "./BucketEventsPanel";
import BucketReplicationPanel from "./BucketReplicationPanel";
import BucketLifecyclePanel from "./BucketLifecyclePanel";
const styles = (theme: Theme) =>
createStyles({
seeMore: {
marginTop: theme.spacing(3),
},
paper: {
display: "flex",
overflow: "auto",
flexDirection: "column",
},
addSideBar: {
width: "320px",
padding: "20px",
},
tableToolbar: {
paddingLeft: theme.spacing(2),
paddingRight: theme.spacing(0),
},
minTableHeader: {
color: "#393939",
"& tr": {
"& th": {
fontWeight: "bold",
},
},
},
noRecords: {
lineHeight: "24px",
textAlign: "center",
padding: "20px",
},
gridWrapper: {
width: 320,
},
gridContainer: {
display: "grid",
gridTemplateColumns: "auto auto",
gridGap: 8,
justifyContent: "flex-start",
alignItems: "center",
"& div:not(.MuiCircularProgress-root)": {
display: "flex",
alignItems: "center",
},
"& div:nth-child(odd)": {
justifyContent: "flex-end",
fontWeight: 700,
},
"& div:nth-child(2n)": {
minWidth: 150,
},
},
masterActions: {
width: "25%",
minWidth: "120px",
"& div": {
margin: "5px 0px",
},
},
headerContainer: {
display: "flex",
justifyContent: "space-between",
},
capitalizeFirst: {
textTransform: "capitalize",
},
doubleElement: {
display: "flex",
justifyContent: "space-between",
},
encCheckbox: {
margin: 0,
padding: 0,
},
tabPan: {
marginTop: "5px",
},
fixedHeight: {
height: 165,
minWidth: 247,
padding: "25px 28px",
"& svg": {
maxHeight: 18,
},
},
routerContainer: {
marginTop: 5,
},
titleCol: {
fontWeight: "bold",
},
...searchField,
...actionsTray,
actionsTray: {
...actionsTray.actionsTray,
padding: "15px 0 0",
},
...hrClass,
...buttonsStyles,
...containerForHeader(theme.spacing(4)),
});
interface IBucketDetailsProps {
classes: any;
match: any;
history: any;
session: ISessionResponse;
selectedTab: string;
setErrorSnackMessage: typeof setErrorSnackMessage;
setBucketDetailsTab: typeof setBucketDetailsTab;
}
function a11yProps(index: any) {
return {
id: `simple-tab-${index}`,
"aria-controls": `simple-tabpanel-${index}`,
};
}
const BucketDetails = ({
classes,
match,
history,
session,
selectedTab,
setErrorSnackMessage,
setBucketDetailsTab,
}: IBucketDetailsProps) => {
const [loadingPerms, setLoadingPerms] = useState<boolean>(true);
const [canGetReplication, setCanGetReplication] = useState<boolean>(false);
const bucketName = match.params["bucketName"];
useEffect(() => {
let matchURL = match.params ? match.params["0"] : "summary";
if (!matchURL) {
matchURL = "";
}
const splitMatch = matchURL.split("/");
if (selectedTab !== splitMatch[0]) {
setBucketDetailsTab(splitMatch[0]);
}
}, [match, bucketName, setBucketDetailsTab, selectedTab]);
// check the permissions for creating bucket
useEffect(() => {
if (loadingPerms) {
api
.invoke("POST", `/api/v1/has-permission`, {
actions: [
{
id: "GetReplicationConfiguration",
action: "s3:GetReplicationConfiguration",
bucket_name: bucketName,
},
],
})
.then((res: HasPermissionResponse) => {
setLoadingPerms(false);
if (!res.permissions) {
return;
}
const actions = res.permissions ? res.permissions : [];
let canGetReplicationVal = actions.find(
(s) => s.id === "GetReplicationConfiguration"
);
if (canGetReplicationVal && canGetReplicationVal.can) {
setCanGetReplication(true);
} else {
setCanGetReplication(false);
}
setLoadingPerms(false);
})
.catch((err: any) => {
setLoadingPerms(false);
setErrorSnackMessage(err);
});
}
}, [bucketName, loadingPerms, setErrorSnackMessage]);
const changeRoute = (newTab: string) => {
let mainRoute = `/buckets/${bucketName}`;
switch (newTab) {
case "events":
mainRoute += "/events";
break;
case "replication":
mainRoute += "/replication";
break;
case "lifecycle":
mainRoute += "/lifecycle";
break;
case "access":
mainRoute += "/access";
break;
default:
mainRoute += "/summary";
}
setBucketDetailsTab(newTab);
history.push(mainRoute);
};
return (
<Fragment>
<PageHeader label={`Bucket > ${match.params["bucketName"]}`} />
<Grid container className={classes.container}>
<Grid item xs={12}>
<Tabs
value={selectedTab !== "" ? selectedTab : "summary"}
onChange={(e: React.ChangeEvent<{}>, newValue: string) => {
changeRoute(newValue);
}}
indicatorColor="primary"
textColor="primary"
aria-label="cluster-tabs"
variant="scrollable"
scrollButtons="auto"
>
<Tab value="summary" label="Summary" {...a11yProps(0)} />
<Tab value="events" label="Events" {...a11yProps(1)} />
<Tab
value="replication"
label="Replication"
{...a11yProps(2)}
disabled={!canGetReplication}
/>
<Tab value="lifecycle" label="Lifecycle" {...a11yProps(3)} />
<Tab value="access" label="Access" {...a11yProps(4)} />
</Tabs>
</Grid>
<Grid item xs={12}>
<Grid item xs={12} className={classes.routerContainer}>
<Router history={history}>
<Switch>
<Route
path="/buckets/:bucketName/summary"
component={BucketSummaryPanel}
/>
<Route
path="/buckets/:bucketName/events"
component={BucketEventsPanel}
/>
<Route
path="/buckets/:bucketName/replication"
component={BucketReplicationPanel}
/>
<Route
path="/buckets/:bucketName/lifecycle"
component={BucketLifecyclePanel}
/>
<Route
path="/buckets/:bucketName/access"
component={AccessDetailsPanel}
/>
<Route
path="/buckets/:bucketName/access"
component={AccessDetailsPanel}
/>
<Route
path="/buckets/:bucketName"
component={() => (
<Redirect to={`/buckets/${bucketName}/summary`} />
)}
/>
</Switch>
</Router>
</Grid>
</Grid>
</Grid>
</Fragment>
);
};
const mapState = (state: AppState) => ({
session: state.console.session,
selectedTab: state.buckets.bucketDetails.selectedTab,
});
const connector = connect(mapState, {
setErrorSnackMessage,
setBucketDetailsTab,
});
export default withStyles(styles)(connector(BucketDetails));

View File

@@ -0,0 +1,191 @@
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useState, useEffect, Fragment } from "react";
import { connect } from "react-redux";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
import { Button, TextField } from "@material-ui/core";
import get from "lodash/get";
import Grid from "@material-ui/core/Grid";
import InputAdornment from "@material-ui/core/InputAdornment";
import SearchIcon from "@material-ui/icons/Search";
import { CreateIcon } from "../../../../icons";
import { BucketEvent, BucketEventList } from "../types";
import { setErrorSnackMessage } from "../../../../actions";
import { AppState } from "../../../../store";
import {
actionsTray,
searchField,
} from "../../Common/FormComponents/common/styleLibrary";
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
import api from "../../../../common/api";
import DeleteEvent from "./DeleteEvent";
import AddEvent from "./AddEvent";
const styles = (theme: Theme) =>
createStyles({
...searchField,
...actionsTray,
actionsTray: {
...actionsTray.actionsTray,
padding: "15px 0 0",
},
});
interface IBucketEventsProps {
classes: any;
match: any;
setErrorSnackMessage: typeof setErrorSnackMessage;
}
const BucketEventsPanel = ({
classes,
match,
setErrorSnackMessage,
}: IBucketEventsProps) => {
const [addEventScreenOpen, setAddEventScreenOpen] = useState<boolean>(false);
const [loadingEvents, setLoadingEvents] = useState<boolean>(true);
const [records, setRecords] = useState<BucketEvent[]>([]);
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
const [selectedEvent, setSelectedEvent] = useState<BucketEvent | null>(null);
const [filter, setFilter] = useState<string>("");
const bucketName = match.params["bucketName"];
useEffect(() => {
if (loadingEvents) {
api
.invoke("GET", `/api/v1/buckets/${bucketName}/events`)
.then((res: BucketEventList) => {
const events = get(res, "events", []);
setLoadingEvents(false);
setRecords(events || []);
})
.catch((err: any) => {
setLoadingEvents(false);
setErrorSnackMessage(err);
});
}
}, [loadingEvents, setErrorSnackMessage, bucketName]);
const eventsDisplay = (events: string[]) => {
return <Fragment>{events.join(", ")}</Fragment>;
};
const confirmDeleteEvent = (evnt: BucketEvent) => {
setDeleteOpen(true);
setSelectedEvent(evnt);
};
const closeAddEventAndRefresh = () => {
setAddEventScreenOpen(false);
setLoadingEvents(true);
};
const closeDeleteModalAndRefresh = (refresh: boolean) => {
setDeleteOpen(false);
if (refresh) {
setLoadingEvents(true);
}
};
const tableActions = [{ type: "delete", onClick: confirmDeleteEvent }];
return (
<Fragment>
{deleteOpen && (
<DeleteEvent
deleteOpen={deleteOpen}
selectedBucket={bucketName}
bucketEvent={selectedEvent}
closeDeleteModalAndRefresh={closeDeleteModalAndRefresh}
/>
)}
{addEventScreenOpen && (
<AddEvent
open={addEventScreenOpen}
selectedBucket={bucketName}
closeModalAndRefresh={closeAddEventAndRefresh}
/>
)}
<Grid container>
<Grid item xs={12} className={classes.actionsTray}>
<TextField
placeholder="Filter"
className={classes.searchField}
id="search-resource"
label=""
onChange={(event) => {
setFilter(event.target.value);
}}
InputProps={{
disableUnderline: true,
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
/>
<Button
variant="contained"
color="primary"
startIcon={<CreateIcon />}
size="medium"
onClick={() => {
setAddEventScreenOpen(true);
}}
>
Subscribe to Event
</Button>
</Grid>
<Grid item xs={12}>
<br />
</Grid>
<Grid item xs={12}>
<TableWrapper
itemActions={tableActions}
columns={[
{ label: "SQS", elementKey: "arn" },
{
label: "Events",
elementKey: "events",
renderFunction: eventsDisplay,
},
{ label: "Prefix", elementKey: "prefix" },
{ label: "Suffix", elementKey: "suffix" },
]}
isLoading={loadingEvents}
records={records}
entityName="Events"
idField="id"
/>
</Grid>
</Grid>
</Fragment>
);
};
const mapState = (state: AppState) => ({
session: state.console.session,
});
const connector = connect(mapState, {
setErrorSnackMessage,
});
export default withStyles(styles)(connector(BucketEventsPanel));

View File

@@ -0,0 +1,233 @@
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useState, useEffect } from "react";
import { connect } from "react-redux";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
import { Button, TextField } from "@material-ui/core";
import get from "lodash/get";
import * as reactMoment from "react-moment";
import Grid from "@material-ui/core/Grid";
import InputAdornment from "@material-ui/core/InputAdornment";
import SearchIcon from "@material-ui/icons/Search";
import { LifeCycleItem } from "../types";
import { CreateIcon } from "../../../../icons";
import {
actionsTray,
searchField,
} from "../../Common/FormComponents/common/styleLibrary";
import { setErrorSnackMessage } from "../../../../actions";
import api from "../../../../common/api";
import EditLifecycleConfiguration from "./EditLifecycleConfiguration";
import AddLifecycleModal from "./AddLifecycleModal";
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
import { AppState } from "../../../../store";
const styles = (theme: Theme) =>
createStyles({
...searchField,
...actionsTray,
actionsTray: {
...actionsTray.actionsTray,
padding: "15px 0 0",
},
});
interface IBucketLifecyclePanelProps {
classes: any;
match: any;
setErrorSnackMessage: typeof setErrorSnackMessage;
}
const BucketLifecyclePanel = ({
classes,
match,
setErrorSnackMessage,
}: IBucketLifecyclePanelProps) => {
const [loadingLifecycle, setLoadingLifecycle] = useState<boolean>(true);
const [lifecycleRecords, setLifecycleRecords] = useState<LifeCycleItem[]>([]);
const [addLifecycleOpen, setAddLifecycleOpen] = useState<boolean>(false);
const [editLifecycleOpen, setEditLifecycleOpen] = useState<boolean>(false);
const bucketName = match.params["bucketName"];
useEffect(() => {
if (loadingLifecycle) {
api
.invoke("GET", `/api/v1/buckets/${bucketName}/lifecycle`)
.then((res: any) => {
const records = get(res, "lifecycle", []);
setLifecycleRecords(records || []);
setLoadingLifecycle(false);
})
.catch((err) => {
console.error(err);
setLoadingLifecycle(false);
});
}
}, [loadingLifecycle, setLoadingLifecycle, bucketName]);
const closeEditLCAndRefresh = (refresh: boolean) => {
setEditLifecycleOpen(false);
if (refresh) {
setLoadingLifecycle(true);
}
};
const closeAddLCAndRefresh = (refresh: boolean) => {
setAddLifecycleOpen(false);
if (refresh) {
setLoadingLifecycle(true);
}
};
const expirationRender = (expiration: any) => {
if (expiration.days) {
return `${expiration.days} day${expiration.days > 1 ? "s" : ""}`;
}
if (expiration.date === "0001-01-01T00:00:00Z") {
return "";
}
return <reactMoment.default>{expiration.date}</reactMoment.default>;
};
const transitionRender = (transition: any) => {
if (transition.days) {
return `${transition.days} day${transition.days > 1 ? "s" : ""}`;
}
if (transition.date === "0001-01-01T00:00:00Z") {
return "";
}
return <reactMoment.default>{transition.date}</reactMoment.default>;
};
const renderStorageClass = (objectST: any) => {
const stClass = get(objectST, "transition.storage_class", "");
return stClass;
};
const lifecycleColumns = [
{ label: "ID", elementKey: "id" },
{
label: "Prefix",
elementKey: "prefix",
},
{
label: "Status",
elementKey: "status",
},
{
label: "Expiration",
elementKey: "expiration",
renderFunction: expirationRender,
},
{
label: "Transition",
elementKey: "transition",
renderFunction: transitionRender,
},
{
label: "Storage Class",
elementKey: "storage_class",
renderFunction: renderStorageClass,
renderFullObject: true,
},
];
return (
<Fragment>
{editLifecycleOpen && (
<EditLifecycleConfiguration
open={editLifecycleOpen}
closeModalAndRefresh={closeEditLCAndRefresh}
selectedBucket={bucketName}
lifecycle={{
id: "",
}}
/>
)}
{addLifecycleOpen && (
<AddLifecycleModal
open={addLifecycleOpen}
bucketName={bucketName}
closeModalAndRefresh={closeAddLCAndRefresh}
/>
)}
<Grid container>
<Grid item xs={12} className={classes.actionsTray}>
<TextField
placeholder="Filter"
className={classes.searchField}
id="search-resource"
label=""
onChange={(event) => {
// setFilter(event.target.value);
}}
InputProps={{
disableUnderline: true,
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
/>
<Button
variant="contained"
color="primary"
startIcon={<CreateIcon />}
size="medium"
onClick={() => {
setAddLifecycleOpen(true);
}}
>
Add Lifecycle Rule
</Button>
</Grid>
<Grid item xs={12}>
<br />
</Grid>
<Grid item xs={12}>
<TableWrapper
itemActions={[]}
columns={lifecycleColumns}
isLoading={loadingLifecycle}
records={lifecycleRecords}
entityName="Lifecycle"
customEmptyMessage="There are no Lifecycle rules yet"
idField="id"
/>
</Grid>
</Grid>
</Fragment>
);
};
const mapState = (state: AppState) => ({
session: state.console.session,
});
const connector = connect(mapState, {
setErrorSnackMessage,
});
export default withStyles(styles)(connector(BucketLifecyclePanel));

View File

@@ -0,0 +1,295 @@
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useEffect, useState, Fragment } from "react";
import { connect } from "react-redux";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
import { Button, IconButton, TextField } from "@material-ui/core";
import Grid from "@material-ui/core/Grid";
import InputAdornment from "@material-ui/core/InputAdornment";
import SearchIcon from "@material-ui/icons/Search";
import { CreateIcon } from "../../../../icons";
import { setErrorSnackMessage } from "../../../../actions";
import {
actionsTray,
searchField,
} from "../../Common/FormComponents/common/styleLibrary";
import {
BucketReplication,
BucketReplicationDestination,
BucketReplicationRule,
HasPermissionResponse,
} from "../types";
import api from "../../../../common/api";
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
import AddReplicationModal from "./AddReplicationModal";
import DeleteReplicationRule from "./DeleteReplicationRule";
import { AppState } from "../../../../store";
import RefreshIcon from "@material-ui/icons/Refresh";
interface IBucketReplicationProps {
classes: any;
match: any;
setErrorSnackMessage: typeof setErrorSnackMessage;
}
const styles = (theme: Theme) =>
createStyles({
...searchField,
...actionsTray,
actionsTray: {
...actionsTray.actionsTray,
padding: "15px 0 0",
},
});
const BucketReplicationPanel = ({
classes,
match,
setErrorSnackMessage,
}: IBucketReplicationProps) => {
const [canPutReplication, setCanPutReplication] = useState<boolean>(false);
const [loadingReplication, setLoadingReplication] = useState<boolean>(true);
const [replicationRules, setReplicationRules] = useState<
BucketReplicationRule[]
>([]);
const [loadingPerms, setLoadingPerms] = useState<boolean>(true);
const [canGetReplication, setCanGetReplication] = useState<boolean>(false);
const [deleteReplicationModal, setDeleteReplicationModal] =
useState<boolean>(false);
const [openSetReplication, setOpenSetReplication] = useState<boolean>(false);
const [selectedRRule, setSelectedRRule] = useState<string>("");
const bucketName = match.params["bucketName"];
useEffect(() => {
if (loadingPerms) {
api
.invoke("POST", `/api/v1/has-permission`, {
actions: [
{
id: "PutReplicationConfiguration",
action: "s3:PutReplicationConfiguration",
bucket_name: bucketName,
},
{
id: "GetReplicationConfiguration",
action: "s3:GetReplicationConfiguration",
bucket_name: bucketName,
},
],
})
.then((res: HasPermissionResponse) => {
setLoadingPerms(false);
if (!res.permissions) {
return;
}
const actions = res.permissions ? res.permissions : [];
let userCanPutReplication = actions.find(
(s) => s.id === "PutReplicationConfiguration"
);
if (userCanPutReplication && userCanPutReplication.can) {
setCanPutReplication(true);
} else {
setCanPutReplication(false);
}
let canGetReplication = actions.find(
(s) => s.id === "GetReplicationConfiguration"
);
if (canGetReplication && canGetReplication.can) {
setCanGetReplication(true);
} else {
setCanGetReplication(false);
}
setLoadingPerms(false);
})
.catch((err: any) => {
setLoadingPerms(false);
setErrorSnackMessage(err);
});
}
}, [bucketName, loadingPerms, setErrorSnackMessage]);
useEffect(() => {
if (loadingReplication) {
api
.invoke("GET", `/api/v1/buckets/${bucketName}/replication`)
.then((res: BucketReplication) => {
const r = res.rules ? res.rules : [];
setReplicationRules(r);
setLoadingReplication(false);
})
.catch((err: any) => {
setErrorSnackMessage(err);
setLoadingReplication(false);
});
}
}, [loadingReplication, setErrorSnackMessage, bucketName]);
if (!canGetReplication) {
return null;
}
const closeAddReplication = () => {
setOpenReplicationOpen(false);
setLoadingReplication(true);
};
const setOpenReplicationOpen = (open = false) => {
setOpenSetReplication(open);
};
const closeReplicationModalDelete = (refresh: boolean) => {
setDeleteReplicationModal(false);
if (refresh) {
setLoadingReplication(true);
}
};
const confirmDeleteReplication = (replication: BucketReplicationRule) => {
setSelectedRRule(replication.id);
setDeleteReplicationModal(true);
};
const ruleDestDisplay = (events: BucketReplicationDestination) => {
return <Fragment>{events.bucket.replace("arn:aws:s3:::", "")}</Fragment>;
};
const tagDisplay = (events: BucketReplicationRule) => {
return <Fragment>{events && events.tags !== "" ? "Yes" : "No"}</Fragment>;
};
const replicationTableActions: any = [
{
type: "delete",
onClick: confirmDeleteReplication,
disableButtonFunction: () => replicationRules.length > 1,
},
];
return (
<Fragment>
{openSetReplication && (
<AddReplicationModal
closeModalAndRefresh={closeAddReplication}
open={openSetReplication}
bucketName={bucketName}
/>
)}
{deleteReplicationModal && (
<DeleteReplicationRule
deleteOpen={deleteReplicationModal}
selectedBucket={bucketName}
closeDeleteModalAndRefresh={closeReplicationModalDelete}
ruleToDelete={selectedRRule}
/>
)}
<Grid container>
<Grid item xs={12} className={classes.actionsTray}>
<TextField
placeholder="Filter"
className={classes.searchField}
id="search-resource"
label=""
onChange={(event) => {
// setFilter(event.target.value);
}}
InputProps={{
disableUnderline: true,
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
/>
<IconButton
color="primary"
aria-label="Refresh Replication Rules"
component="span"
onClick={() => {
setLoadingReplication(true);
}}
>
<RefreshIcon />
</IconButton>
{canPutReplication && (
<Button
variant="contained"
color="primary"
startIcon={<CreateIcon />}
size="medium"
onClick={() => {
setOpenReplicationOpen(true);
}}
>
Add Replication Rule
</Button>
)}
</Grid>
<Grid item xs={12}>
<br />
</Grid>
<Grid item xs={12}>
<TableWrapper
itemActions={replicationTableActions}
columns={[
{
label: "Priority",
elementKey: "priority",
},
{
label: "Destination",
elementKey: "destination",
renderFunction: ruleDestDisplay,
},
{
label: "Prefix",
elementKey: "prefix",
},
{
label: "Tags",
elementKey: "tags",
renderFunction: tagDisplay,
},
{ label: "Status", elementKey: "status" },
]}
isLoading={loadingReplication}
records={replicationRules}
entityName="Replication Rules"
idField="id"
/>
</Grid>
</Grid>
</Fragment>
);
};
const mapState = (state: AppState) => ({
session: state.console.session,
});
const connector = connect(mapState, {
setErrorSnackMessage,
});
export default withStyles(styles)(connector(BucketReplicationPanel));

View File

@@ -0,0 +1,468 @@
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useState, useEffect } from "react";
import { connect } from "react-redux";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
import { Button, CircularProgress } from "@material-ui/core";
import get from "lodash/get";
import Paper from "@material-ui/core/Paper";
import Grid from "@material-ui/core/Grid";
import Typography from "@material-ui/core/Typography";
import { AppState } from "../../../../store";
import { setErrorSnackMessage } from "../../../../actions";
import {
BucketEncryptionInfo,
BucketInfo,
BucketObjectLocking,
BucketReplication,
BucketVersioning,
} from "../types";
import { niceBytes } from "../../../../common/utils";
import { BucketList } from "../../Watch/types";
import {
buttonsStyles,
hrClass,
} from "../../Common/FormComponents/common/styleLibrary";
import api from "../../../../common/api";
import SetAccessPolicy from "./SetAccessPolicy";
import SetRetentionConfig from "./SetRetentionConfig";
import EnableBucketEncryption from "./EnableBucketEncryption";
import EnableVersioningModal from "./EnableVersioningModal";
import UsageIcon from "../../../../icons/UsageIcon";
interface IBucketSummaryProps {
classes: any;
match: any;
setErrorSnackMessage: typeof setErrorSnackMessage;
}
const styles = (theme: Theme) =>
createStyles({
paperContainer: {
padding: 15,
paddingLeft: 50,
display: "flex",
},
elementTitle: {
fontWeight: 500,
color: "#777777",
fontSize: 14,
marginTop: -9,
},
consumptionValue: {
color: "#000000",
fontSize: "48px",
fontWeight: "bold",
},
reportedUsage: {
padding: "15px",
},
...hrClass,
...buttonsStyles,
});
const BucketSummary = ({
classes,
match,
setErrorSnackMessage,
}: IBucketSummaryProps) => {
const [info, setInfo] = useState<BucketInfo | null>(null);
const [encryptionCfg, setEncryptionCfg] =
useState<BucketEncryptionInfo | null>(null);
const [bucketSize, setBucketSize] = useState<string>("0");
const [hasObjectLocking, setHasObjectLocking] = useState<boolean>(false);
const [accessPolicyScreenOpen, setAccessPolicyScreenOpen] =
useState<boolean>(false);
const [replicationRules, setReplicationRules] = useState<boolean>(false);
const [loadingObjectLocking, setLoadingLocking] = useState<boolean>(true);
const [loadingSize, setLoadingSize] = useState<boolean>(true);
const [loadingBucket, setLoadingBucket] = useState<boolean>(true);
const [loadingEncryption, setLoadingEncryption] = useState<boolean>(true);
const [loadingVersioning, setLoadingVersioning] = useState<boolean>(true);
const [loadingReplication, setLoadingReplication] = useState<boolean>(true);
const [isVersioned, setIsVersioned] = useState<boolean>(false);
const [encryptionEnabled, setEncryptionEnabled] = useState<boolean>(false);
const [retentionConfigOpen, setRetentionConfigOpen] =
useState<boolean>(false);
const [enableEncryptionScreenOpen, setEnableEncryptionScreenOpen] =
useState<boolean>(false);
const [enableVersioningOpen, setEnableVersioningOpen] =
useState<boolean>(false);
const bucketName = match.params["bucketName"];
let accessPolicy = "n/a";
if (info !== null) {
accessPolicy = info.access;
}
// Effects
useEffect(() => {
if (loadingBucket) {
api
.invoke("GET", `/api/v1/buckets/${bucketName}`)
.then((res: BucketInfo) => {
setLoadingBucket(false);
setInfo(res);
})
.catch((err) => {
setLoadingBucket(false);
setErrorSnackMessage(err);
});
}
}, [loadingBucket, setErrorSnackMessage, bucketName]);
useEffect(() => {
if (loadingEncryption) {
api
.invoke("GET", `/api/v1/buckets/${bucketName}/encryption/info`)
.then((res: BucketEncryptionInfo) => {
if (res.algorithm) {
setEncryptionEnabled(true);
setEncryptionCfg(res);
}
setLoadingEncryption(false);
})
.catch((err) => {
if (
err === "The server side encryption configuration was not found"
) {
setEncryptionEnabled(false);
setEncryptionCfg(null);
}
setLoadingEncryption(false);
});
}
}, [loadingEncryption, bucketName]);
useEffect(() => {
if (loadingVersioning) {
api
.invoke("GET", `/api/v1/buckets/${bucketName}/versioning`)
.then((res: BucketVersioning) => {
setIsVersioned(res.is_versioned);
setLoadingVersioning(false);
})
.catch((err: any) => {
setErrorSnackMessage(err);
setLoadingVersioning(false);
});
}
}, [loadingVersioning, setErrorSnackMessage, bucketName]);
useEffect(() => {
if (loadingVersioning) {
api
.invoke("GET", `/api/v1/buckets/${bucketName}/object-locking`)
.then((res: BucketObjectLocking) => {
setHasObjectLocking(res.object_locking_enabled);
setLoadingLocking(false);
})
.catch((err: any) => {
setErrorSnackMessage(err);
setLoadingLocking(false);
});
}
}, [
loadingObjectLocking,
setErrorSnackMessage,
bucketName,
loadingVersioning,
]);
useEffect(() => {
if (loadingSize) {
api
.invoke("GET", `/api/v1/buckets`)
.then((res: BucketList) => {
const resBuckets = get(res, "buckets", []);
const bucketInfo = resBuckets.find(
(bucket) => bucket.name === bucketName
);
const size = get(bucketInfo, "size", "0");
setLoadingSize(false);
setBucketSize(size);
})
.catch((err: any) => {
setLoadingSize(false);
setErrorSnackMessage(err);
});
}
}, [loadingSize, setErrorSnackMessage, bucketName]);
useEffect(() => {
if (loadingReplication) {
api
.invoke("GET", `/api/v1/buckets/${bucketName}/replication`)
.then((res: BucketReplication) => {
const r = res.rules ? res.rules : [];
setReplicationRules(r.length > 0);
setLoadingReplication(false);
})
.catch((err: any) => {
setErrorSnackMessage(err);
setLoadingReplication(false);
});
}
}, [loadingReplication, setErrorSnackMessage, bucketName]);
const loadAllBucketData = () => {
setLoadingBucket(true);
setLoadingSize(true);
setLoadingVersioning(true);
setLoadingEncryption(true);
};
const setBucketVersioning = () => {
setEnableVersioningOpen(true);
};
const closeEnableBucketEncryption = () => {
setEnableEncryptionScreenOpen(false);
loadAllBucketData();
};
const closeSetAccessPolicy = () => {
setAccessPolicyScreenOpen(false);
loadAllBucketData();
};
const closeRetentionConfig = () => {
setRetentionConfigOpen(false);
loadAllBucketData();
};
const closeEnableVersioning = (refresh: boolean) => {
setEnableVersioningOpen(false);
if (refresh) {
loadAllBucketData();
}
};
return (
<Fragment>
{enableEncryptionScreenOpen && (
<EnableBucketEncryption
open={enableEncryptionScreenOpen}
selectedBucket={bucketName}
encryptionEnabled={encryptionEnabled}
encryptionCfg={encryptionCfg}
closeModalAndRefresh={closeEnableBucketEncryption}
/>
)}
{accessPolicyScreenOpen && (
<SetAccessPolicy
bucketName={bucketName}
open={accessPolicyScreenOpen}
actualPolicy={accessPolicy}
closeModalAndRefresh={closeSetAccessPolicy}
/>
)}
{retentionConfigOpen && (
<SetRetentionConfig
bucketName={bucketName}
open={retentionConfigOpen}
closeModalAndRefresh={closeRetentionConfig}
/>
)}
{enableVersioningOpen && (
<EnableVersioningModal
closeVersioningModalAndRefresh={closeEnableVersioning}
modalOpen={enableVersioningOpen}
selectedBucket={bucketName}
versioningCurrentState={isVersioned}
/>
)}
<br />
<Paper className={classes.paperContainer}>
<Grid container>
<Grid item xs={9}>
<h2>Details</h2>
<hr className={classes.hrClass} />
<table width={"100%"}>
<tbody>
<tr>
<td className={classes.titleCol}>Access Policy:</td>
<td className={classes.capitalizeFirst}>
<Button
color="primary"
className={classes.anchorButton}
onClick={() => {
setAccessPolicyScreenOpen(true);
}}
>
{loadingBucket ? (
<CircularProgress
color="primary"
size={16}
variant="indeterminate"
/>
) : (
accessPolicy.toLowerCase()
)}
</Button>
</td>
<td className={classes.titleCol}>Encryption:</td>
<td>
{loadingEncryption ? (
<CircularProgress
color="primary"
size={16}
variant="indeterminate"
/>
) : (
<Button
color="primary"
className={classes.anchorButton}
onClick={() => {
setEnableEncryptionScreenOpen(true);
}}
>
{encryptionEnabled ? "Enabled" : "Disabled"}
</Button>
)}
</td>
</tr>
<tr>
<td className={classes.titleCol}>Replication:</td>
<td className={classes.doubleElement}>
<span>{replicationRules ? "Enabled" : "Disabled"}</span>
</td>
{!hasObjectLocking ? (
<React.Fragment>
<td className={classes.titleCol}>Object Locking:</td>
<td>Disabled</td>
</React.Fragment>
) : (
<React.Fragment>
<td colSpan={2}></td>
</React.Fragment>
)}
</tr>
</tbody>
</table>
</Grid>
<Grid item xs={3} className={classes.reportedUsage}>
<Grid container direction="row" alignItems="center">
<Grid item className={classes.icon} xs={2}>
<UsageIcon />
</Grid>
<Grid item xs={10}>
<Typography className={classes.elementTitle}>
Reported Usage
</Typography>
</Grid>
</Grid>
<Typography className={classes.consumptionValue}>
{niceBytes(bucketSize)}
</Typography>
</Grid>
</Grid>
</Paper>
<br />
<br />
<Paper className={classes.paperContainer}>
<Grid container>
<Grid item xs={12}>
<h2>Versioning</h2>
<hr className={classes.hrClass} />
<table>
<tbody>
<tr>
<td className={classes.titleCol}>Versioning:</td>
<td>
{loadingVersioning ? (
<CircularProgress
color="primary"
size={16}
variant="indeterminate"
/>
) : (
<Fragment>
<Button
color="primary"
className={classes.anchorButton}
onClick={setBucketVersioning}
>
{isVersioned ? "Enabled" : "Disabled"}
</Button>
</Fragment>
)}
</td>
</tr>
</tbody>
</table>
</Grid>
</Grid>
</Paper>
<br />
<br />
{hasObjectLocking && (
<Paper className={classes.paperContainer}>
<Grid container>
<Grid item xs={12}>
<h2>Object Locking</h2>
<hr className={classes.hrClass} />
<table>
<tbody>
<tr className={classes.gridContainer}>
<td className={classes.titleCol}>Retention:</td>
<td>
{loadingVersioning ? (
<CircularProgress
color="primary"
size={16}
variant="indeterminate"
/>
) : (
<Fragment>
<Button
color="primary"
className={classes.anchorButton}
onClick={() => {
setRetentionConfigOpen(true);
}}
>
Configure
</Button>
</Fragment>
)}
</td>
</tr>
</tbody>
</table>
</Grid>
</Grid>
</Paper>
)}
</Fragment>
);
};
const mapState = (state: AppState) => ({
session: state.console.session,
});
const connector = connect(mapState, {
setErrorSnackMessage,
});
export default withStyles(styles)(connector(BucketSummary));

View File

@@ -0,0 +1,197 @@
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import Grid from "@material-ui/core/Grid";
import { Button, LinearProgress } from "@material-ui/core";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
import { modalBasic } from "../../Common/FormComponents/common/styleLibrary";
import { setModalErrorSnackMessage } from "../../../../actions";
import api from "../../../../common/api";
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import QueryMultiSelector from "../../Common/FormComponents/QueryMultiSelector/QueryMultiSelector";
import { LifeCycleItem } from "../types";
const styles = (theme: Theme) =>
createStyles({
strongText: {
fontWeight: 700,
},
keyName: {
marginLeft: 5,
},
buttonContainer: {
textAlign: "right",
},
...modalBasic,
});
interface IAddUserContentProps {
classes: any;
closeModalAndRefresh: (reload: boolean) => void;
selectedBucket: string;
lifecycle: LifeCycleItem;
open: boolean;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
const EditLifecycleConfiguration = ({
classes,
closeModalAndRefresh,
selectedBucket,
lifecycle,
open,
setModalErrorSnackMessage,
}: IAddUserContentProps) => {
const [addLoading, setAddLoading] = useState<boolean>(false);
const [tags, setTags] = useState<string>("");
const [enabled, setEnabled] = useState<boolean>(false);
useEffect(() => {
if (lifecycle.status === "Enabled") {
setEnabled(true);
}
if (lifecycle.tags) {
const tgs = lifecycle.tags.reduce(
(stringLab: string, currItem: any, index: number) => {
return `${stringLab}${index !== 0 ? "&" : ""}${currItem.key}=${
currItem.value
}`;
},
""
);
setTags(tgs);
}
}, [lifecycle]);
const saveRecord = (event: React.FormEvent) => {
event.preventDefault();
if (addLoading) {
return;
}
setAddLoading(true);
if (selectedBucket !== null && lifecycle !== null) {
api
.invoke(
"PUT",
`/api/v1/buckets/${selectedBucket}/lifecycle/${lifecycle.id}`,
{
disable: !enabled,
tags: tags,
}
)
.then((res) => {
setAddLoading(false);
closeModalAndRefresh(true);
})
.catch((err) => {
setAddLoading(false);
setModalErrorSnackMessage(err);
});
}
};
return (
<ModalWrapper
onClose={() => {
closeModalAndRefresh(false);
}}
modalOpen={open}
title={"Edit Lifecycle Configuration"}
>
<div className={classes.floatingEnabled}>
<FormSwitchWrapper
indicatorLabels={["Enabled", "Disabled"]}
checked={enabled}
value={"user_enabled"}
id="user-status"
name="user-status"
onChange={(e) => {
setEnabled(e.target.checked);
}}
switchOnly
/>
</div>
<React.Fragment>
<form
noValidate
autoComplete="off"
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
saveRecord(e);
}}
>
<Grid container>
<Grid item xs={12} className={classes.formScrollable}>
<Grid item xs={12}>
<InputBoxWrapper
id="id"
name="id"
label="Id"
value={lifecycle.id}
onChange={() => {}}
disabled
/>
</Grid>
<Grid item xs={12}>
<QueryMultiSelector
name="tags"
label="Tags"
elements={tags}
onChange={(vl: string) => {
setTags(vl);
}}
keyPlaceholder="Tag Key"
valuePlaceholder="Tag Value"
withBorder
/>
</Grid>
</Grid>
<Grid item xs={12} className={classes.buttonContainer}>
<Button
type="submit"
variant="contained"
color="primary"
disabled={addLoading}
>
Save
</Button>
</Grid>
{addLoading && (
<Grid item xs={12}>
<LinearProgress />
</Grid>
)}
</Grid>
</form>
</React.Fragment>
</ModalWrapper>
);
};
const mapDispatchToProps = {
setModalErrorSnackMessage,
};
const connector = connect(null, mapDispatchToProps);
export default withStyles(styles)(connector(EditLifecycleConfiguration));

View File

@@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useState } from "react";
import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import Grid from "@material-ui/core/Grid";
import { Button, LinearProgress } from "@material-ui/core";
@@ -25,6 +25,7 @@ import api from "../../../../common/api";
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
import { BucketEncryptionInfo } from "../types";
const styles = (theme: Theme) =>
createStyles({
@@ -45,6 +46,8 @@ const styles = (theme: Theme) =>
interface IEnableBucketEncryptionProps {
classes: any;
open: boolean;
encryptionEnabled: boolean;
encryptionCfg: BucketEncryptionInfo | null;
selectedBucket: string;
closeModalAndRefresh: () => void;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
@@ -53,32 +56,58 @@ interface IEnableBucketEncryptionProps {
const EnableBucketEncryption = ({
classes,
open,
encryptionEnabled,
encryptionCfg,
selectedBucket,
closeModalAndRefresh,
setModalErrorSnackMessage,
}: IEnableBucketEncryptionProps) => {
const [loading, setLoading] = useState<boolean>(false);
const [kmsKeyID, setKmsKeyID] = useState<string>("");
const [encryptionType, setEncryptionType] = useState<string>("sse-s3");
const [encryptionType, setEncryptionType] = useState<string>("disabled");
useEffect(() => {
if (encryptionCfg) {
if (encryptionCfg.algorithm === "AES256") {
setEncryptionType("sse-s3");
} else {
setEncryptionType("sse-kms");
setKmsKeyID(encryptionCfg.kmsMasterKeyID);
}
}
}, [encryptionCfg]);
const enableBucketEncryption = (event: React.FormEvent) => {
event.preventDefault();
if (loading) {
return;
}
api
.invoke("POST", `/api/v1/buckets/${selectedBucket}/encryption/enable`, {
encType: encryptionType,
kmsKeyID: kmsKeyID,
})
.then(() => {
setLoading(false);
closeModalAndRefresh();
})
.catch((err: any) => {
setLoading(false);
setModalErrorSnackMessage(err);
});
if (encryptionType === "disabled") {
api
.invoke("POST", `/api/v1/buckets/${selectedBucket}/encryption/disable`)
.then(() => {
setLoading(false);
closeModalAndRefresh();
})
.catch((err: any) => {
setLoading(false);
setModalErrorSnackMessage(err);
});
} else {
api
.invoke("POST", `/api/v1/buckets/${selectedBucket}/encryption/enable`, {
encType: encryptionType,
kmsKeyID: kmsKeyID,
})
.then(() => {
setLoading(false);
closeModalAndRefresh();
})
.catch((err: any) => {
setLoading(false);
setModalErrorSnackMessage(err);
});
}
};
return (
@@ -108,6 +137,10 @@ const EnableBucketEncryption = ({
label={"Encryption Type"}
value={encryptionType}
options={[
{
label: "Disabled",
value: "disabled",
},
{
label: "SSE-S3",
value: "sse-s3",

View File

@@ -22,7 +22,7 @@ import { AppState } from "../../../store";
import { setMenuOpen } from "../../../actions";
import NotFoundPage from "../../NotFoundPage";
import ListBuckets from "./ListBuckets/ListBuckets";
import ViewBucket from "./ViewBucket/ViewBucket";
import BucketDetails from "./BucketDetails/BucketDetails";
const mapState = (state: AppState) => ({
open: state.system.sidebarOpen,
@@ -34,7 +34,8 @@ const Buckets = () => {
return (
<Router history={history}>
<Switch>
<Route path="/buckets/:bucketName" component={ViewBucket} />
<Route path="/buckets/:bucketName/*" component={BucketDetails} />
<Route path="/buckets/:bucketName" component={BucketDetails} />
<Route path="/" component={ListBuckets} />
<Route component={NotFoundPage} />
</Switch>

View File

@@ -126,9 +126,8 @@ const AddBucket = ({
}: IAddBucketProps) => {
const [addLoading, setAddLoading] = useState<boolean>(false);
const [sendEnabled, setSendEnabled] = useState<boolean>(false);
const [lockingFieldDisabled, setLockingFieldDisabled] = useState<boolean>(
false
);
const [lockingFieldDisabled, setLockingFieldDisabled] =
useState<boolean>(false);
const addRecord = (event: React.FormEvent) => {
event.preventDefault();
@@ -238,12 +237,13 @@ const AddBucket = ({
quotaSize,
quotaUnit,
quotaEnabled,
retentionEnabled,
addBucketRetention,
addBucketRetentionMode,
addBucketRetentionUnit,
addBucketRetentionValidity,
retentionValidity,
versioningEnabled,
enableObjectLocking,
]);
return (

View File

@@ -36,6 +36,7 @@ import GenericWizard from "../../Common/GenericWizard/GenericWizard";
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
import { SelectorTypes } from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector";
import { getBytes, k8sfactorForDropdown } from "../../../../common/utils";
interface IBulkReplicationModal {
open: boolean;
@@ -93,6 +94,10 @@ const AddBulkReplicationModal = ({
const [targetURL, setTargetURL] = useState<string>("");
const [region, setRegion] = useState<string>("");
const [useTLS, setUseTLS] = useState<boolean>(true);
const [replicationMode, setReplicationMode] = useState<string>("async");
const [bandwidthScalar, setBandwidthScalar] = useState<string>("100");
const [bandwidthUnit, setBandwidthUnit] = useState<string>("Gi");
const [healthCheck, setHealthCheck] = useState<string>("60");
const [relationBuckets, setRelationBuckets] = useState<string[]>([]);
const [remoteBucketsOpts, setRemoteBucketOpts] = useState<string[]>([]);
const [responseItem, setResponseItem] = useState<BulkReplicationItem[]>([]);
@@ -131,12 +136,20 @@ const AddBulkReplicationModal = ({
});
const endURL = `${useTLS ? "https://" : "http://"}${targetURL}`;
const hc = parseInt(healthCheck);
const remoteBucketsInfo = {
accessKey: accessKey,
secretKey: secretKey,
targetURL: endURL,
region: region,
bucketsRelation: replicate,
syncMode: replicationMode,
bandwidth:
replicationMode === "async"
? parseInt(getBytes(bandwidthScalar, bandwidthUnit, true))
: 0,
healthCheckPeriod: hc,
};
api
@@ -386,6 +399,67 @@ const AddBulkReplicationModal = ({
value={region}
/>
</Grid>
<Grid item xs={12}>
<SelectWrapper
id="replication_mode"
name="replication_mode"
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
setReplicationMode(e.target.value as string);
}}
label="Replication Mode"
value={replicationMode}
options={[
{ label: "Asynchronous", value: "async" },
{ label: "Synchronous", value: "sync" },
]}
/>
</Grid>
{replicationMode === "async" && (
<Grid item xs={12}>
<div className={classes.multiContainer}>
<div>
<InputBoxWrapper
type="number"
id="bandwidth_scalar"
name="bandwidth_scalar"
onChange={(
e: React.ChangeEvent<HTMLInputElement>
) => {
setBandwidthScalar(e.target.value as string);
}}
label="Bandwidth"
value={bandwidthScalar}
min="0"
/>
</div>
<div className={classes.sizeFactorContainer}>
<SelectWrapper
label={"Unit"}
id="bandwidth_unit"
name="bandwidth_unit"
value={bandwidthUnit}
onChange={(
e: React.ChangeEvent<{ value: unknown }>
) => {
setBandwidthUnit(e.target.value as string);
}}
options={k8sfactorForDropdown()}
/>
</div>
</div>
</Grid>
)}
<Grid item xs={12}>
<InputBoxWrapper
id="healthCheck"
name="healthCheck"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setHealthCheck(e.target.value as string);
}}
label="Health Check Duration"
value={healthCheck}
/>
</Grid>
</Fragment>
),
buttons: [

View File

@@ -97,9 +97,8 @@ const ListBuckets = ({
const [loadingPerms, setLoadingPerms] = useState<boolean>(true);
const [canCreateBucket, setCanCreateBucket] = useState<boolean>(false);
const [selectedBuckets, setSelectedBuckets] = useState<string[]>([]);
const [replicationModalOpen, setReplicationModalOpen] = useState<boolean>(
false
);
const [replicationModalOpen, setReplicationModalOpen] =
useState<boolean>(false);
// check the permissions for creating bucket
useEffect(() => {

View File

@@ -33,7 +33,7 @@ import {
searchField,
} from "../../../../Common/FormComponents/common/styleLibrary";
import PageHeader from "../../../../Common/PageHeader/PageHeader";
import { Button, Input, Typography } from "@material-ui/core";
import { Button, IconButton, Input, Typography } from "@material-ui/core";
import * as reactMoment from "react-moment";
import { CreateIcon } from "../../../../../../icons";
import BrowserBreadcrumbs from "../../../../ObjectBrowser/BrowserBreadcrumbs";
@@ -59,6 +59,7 @@ import {
setSnackBarMessage,
setErrorSnackMessage,
} from "../../../../../../actions";
import RefreshIcon from "@material-ui/icons/Refresh";
const commonIcon = {
backgroundRepeat: "no-repeat",
@@ -129,6 +130,9 @@ const styles = (theme: Theme) =>
backgroundImage: "url(/images/ob_folder_filled.svg)",
},
},
listButton: {
marginLeft: "10px",
},
...actionsTray,
...searchField,
...objectBrowserCommon,
@@ -195,13 +199,9 @@ const ListObjects = ({
const [selectedObject, setSelectedObject] = useState<string>("");
const [selectedBucket, setSelectedBucket] = useState<string>("");
const [filterObjects, setFilterObjects] = useState<string>("");
const [loadingPromise, setLoadingPromise] = useState<Promise<any> | null>(
null
);
const [loadingStartTime, setLoadingStartTime] = useState<number>(0);
const [loadingMessage, setLoadingMessage] = useState<React.ReactNode>(
defLoading
);
const [loadingMessage, setLoadingMessage] =
useState<React.ReactNode>(defLoading);
const updateMessage = () => {
let timeDelta = Date.now() - loadingStartTime;
@@ -269,7 +269,7 @@ const ListObjects = ({
setLoadingStartTime(currentTimestamp);
setLoadingMessage(defLoading);
let p = api
api
.invoke("GET", `/api/v1/buckets/${bucketName}/objects${extraPath}`)
.then((res: BucketObjectsList) => {
setSelectedBucket(bucketName);
@@ -302,7 +302,6 @@ const ListObjects = ({
setLoading(false);
setErrorSnackMessage(err);
});
setLoadingPromise(p);
}
}, [loading, match, setLastAsFile, setErrorSnackMessage]);
@@ -546,34 +545,6 @@ const ListObjects = ({
<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"
inputProps={{ multiple: true }}
onChange={(e) => uploadObject(e)}
id="file-input"
style={{ display: "none" }}
/>
</Button>
</div>
</Grid>
<Grid item xs={12} className={classes.actionsTray}>
<TextField
@@ -593,6 +564,44 @@ const ListObjects = ({
),
}}
/>
<IconButton
color="primary"
aria-label="Refresh List"
component="span"
onClick={() => {
setLoading(true);
}}
>
<RefreshIcon />
</IconButton>
<Button
variant="contained"
color="primary"
startIcon={<CreateIcon />}
component="label"
onClick={() => {
setCreateFolderOpen(true);
}}
className={classes.listButton}
>
Create Folder
</Button>
<Button
variant="contained"
color="primary"
startIcon={<UploadFile />}
component="label"
className={classes.listButton}
>
File
<Input
type="file"
inputProps={{ multiple: true }}
onChange={(e) => uploadObject(e)}
id="file-input"
style={{ display: "none" }}
/>
</Button>
</Grid>
<Grid item xs={12}>
<br />

View File

@@ -1,214 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useState } from "react";
import { connect } from "react-redux";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
import { Button, LinearProgress } from "@material-ui/core";
import get from "lodash/get";
import Grid from "@material-ui/core/Grid";
import { modalBasic } from "../../Common/FormComponents/common/styleLibrary";
import { BulkReplicationResponse } from "../types";
import { setModalErrorSnackMessage } from "../../../../actions";
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
import api from "../../../../common/api";
interface IReplicationModal {
open: boolean;
closeModalAndRefresh: () => any;
classes: any;
bucketName: string;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
const styles = (theme: Theme) =>
createStyles({
minTableHeader: {
color: "#393939",
"& tr": {
"& th": {
fontWeight: "bold",
},
},
},
buttonContainer: {
textAlign: "right",
},
...modalBasic,
});
const AddReplicationModal = ({
open,
closeModalAndRefresh,
classes,
bucketName,
setModalErrorSnackMessage,
}: IReplicationModal) => {
const [addLoading, setAddLoading] = useState(false);
const [accessKey, setAccessKey] = useState("");
const [secretKey, setSecretKey] = useState("");
const [targetURL, setTargetURL] = useState("");
const [targetBucket, setTargetBucket] = useState("");
const [region, setRegion] = useState("");
const addRecord = () => {
const replicate = [
{
originBucket: bucketName,
destinationBucket: targetBucket,
},
];
const remoteBucketsInfo = {
accessKey: accessKey,
secretKey: secretKey,
targetURL: targetURL,
region: region,
bucketsRelation: replicate,
};
api
.invoke("POST", "/api/v1/buckets-replication", remoteBucketsInfo)
.then((response: BulkReplicationResponse) => {
setAddLoading(false);
const states = get(response, "replicationState", []);
if (states.length > 0) {
const itemVal = states[0];
setAddLoading(false);
if (itemVal.errorString && itemVal.errorString !== "") {
setModalErrorSnackMessage(itemVal.errorString);
return;
}
closeModalAndRefresh();
return;
}
setModalErrorSnackMessage("No changes applied");
})
.catch((err) => {
setAddLoading(false);
setModalErrorSnackMessage(err);
});
};
return (
<ModalWrapper
modalOpen={open}
onClose={() => {
closeModalAndRefresh();
}}
title="Set Bucket Replication"
>
<form
noValidate
autoComplete="off"
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
setAddLoading(true);
addRecord();
}}
>
<Grid container>
<Grid item xs={12} className={classes.formScrollable}>
<Grid item xs={12}>
<InputBoxWrapper
id="accessKey"
name="accessKey"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setAccessKey(e.target.value);
}}
label="Access Key"
value={accessKey}
/>
</Grid>
<Grid item xs={12}>
<InputBoxWrapper
id="secretKey"
name="secretKey"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setSecretKey(e.target.value);
}}
label="Secret Key"
value={secretKey}
/>
</Grid>
<Grid item xs={12}>
<InputBoxWrapper
id="targetURL"
name="targetURL"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setTargetURL(e.target.value);
}}
placeholder="https://play.min.io:9000"
label="Target URL"
value={targetURL}
/>
</Grid>
<Grid item xs={12}>
<InputBoxWrapper
id="targetBucket"
name="targetBucket"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setTargetBucket(e.target.value);
}}
label="Target Bucket"
value={targetBucket}
/>
</Grid>
<Grid item xs={12}>
<InputBoxWrapper
id="region"
name="region"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setRegion(e.target.value);
}}
label="Region"
value={region}
/>
</Grid>
</Grid>
<Grid item xs={12} className={classes.buttonContainer}>
<Button
type="submit"
variant="contained"
color="primary"
disabled={addLoading}
>
Save
</Button>
</Grid>
{addLoading && (
<Grid item xs={12}>
<LinearProgress />
</Grid>
)}
</Grid>
</form>
</ModalWrapper>
);
};
const connector = connect(null, {
setModalErrorSnackMessage,
});
export default withStyles(styles)(connector(AddReplicationModal));

View File

@@ -1,940 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useEffect, useState, Fragment } from "react";
import { connect } from "react-redux";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
import { Button, IconButton } from "@material-ui/core";
import get from "lodash/get";
import Paper from "@material-ui/core/Paper";
import Grid from "@material-ui/core/Grid";
import Tabs from "@material-ui/core/Tabs";
import Tab from "@material-ui/core/Tab";
import CircularProgress from "@material-ui/core/CircularProgress";
import Checkbox from "@material-ui/core/Checkbox";
import Typography from "@material-ui/core/Typography";
import api from "../../../../common/api";
import {
BucketEncryptionInfo,
BucketEvent,
BucketEventList,
BucketInfo,
BucketList,
BucketObjectLocking,
BucketReplication,
BucketReplicationDestination,
BucketReplicationRule,
BucketReplicationRuleDeleteMarker,
BucketVersioning,
HasPermissionResponse,
} from "../types";
import { CreateIcon } from "../../../../icons";
import { niceBytes } from "../../../../common/utils";
import { containerForHeader } from "../../Common/FormComponents/common/styleLibrary";
import { setErrorSnackMessage } from "../../../../actions";
import { Policy } from "../../Policies/types";
import { User } from "../../Users/types";
import SetRetentionConfig from "./SetRetentionConfig";
import AddEvent from "./AddEvent";
import DeleteEvent from "./DeleteEvent";
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
import AddReplicationModal from "./AddReplicationModal";
import PageHeader from "../../Common/PageHeader/PageHeader";
import EnableBucketEncryption from "./EnableBucketEncryption";
import PencilIcon from "../../Common/TableWrapper/TableActionIcons/PencilIcon";
import EnableVersioningModal from "./EnableVersioningModal";
import UsageIcon from "../../../../icons/UsageIcon";
import AddPolicy from "../../Policies/AddPolicy";
import SetAccessPolicy from "./SetAccessPolicy";
import DeleteReplicationRule from "../ViewBucket/DeleteReplicationRule";
const styles = (theme: Theme) =>
createStyles({
seeMore: {
marginTop: theme.spacing(3),
},
paper: {
display: "flex",
overflow: "auto",
flexDirection: "column",
},
addSideBar: {
width: "320px",
padding: "20px",
},
tableToolbar: {
paddingLeft: theme.spacing(2),
paddingRight: theme.spacing(0),
},
minTableHeader: {
color: "#393939",
"& tr": {
"& th": {
fontWeight: "bold",
},
},
},
actionsTray: {
textAlign: "right",
"& button": {
marginLeft: 10,
},
},
searchField: {
background: "#FFFFFF",
padding: 12,
borderRadius: 5,
boxShadow: "0px 3px 6px #00000012",
},
noRecords: {
lineHeight: "24px",
textAlign: "center",
padding: "20px",
},
gridWrapper: {
width: 320,
},
gridContainer: {
display: "grid",
gridTemplateColumns: "auto auto",
gridGap: 8,
justifyContent: "flex-start",
alignItems: "center",
"& div:not(.MuiCircularProgress-root)": {
display: "flex",
alignItems: "center",
},
"& div:nth-child(odd)": {
justifyContent: "flex-end",
fontWeight: 700,
},
"& div:nth-child(2n)": {
minWidth: 150,
},
},
masterActions: {
width: "25%",
minWidth: "120px",
"& div": {
margin: "5px 0px",
},
},
paperContainer: {
padding: 15,
paddingLeft: 50,
display: "flex",
},
headerContainer: {
display: "flex",
justifyContent: "space-between",
},
capitalizeFirst: {
textTransform: "capitalize",
},
doubleElement: {
display: "flex",
justifyContent: "space-between",
},
encCheckbox: {
margin: 0,
padding: 0,
},
tabPan: {
marginTop: "5px",
},
fixedHeight: {
height: 165,
minWidth: 247,
padding: "25px 28px",
"& svg": {
maxHeight: 18,
},
},
elementTitle: {
fontWeight: 500,
color: "#777777",
fontSize: 14,
marginTop: -9,
},
consumptionValue: {
color: "#000000",
fontSize: "60px",
fontWeight: "bold",
},
...containerForHeader(theme.spacing(4)),
});
interface IViewBucketProps {
classes: any;
match: any;
setErrorSnackMessage: typeof setErrorSnackMessage;
}
interface TabPanelProps {
children?: React.ReactNode;
index: any;
value: any;
}
function TabPanel(props: TabPanelProps) {
const { children, value, index, ...other } = props;
return (
<div
role="tabpanel"
hidden={value !== index}
id={`simple-tabpanel-${index}`}
aria-labelledby={`simple-tab-${index}`}
style={{ marginTop: "5px" }}
{...other}
>
{value === index && <Fragment>{children}</Fragment>}
</div>
);
}
function a11yProps(index: any) {
return {
id: `simple-tab-${index}`,
"aria-controls": `simple-tabpanel-${index}`,
};
}
const ViewBucket = ({
classes,
match,
setErrorSnackMessage,
}: IViewBucketProps) => {
const [info, setInfo] = useState<BucketInfo | null>(null);
const [records, setRecords] = useState<BucketEvent[]>([]);
const [replicationRules, setReplicationRules] = useState<
BucketReplicationRule[]
>([]);
const [bucketPolicy, setBucketPolicy] = useState<Policy[]>([]);
const [loadingPolicy, setLoadingPolicy] = useState<boolean>(true);
const [bucketUsers, setBucketUsers] = useState<User[]>([]);
const [loadingUsers, setLoadingUsers] = useState<boolean>(true);
const [loadingBucket, setLoadingBucket] = useState<boolean>(true);
const [loadingEvents, setLoadingEvents] = useState<boolean>(true);
const [loadingVersioning, setLoadingVersioning] = useState<boolean>(true);
const [loadingObjectLocking, setLoadingLocking] = useState<boolean>(true);
const [loadingReplication, setLoadingReplication] = useState<boolean>(true);
const [loadingSize, setLoadingSize] = useState<boolean>(true);
const [loadingEncryption, setLoadingEncryption] = useState<boolean>(true);
const [accessPolicyScreenOpen, setAccessPolicyScreenOpen] = useState<boolean>(
false
);
const [curTab, setCurTab] = useState<number>(0);
const [addScreenOpen, setAddScreenOpen] = useState<boolean>(false);
const [policyScreenOpen, setPolicyScreenOpen] = useState<boolean>(false);
const [
enableEncryptionScreenOpen,
setEnableEncryptionScreenOpen,
] = useState<boolean>(false);
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
const [selectedEvent, setSelectedEvent] = useState<BucketEvent | null>(null);
const [bucketSize, setBucketSize] = useState<string>("0");
const [openSetReplication, setOpenSetReplication] = useState<boolean>(false);
const [isVersioned, setIsVersioned] = useState<boolean>(false);
const [hasObjectLocking, setHasObjectLocking] = useState<boolean>(false);
const [encryptionEnabled, setEncryptionEnabled] = useState<boolean>(false);
const [retentionConfigOpen, setRetentionConfigOpen] = useState<boolean>(
false
);
const [policyEdit, setPolicyEdit] = useState<any>(null);
const [enableVersioningOpen, setEnableVersioningOpen] = useState<boolean>(
false
);
const [loadingPerms, setLoadingPerms] = useState<boolean>(true);
const [canPutReplication, setCanPutReplication] = useState<boolean>(false);
const [canGetReplication, setCanGetReplication] = useState<boolean>(false);
const [deleteReplicationModal, setDeleteReplicationModal] = useState<boolean>(
false
);
const [selectedRRule, setSelectedRRule] = useState<string>("");
// check the permissions for creating bucket
useEffect(() => {
if (loadingPerms) {
api
.invoke("POST", `/api/v1/has-permission`, {
actions: [
{
id: "PutReplicationConfiguration",
action: "s3:PutReplicationConfiguration",
bucket_name: bucketName,
},
{
id: "GetReplicationConfiguration",
action: "s3:GetReplicationConfiguration",
bucket_name: bucketName,
},
],
})
.then((res: HasPermissionResponse) => {
setLoadingPerms(false);
if (!res.permissions) {
return;
}
const actions = res.permissions ? res.permissions : [];
let canPutReplication = actions.find(
(s) => s.id === "PutReplicationConfiguration"
);
if (canPutReplication && canPutReplication.can) {
setCanPutReplication(true);
} else {
setCanPutReplication(false);
}
let canGetReplication = actions.find(
(s) => s.id === "GetReplicationConfiguration"
);
if (canGetReplication && canGetReplication.can) {
setCanGetReplication(true);
} else {
setCanGetReplication(false);
}
setLoadingPerms(false);
})
.catch((err: any) => {
setLoadingPerms(false);
setErrorSnackMessage(err);
});
}
}, [loadingPerms, setErrorSnackMessage]);
const bucketName = match.params["bucketName"];
useEffect(() => {
if (loadingEvents) {
api
.invoke("GET", `/api/v1/buckets/${bucketName}/events`)
.then((res: BucketEventList) => {
const events = get(res, "events", []);
setLoadingEvents(false);
setRecords(events || []);
})
.catch((err: any) => {
setLoadingEvents(false);
setErrorSnackMessage(err);
});
}
}, [loadingEvents, setErrorSnackMessage, bucketName]);
useEffect(() => {
if (loadingVersioning) {
api
.invoke("GET", `/api/v1/buckets/${bucketName}/versioning`)
.then((res: BucketVersioning) => {
setIsVersioned(res.is_versioned);
setLoadingVersioning(false);
})
.catch((err: any) => {
setErrorSnackMessage(err);
setLoadingVersioning(false);
});
}
}, [loadingVersioning, setErrorSnackMessage, bucketName]);
useEffect(() => {
if (loadingVersioning) {
api
.invoke("GET", `/api/v1/buckets/${bucketName}/object-locking`)
.then((res: BucketObjectLocking) => {
setHasObjectLocking(res.object_locking_enabled);
setLoadingLocking(false);
})
.catch((err: any) => {
setErrorSnackMessage(err);
setLoadingLocking(false);
});
}
}, [loadingObjectLocking, setErrorSnackMessage, bucketName]);
useEffect(() => {
if (loadingReplication) {
api
.invoke("GET", `/api/v1/buckets/${bucketName}/replication`)
.then((res: BucketReplication) => {
const r = res.rules ? res.rules : [];
setReplicationRules(r);
setLoadingReplication(false);
})
.catch((err: any) => {
setErrorSnackMessage(err);
setLoadingReplication(false);
});
}
}, [loadingReplication, setErrorSnackMessage, bucketName]);
useEffect(() => {
if (loadingPolicy) {
api
.invoke("GET", `/api/v1/bucket-policy/${bucketName}`)
.then((res: any) => {
setBucketPolicy(res.policies);
setLoadingPolicy(false);
})
.catch((err: any) => {
setErrorSnackMessage(err);
setLoadingPolicy(false);
});
}
}, [loadingPolicy, setErrorSnackMessage, bucketName]);
useEffect(() => {
if (loadingUsers) {
api
.invoke("GET", `/api/v1/bucket-users/${bucketName}`)
.then((res: any) => {
setBucketUsers(res);
setLoadingUsers(false);
})
.catch((err: any) => {
setErrorSnackMessage(err);
setLoadingUsers(false);
});
}
}, [loadingUsers, setErrorSnackMessage, bucketName]);
useEffect(() => {
if (loadingSize) {
api
.invoke("GET", `/api/v1/buckets`)
.then((res: BucketList) => {
const resBuckets = get(res, "buckets", []);
const bucketInfo = resBuckets.find(
(bucket) => bucket.name === bucketName
);
const size = get(bucketInfo, "size", "0");
setLoadingSize(false);
setBucketSize(size);
})
.catch((err: any) => {
setLoadingSize(false);
setErrorSnackMessage(err);
});
}
}, [loadingSize, setErrorSnackMessage, bucketName]);
useEffect(() => {
if (loadingBucket) {
api
.invoke("GET", `/api/v1/buckets/${bucketName}`)
.then((res: BucketInfo) => {
setLoadingBucket(false);
setInfo(res);
})
.catch((err) => {
setLoadingBucket(false);
setErrorSnackMessage(err);
});
}
}, [loadingBucket, setErrorSnackMessage, bucketName]);
useEffect(() => {
if (loadingEncryption) {
api
.invoke("GET", `/api/v1/buckets/${bucketName}/encryption/info`)
.then((res: BucketEncryptionInfo) => {
if (res.algorithm) {
setEncryptionEnabled(true);
}
setLoadingEncryption(false);
})
.catch((err) => {
console.error(err);
setLoadingEncryption(false);
});
}
}, [loadingEncryption, bucketName]);
const setBucketVersioning = () => {
setEnableVersioningOpen(true);
};
const loadAllBucketData = () => {
setLoadingBucket(true);
setLoadingSize(true);
setLoadingReplication(true);
setLoadingVersioning(true);
setLoadingEvents(true);
setLoadingEncryption(true);
};
const closeAddModalAndRefresh = (refresh: boolean) => {
setPolicyScreenOpen(false);
if (refresh) {
fetchPolicies();
}
};
const fetchPolicies = () => {
setLoadingPolicy(true);
};
const closeAddEventAndRefresh = () => {
setAddScreenOpen(false);
loadAllBucketData();
};
const closeEnableBucketEncryption = () => {
setEnableEncryptionScreenOpen(false);
loadAllBucketData();
};
const closeSetAccessPolicy = () => {
setAccessPolicyScreenOpen(false);
loadAllBucketData();
};
const closeRetentionConfig = () => {
setRetentionConfigOpen(false);
loadAllBucketData();
};
const closeAddReplication = () => {
setOpenReplicationOpen(false);
loadAllBucketData();
};
const closeDeleteModalAndRefresh = (refresh: boolean) => {
setDeleteOpen(false);
if (refresh) {
loadAllBucketData();
}
};
const confirmDeleteEvent = (evnt: BucketEvent) => {
setDeleteOpen(true);
setSelectedEvent(evnt);
};
const confirmDeleteReplication = (replication: BucketReplicationRule) => {
setSelectedRRule(replication.id);
setDeleteReplicationModal(true);
};
const closeEnableVersioning = (refresh: boolean) => {
setEnableVersioningOpen(false);
if (refresh) {
loadAllBucketData();
}
};
let accessPolicy = "n/a";
if (info !== null) {
accessPolicy = info.access;
}
const eventsDisplay = (events: string[]) => {
return <Fragment>{events.join(", ")}</Fragment>;
};
const ruleDestDisplay = (events: BucketReplicationDestination) => {
return <Fragment>{events.bucket.replace("arn:aws:s3:::", "")}</Fragment>;
};
const ruleDelDisplay = (events: BucketReplicationRuleDeleteMarker) => {
return <Fragment>{events.status}</Fragment>;
};
const setOpenReplicationOpen = (open = false) => {
setOpenSetReplication(open);
};
const closeReplicationModalDelete = (refresh: boolean) => {
setDeleteReplicationModal(false);
if (refresh) {
setLoadingReplication(true);
}
};
const handleEncryptionCheckbox = (
event: React.ChangeEvent<HTMLInputElement>
) => {
if (event.target.checked) {
setEnableEncryptionScreenOpen(true);
} else {
api
.invoke("POST", `/api/v1/buckets/${bucketName}/encryption/disable`)
.then(() => {
setEncryptionEnabled(false);
})
.catch((err: any) => {
setErrorSnackMessage(err);
});
}
};
const tableActions = [{ type: "delete", onClick: confirmDeleteEvent }];
const viewAction = (row: any) => {
setPolicyScreenOpen(true);
setPolicyEdit(row);
};
const PolicyActions = [{ type: "view", onClick: viewAction }];
const replicationTableActions = [
{
type: "delete",
onClick: confirmDeleteReplication,
disableButtonFunction: () => replicationRules.length <= 1,
},
];
return (
<Fragment>
{addScreenOpen && (
<AddEvent
open={addScreenOpen}
selectedBucket={bucketName}
closeModalAndRefresh={closeAddEventAndRefresh}
/>
)}
{enableEncryptionScreenOpen && (
<EnableBucketEncryption
open={enableEncryptionScreenOpen}
selectedBucket={bucketName}
closeModalAndRefresh={closeEnableBucketEncryption}
/>
)}
{accessPolicyScreenOpen && (
<SetAccessPolicy
bucketName={bucketName}
open={accessPolicyScreenOpen}
actualPolicy={accessPolicy}
closeModalAndRefresh={closeSetAccessPolicy}
/>
)}
{policyScreenOpen && (
<AddPolicy
open={policyScreenOpen}
closeModalAndRefresh={closeAddModalAndRefresh}
policyEdit={policyEdit}
/>
)}
{retentionConfigOpen && (
<SetRetentionConfig
bucketName={bucketName}
open={retentionConfigOpen}
closeModalAndRefresh={closeRetentionConfig}
/>
)}
{openSetReplication && (
<AddReplicationModal
closeModalAndRefresh={closeAddReplication}
open={openSetReplication}
bucketName={bucketName}
/>
)}
{deleteOpen && (
<DeleteEvent
deleteOpen={deleteOpen}
selectedBucket={bucketName}
bucketEvent={selectedEvent}
closeDeleteModalAndRefresh={closeDeleteModalAndRefresh}
/>
)}
{enableVersioningOpen && (
<EnableVersioningModal
closeVersioningModalAndRefresh={closeEnableVersioning}
modalOpen={enableVersioningOpen}
selectedBucket={bucketName}
versioningCurrentState={isVersioned}
/>
)}
{deleteReplicationModal && (
<DeleteReplicationRule
deleteOpen={deleteReplicationModal}
selectedBucket={bucketName}
closeDeleteModalAndRefresh={closeReplicationModalDelete}
ruleToDelete={selectedRRule}
/>
)}
<PageHeader label={`Bucket > ${match.params["bucketName"]}`} />
<Grid container>
<Grid item xs={12} className={classes.container}>
<Grid item xs={12}>
<Grid container spacing={2}>
<Grid item>
<Paper className={classes.fixedHeight}>
<Grid container direction="row" alignItems="center">
<Grid item className={classes.icon}>
<UsageIcon />
</Grid>
<Grid item>
<Typography className={classes.elementTitle}>
Reported Usage
</Typography>
</Grid>
</Grid>
<Typography className={classes.consumptionValue}>
{niceBytes(bucketSize)}
</Typography>
</Paper>
</Grid>
<Grid item>
<Paper className={classes.paperContainer}>
<div className={classes.gridContainer}>
<div>Access Policy:</div>
<div className={classes.capitalizeFirst}>
{loadingBucket ? (
<CircularProgress
color="primary"
size={16}
variant="indeterminate"
/>
) : (
accessPolicy.toLowerCase()
)}
<IconButton
color="primary"
aria-label="access"
size="small"
className={classes.propertiesIcon}
onClick={setBucketVersioning}
>
<PencilIcon active={true} />
</IconButton>
</div>
<div>Replication:</div>
<div className={classes.doubleElement}>
<span>{replicationRules.length ? "Yes" : "No"}</span>
</div>
{!hasObjectLocking && (
<Fragment>
<div>Object Locking:</div>
<div>No</div>
</Fragment>
)}
<div>Encryption:</div>
<div>
<Checkbox
color="primary"
className={classes.encCheckbox}
inputProps={{
"aria-label": "secondary checkbox",
}}
onChange={(event) => handleEncryptionCheckbox(event)}
checked={encryptionEnabled}
/>
</div>
</div>
{hasObjectLocking && (
<div className={classes.gridContainer}>
<div>Object Locking</div>
<div></div>
<div>Versioning:</div>
<div>
{loadingVersioning ? (
<CircularProgress
color="primary"
size={16}
variant="indeterminate"
/>
) : (
<Fragment>
{isVersioned && !loadingVersioning ? "Yes" : "No"}
&nbsp;
<IconButton
color="primary"
aria-label="retention"
size="small"
className={classes.propertiesIcon}
onClick={() => {
setAccessPolicyScreenOpen(true);
}}
>
<PencilIcon active={true} />
</IconButton>
</Fragment>
)}
</div>
<div>Retention:</div>
<div>
{loadingVersioning ? (
<CircularProgress
color="primary"
size={16}
variant="indeterminate"
/>
) : (
<Fragment>
&nbsp;
<IconButton
color="primary"
aria-label="retention"
size="small"
className={classes.propertiesIcon}
onClick={() => {
setRetentionConfigOpen(true);
}}
>
<PencilIcon active={true} />
</IconButton>
</Fragment>
)}
</div>
</div>
)}
</Paper>
</Grid>
</Grid>
</Grid>
<Grid item xs={12}>
<br />
</Grid>
<Grid container item xs={12}>
<Grid item xs={6}>
<Tabs
value={curTab}
onChange={(e: React.ChangeEvent<{}>, newValue: number) => {
setCurTab(newValue);
}}
indicatorColor="primary"
textColor="primary"
aria-label="cluster-tabs"
>
<Tab label="Events" {...a11yProps(0)} />
{canGetReplication && (
<Tab label="Replication" {...a11yProps(1)} />
)}
<Tab label="Policies" {...a11yProps(2)} />
<Tab label="Users" {...a11yProps(3)} />
</Tabs>
</Grid>
<Grid item xs={6} className={classes.actionsTray}>
{curTab === 0 && (
<Button
variant="contained"
color="primary"
startIcon={<CreateIcon />}
size="medium"
onClick={() => {
setAddScreenOpen(true);
}}
>
Subscribe to Event
</Button>
)}
{curTab === 1 && (
<Fragment>
{canPutReplication && (
<Button
variant="contained"
color="primary"
startIcon={<CreateIcon />}
size="medium"
onClick={() => {
setOpenReplicationOpen(true);
}}
>
Add Replication Rule
</Button>
)}
</Fragment>
)}
</Grid>
</Grid>
<Grid item xs={12}>
<TabPanel index={0} value={curTab}>
<TableWrapper
itemActions={tableActions}
columns={[
{ label: "SQS", elementKey: "arn" },
{
label: "Events",
elementKey: "events",
renderFunction: eventsDisplay,
},
{ label: "Prefix", elementKey: "prefix" },
{ label: "Suffix", elementKey: "suffix" },
]}
isLoading={loadingEvents}
records={records}
entityName="Events"
idField="id"
/>
</TabPanel>
{canGetReplication && (
<TabPanel index={1} value={curTab}>
<TableWrapper
itemActions={replicationTableActions}
columns={[
{ label: "ID", elementKey: "id" },
{
label: "Priority",
elementKey: "priority",
},
{
label: "Destination",
elementKey: "destination",
renderFunction: ruleDestDisplay,
},
{
label: "Delete Marker Replication",
elementKey: "delete_marker_replication",
renderFunction: ruleDelDisplay,
},
{ label: "Status", elementKey: "status" },
]}
isLoading={loadingEvents}
records={replicationRules}
entityName="Replication Rules"
idField="id"
/>
</TabPanel>
)}
<TabPanel index={2} value={curTab}>
<TableWrapper
itemActions={PolicyActions}
columns={[{ label: "Name", elementKey: "name" }]}
isLoading={loadingEvents}
records={bucketPolicy}
entityName="Policies"
idField="name"
/>
</TabPanel>
<TabPanel index={3} value={curTab}>
<TableWrapper
columns={[{ label: "User", elementKey: "accessKey" }]}
isLoading={loadingUsers}
records={bucketUsers}
entityName="Users"
idField="accessKey"
/>
</TabPanel>
</Grid>
</Grid>
</Grid>
</Fragment>
);
};
const connector = connect(null, {
setErrorSnackMessage,
});
export default withStyles(styles)(connector(ViewBucket));

View File

@@ -27,6 +27,7 @@ export const ADD_BUCKET_RETENTION = "ADD_BUCKET_RETENTION";
export const ADD_BUCKET_RETENTION_MODE = "ADD_BUCKET_RETENTION_MODE";
export const ADD_BUCKET_RETENTION_UNIT = "ADD_BUCKET_RETENTION_UNIT";
export const ADD_BUCKET_RETENTION_VALIDITY = "ADD_BUCKET_RETENTION_VALIDITY";
export const BUCKET_DETAILS_SET_TAB = "BUCKET_DETAILS/SET_TAB";
interface AddBucketOpenAction {
type: typeof ADD_BUCKET_OPEN;
@@ -90,6 +91,11 @@ interface AddBucketRetentionValidityAction {
retentionValidity: number;
}
interface SetBucketDetailsTab {
type: typeof BUCKET_DETAILS_SET_TAB;
tab: string;
}
export type BucketActionTypes =
| AddBucketOpenAction
| AddBucketNameAction
@@ -103,7 +109,8 @@ export type BucketActionTypes =
| AddBucketRetentionAction
| AddBucketRetentionModeAction
| AddBucketRetentionUnitAction
| AddBucketRetentionValidityAction;
| AddBucketRetentionValidityAction
| SetBucketDetailsTab;
export function addBucketOpen(open: boolean) {
return {
@@ -193,3 +200,10 @@ export function addBucketRetentionValidity(validity: number) {
retentionValidity: validity,
};
}
export function setBucketDetailsTab(tab: string) {
return {
type: BUCKET_DETAILS_SET_TAB,
tab,
};
}

View File

@@ -29,6 +29,7 @@ import {
ADD_BUCKET_RETENTION_VALIDITY,
BucketActionTypes,
ADD_BUCKET_LOCKING,
BUCKET_DETAILS_SET_TAB,
} from "./actions";
export interface BucketsState {
@@ -44,6 +45,11 @@ export interface BucketsState {
addBucketRetentionMode: string;
addBucketRetentionUnit: string;
addBucketRetentionValidity: number;
bucketDetails: BucketDetailsState;
}
export interface BucketDetailsState {
selectedTab: string;
}
const initialState: BucketsState = {
@@ -59,6 +65,9 @@ const initialState: BucketsState = {
addBucketRetentionMode: "compliance",
addBucketRetentionUnit: "days",
addBucketRetentionValidity: 1,
bucketDetails: {
selectedTab: "summary",
},
};
export function bucketsReducer(
@@ -126,7 +135,14 @@ export function bucketsReducer(
...state,
addBucketRetentionValidity: action.retentionValidity,
};
case BUCKET_DETAILS_SET_TAB:
return {
...state,
bucketDetails: {
...state.bucketDetails,
selectedTab: action.tab,
},
};
case ADD_BUCKET_RESET:
return {
...state,

View File

@@ -73,8 +73,13 @@ export interface BucketReplicationRule {
id: string;
status: string;
priority: number;
delete_marker_replication: BucketReplicationRuleDeleteMarker;
delete_marker_replication: boolean;
deletes_replication: boolean;
metadata_replication: boolean;
prefix?: string;
tags?: string;
Destination: BucketReplicationDestination;
syncMode: string;
}
export interface BucketReplication {
@@ -142,3 +147,23 @@ export interface BulkReplicationItem {
originBucket: string;
targetBucket: string;
}
interface IExpirationLifecycle {
days: number;
date: string;
}
interface ITransitionLifecycle {
days: number;
date: string;
storage_class?: string;
}
export interface LifeCycleItem {
id: string;
prefix?: string;
expiration?: IExpirationLifecycle;
transition?: ITransitionLifecycle;
tags?: any;
status?: string;
}

View File

@@ -31,6 +31,10 @@ const styles = (theme: Theme) =>
buttonContainer: {
textAlign: "right",
},
credentialsPanel: {
overflowY: "auto",
maxHeight: 350,
},
});
interface ICredentialsPromptProps {
@@ -84,16 +88,31 @@ const CredentialsPrompt = ({
A new {entity} has been created with the following details:
{consoleCreds && (
<React.Fragment>
<Grid item xs={12}>
<Grid item xs={12} className={classes.credentialsPanel}>
<strong>Console Credentials</strong>
<ul>
<li>
<b>Access Key:</b> {consoleCreds.accessKey}
</li>
<li>
<b>Secret Key:</b> {consoleCreds.secretKey}
</li>
</ul>
{Array.isArray(consoleCreds) &&
consoleCreds.map((credentialsPair, index) => {
return (
<ul key={`creds-item-${index.toString()}`}>
<li>
<b>Access Key:</b> {credentialsPair.accessKey}
</li>
<li>
<b>Secret Key:</b> {credentialsPair.secretKey}
</li>
</ul>
);
})}
{!Array.isArray(consoleCreds) && (
<ul>
<li>
<b>Access Key:</b> {consoleCreds.accessKey}
</li>
<li>
<b>Secret Key:</b> {consoleCreds.secretKey}
</li>
</ul>
)}
</Grid>
</React.Fragment>
)}
@@ -112,12 +131,27 @@ const CredentialsPrompt = ({
let consoleExtras = {};
if (consoleCreds) {
consoleExtras = {
console: {
access_key: consoleCreds.accessKey,
secret_key: consoleCreds.secretKey,
},
};
if (!Array.isArray(consoleCreds)) {
consoleExtras = {
console: [
{
access_key: consoleCreds.accessKey,
secret_key: consoleCreds.secretKey,
},
],
};
} else {
const cCreds = consoleCreds.map((itemMap) => {
return {
access_key: itemMap.accessKey,
secret_key: itemMap.secretKey,
};
});
consoleExtras = {
console: [...cCreds],
};
}
}
download(

Some files were not shown because too many files have changed in this diff Show More