Compare commits

...

147 Commits

Author SHA1 Message Date
Minio Trusted
6a96ec8177 use .Tag instead of .Version to have consistent naming 2021-01-19 02:09:40 -08:00
Minio Trusted
85398eec53 add v prefix for container {version} 2021-01-19 00:46:15 -08:00
Minio Trusted
e7f220b069 fix: update goreleaser and docker 2021-01-18 17:53:05 -08:00
Alex
1bb7658294 Updated assets file (#562)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2021-01-18 15:18:26 -08:00
Cesar N
39b7b3292a Fix retention date on object UI (#556)
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2021-01-18 14:25:03 -08:00
Alex
38cf606371 Added validation to Log Search module (#561)
Added validation to Log Search module so we can hide the log search option when API is not available

Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2021-01-18 14:05:49 -08:00
Daniel Valdivia
5e3f9acff9 API Resource Quota return all storage classes if no quota is set for a namespace (#560) 2021-01-18 13:16:30 -08:00
Alex
2305c0563a Added error notifications to console (#557)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2021-01-15 20:32:39 -08:00
Cesar N
b5a3398a69 Allow arbitrary number of file uploads (#554)
Parameter definition for file upload on swagger.yaml was removed
since go-swagger doesn't support multiple upload of files. Implementation
was done instead on  user_objects.go file.

Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2021-01-15 15:46:07 -08:00
Daniel Valdivia
c787110e17 Default kustomize without operator (#555) 2021-01-15 15:23:25 -08:00
Cesar N
1a83797a86 Add more doc details on UI (#552) 2021-01-14 10:02:16 -08:00
Daniel Valdivia
68e0f1d6a2 Determine schema for console endpoint (#550)
* Determine schema for console endpoint

* Simplify check

* Differenciate Schema
2021-01-13 13:24:30 -08:00
Lenin Alevski
2d3a3c396c TLS certificates configuration for tenant (#540)
- Update Create Tenant Wizard to support configuring multiple TLS Certificates
- Enable support for both autocert and custom certs when creating a tenant

Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2021-01-13 13:01:42 -08:00
Cesar N
d6aceb5430 Add get healthInfo api using websockets (#543)
Integrate also HealthInfo API with Console UI
2021-01-13 12:43:34 -08:00
Alex
1c109769df Implemented Log Search API & Prometheus functionality (#549)
Implemented Log Search API & Prometheus functionality in console, also fixed minor issues in all the platform

Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2021-01-13 12:08:32 -08:00
Lenin Alevski
f3bcfc327d Product license verification in Console (#518)
Operator UI - Provide and store License key
- New License section in Operator UI will allow user to provide the
  license key via input form
- New License section in Operator UI will allow the user to fetch the
  license key using subnet credentials
-  Console backend has to verify provided license is valid -
   https://godoc.org/github.com/minio/minio/pkg/licverifier#example-package
-  Console backend has to store the license key in k8s secrets

Operator UI - Set license to tenant during provisioning
- Check if license key exists in k8s secret during tenant creation
- If License is present attach the license-key jwt to the new console
tenant via an environment variable

Operator UI - Set license for an existing tenant
- Tenant view will display information about the current status of the
  Tenant License
- If Tenant doesn't have a License then Operator-UI will allow to attach
new license by clicking the Add License button
- Console backend will extract the license from the k8s secret and save
the license-key jwt in the tenant console environment variable and
redeploy
2021-01-12 13:55:07 -08:00
Cesar N
fd779c2ffa Fix Group modal typos (#546) 2021-01-08 16:12:02 -08:00
Lenin Alevski
58903e8337 Remove use of Privileged Credentials (#535)
- Leverage on MinIO Oauth integration instead of the 
  current Console implementation
- Refactor pkg/idp
- Added tests to login
2021-01-07 11:49:56 -08:00
Alex
5b98bb8fd6 Added loader state change to ensure that folder (#542)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2021-01-05 15:05:25 -08:00
Cesar N
c98d5c06d0 Update assets to show latest UI changes (#538) 2021-01-04 19:21:36 -06:00
Daniel Valdivia
33c979783d Consolidate New Prompt Credentials - Subnet #1441 (#537) 2020-12-30 00:00:47 -08:00
Harshavardhana
eeb95b2bf6 turn-off internode in trace console (#536) 2020-12-29 15:07:37 -08:00
Alex
e5c96a0787 Fixed class override issue (#533) 2020-12-21 17:37:51 -06:00
Cesar N
e3c6e22b4e Update to latest minio version and fix updates (#530) 2020-12-21 15:11:46 -08:00
Lenin Alevski
9789ec36db add warning when active directory has insecure connection (#524)
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-12-21 09:42:39 -08:00
Cesar N
51ba86fa46 Add progress bar on UI (#526) 2020-12-18 15:40:03 -08:00
Cesar N
f5922bb68b Update to latest minio-go (#523) 2020-12-16 22:02:33 -06:00
Lenin Alevski
40812fc086 Fixing small typo during login error (#522) 2020-12-16 12:41:27 -08:00
Lenin Alevski
8b34b81a61 Add description to autocert and custom certificates in tenant create wizard (#521)
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-12-16 09:24:30 -08:00
Daniel Valdivia
04e1c4573f Remove Duplicate Definitions on Swagger (#519)
Co-authored-by: Cesar N <ces.nietor@gmail.com>
2020-12-16 08:14:08 -08:00
Cesar N
d7de170105 Add Get Bucket Retention Config Api (#520) 2020-12-15 19:25:43 -06:00
Alex
369ae9342e Added EC Parity correct values to add tenant modal (#517)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-12-15 11:54:12 -08:00
Cesar N
2b1d17e38f Integrate Set Retention Config on existing Bucket in UI (#515) 2020-12-15 10:44:53 -06:00
Cesar N
d5c01fcd7d Integrate retention option during bucket creation on UI (#509) 2020-12-14 17:31:37 -06:00
Daniel Valdivia
d97d18ebab Introduce ErrorBlock component to display error text (#514) 2020-12-14 12:56:56 -08:00
dependabot[bot]
aa2714d118 Bump ini from 1.3.5 to 1.3.8 in /portal-ui (#511)
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-12-14 12:56:42 -08:00
Daniel Valdivia
06f259f190 Run React Tests (#508)
Co-authored-by: Cesar N <ces.nietor@gmail.com>
2020-12-14 12:10:37 -08:00
Daniel Valdivia
77e74917ca Fix all react warnings (#507) 2020-12-14 11:47:54 -08:00
Daniel Valdivia
d582cc96b7 Update README screenshots (#510)
Co-authored-by: Cesar N <ces.nietor@gmail.com>
2020-12-11 19:22:02 -08:00
Alex
0288215fbb Added padding to error message in login screen (#506)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
Co-authored-by: Cesar N <ces.nietor@gmail.com>
2020-12-11 18:30:42 -08:00
Alex
d3e84e5824 Added notification for delete object (#505) 2020-12-11 19:12:21 -06:00
Cesar N
dd91c793e2 Add retention option on bucket creation (#504)
This also deletes a bucket if it was created and an error occurred
2020-12-11 10:22:25 -06:00
Daniel Valdivia
b495148a69 Set Operator Logo for Operator Mode (#503) 2020-12-10 21:49:20 -08:00
Daniel Valdivia
e0f3e4513d Replace IDP with Identity Provieder (#502) 2020-12-10 21:19:29 -08:00
Alex
6512a51119 Moved notifications lambda pages to settings (#496) 2020-12-10 13:59:45 -06:00
Cesar N
90c54221d6 Add confirmation input on tenant deletion (#495)
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-12-09 23:22:18 -08:00
Alex
3f023f9771 First set of changes for settings pages new design (#493)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2020-12-09 20:06:14 -08:00
Cesar N
a4ad341a18 Bring trace, watch, heal and logs back to user console UI (#491) 2020-12-09 15:10:39 -08:00
Daniel Valdivia
2d6f949359 Fix bad import on Console TSX (#494)
Also fixing some linting problems
2020-12-09 10:31:01 -08:00
Lenin Alevski
7577703d64 Fix operator login acl regression (#492)
* Fix operator login acl regression

* wip
2020-12-08 20:10:43 -08:00
Daniel Valdivia
b24d62a695 Refactor React Classes to Functions (#483) 2020-12-08 12:31:04 -06:00
Cesar N
e541446631 Remove size and date from folder list item (#484) 2020-12-07 18:22:07 -06:00
Lenin Alevski
e2d86354fc Change Password support for Console (#457)
- Account change password endpoints
- Change account password modal
- Grouped account settings and service accounts
- Removed the SuperAdmin credentials from almost all places, only
  missing place is Oauth login
- Renamed service-accounts UI labels to account in Menu

Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-12-07 15:11:08 -08:00
Daniel Valdivia
1ce18043d5 Disable Auto Complete for Operator Console (#482) 2020-12-07 13:34:43 -08:00
Lenin Alevski
4005c20f7e Remove TLS skip verify in wss/watch endpoint (#472)
* Move heal and watch to tenant details view on operator-ui

* TLS skip verify in wss/watch endpoint

Use insecure: true in the meantime so the wss/watch endpoint works while
we add support for custotm TLS transport in the S3 client library.

Removed "InsecureSkipVerify: true" from s3AdminClient and s3Client HTTP clients

- We preserve the insecure parameter in the  `newS3Config` and  `NewAdminClientWithInsecure` functions for debugging and testing purposes.
- By default InsecureSkipVerify is false, therefore in order for Operator-Console to verify the TLS connections to MinIO tenants with self-signed certificates it requires the `ca.crt` or the `public.crt` of the tenant to exists under `~/.console/certs/CAs` which is the right way to do it.

Co-authored-by: Cesar Nieto <ces.nietor@gmail.com>
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-12-07 11:49:00 -08:00
Alex
5bcf245ed9 Added Edit minio image functionality (#474)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
Co-authored-by: Cesar N <ces.nietor@gmail.com>
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-12-07 11:27:16 -08:00
Nitish Tiwari
402e07c844 Remove alpine base and use UBI as the default base image (#480)
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-12-07 10:53:24 -08:00
Alex
8404baecd8 Removed unused pagination items (#470)
Removed unused pagination items, also updated dependencies of material-ui

Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-12-07 10:13:12 -08:00
Cesar N
3c0e3a1208 Update console to use latest operator (#476)
Main changes Rename everything from Zone->Pool
2020-12-07 07:49:51 -08:00
Alex
cb35dcf971 Updated console to use React 17 (#469) 2020-12-04 20:05:32 -06:00
0xflotus
41418bcf45 chore: enabled syntax highlighting (#471) 2020-12-04 16:17:30 -06:00
Harshavardhana
132b08b40e import minio/pkg/certs as xcerts (#473)
update dependency to fix windows cert issues,
now handled properly by the pkg/certs package
in MinIO.
2020-12-04 15:42:12 -06:00
Alex
dbbaae78f7 Added tenant usage indicator (#454) 2020-12-03 17:51:03 -06:00
Alex
585780d415 Connected retention policy modal (#437) 2020-12-03 16:21:44 -06:00
Cesar N
44b9979f02 Add api to set object lock config on a bucket (#463) 2020-12-03 13:45:45 -06:00
Cesar N
0749c87ce7 Set prometheus to always enabled on tenant creation (#464) 2020-12-03 12:59:35 -06:00
Cesar N
e5f7059a5e Rename none option on idp step to Built In on Tenant Creation (#465) 2020-12-03 12:15:41 -06:00
Cesar N
d15472f417 Fix object download (#466)
If an object is within a folder the object downloaded now only has the object's name.
Also, it now supports object version downloading.
2020-12-03 11:37:53 -06:00
Nitish Tiwari
726bfe623c Add Dockerfile based on Red Hat UBI (#453) 2020-12-03 00:54:40 -08:00
Cesar N
e47a57af8c Add custom registry on tenant creation (#455) 2020-12-02 15:27:47 -06:00
Harshavardhana
f673f17407 update deps for minio/minio and minio/mc (#458) 2020-12-01 23:48:34 -08:00
Cesar N
829833f242 Add set policy to multiple user/groups (#382) 2020-11-30 17:23:14 -06:00
Lenin Alevski
94c3ade7fc Adding context timeout to login and get location operations (#432) 2020-11-30 16:24:30 -06:00
Cesar N
4a27ef4b2c Move heal and watch to tenant details view on operator-ui (#449)
Use insecure: true in the meantime so the wss/watch endpoint works while
we add support for custotm TLS transport in the S3 client library.
Removed "InsecureSkipVerify: true" from s3AdminClient and s3Client HTTP clients
2020-11-30 14:41:58 -06:00
Lenin Alevski
59b43884ff Create Tenant TLS refactor (#450)
- fixed small bug in which RequestAutoCert was not setting properly
- support AutoCert and external certificates on Tenant creation
2020-11-30 14:08:13 -06:00
Alex
219fe55356 Predefined list (#452)
Added predefined list component
2020-11-30 11:27:37 -06:00
Alex
9136c2a167 Fixed object lock (#445) 2020-11-25 10:40:39 -08:00
Alex
114bc364e3 Connected Share object modal (#440) 2020-11-24 18:56:32 -08:00
Alex
2caad9964f Added legal hold modal (#436) 2020-11-24 16:39:16 -08:00
Minio Trusted
d573007747 update console to v0.4.6 2020-11-24 14:00:52 -08:00
Lenin Alevski
f054b1c251 Ensure GetConsoleSTSClient() is used correctly (#425) 2020-11-20 13:50:35 -08:00
Lenin Alevski
7a2358272a Get LDAP identity for console access/secret keys (#398)
- If MinIO is configured with LDAP then users and groups are external, and
  the credentials provided in the CONSOLE_ACCESS_KEY and
  CONSOLE_SECRET_KEY env vars will belong to an existing user in the active
  directory, therefore we need to authenticate first with
  `credentials.NewLDAPIdentity`
- Fixed race condition bug in which TLS RootCAs certs were not loading
  correctly (certPool was always null)
- Fixed TLS bug in which if Console was deployed without TLS enabled
  RootCAs certs were not loading
- Initialize LDAP Admin credentials once
- Initialize stsClient once
2020-11-20 11:52:34 -08:00
Alex
8a6a75b7a2 Connected object tags API (#421)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2020-11-19 21:30:33 -08:00
Cesar N
8cf678fb27 Replace mc with latest mc on go mod (#424) 2020-11-19 15:23:31 -08:00
Cesar N
a20c6dc907 Add download version object on download api (#423) 2020-11-19 15:04:13 -08:00
Daniel Valdivia
37ff8bb60d Fix Tenant Details header (#420)
Also renames zones to servers
2020-11-19 11:45:30 -08:00
Lenin Alevski
b6ac055857 Show error message if not possible to create CAs folder (#407)
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-11-18 22:46:54 -08:00
Cesar N
12e53a1468 Remove minio root credentials from CreateTenant response (#402)
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-11-18 16:16:06 -08:00
Alex
b21123e1cd Connected delete & download buttons for object details (#399)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-11-18 16:06:34 -08:00
Lenin Alevski
f1db949abc Fixes Console issue #400 (#401)
Previously cookie path was set to Path="/api", this was a performance
improvement to tell the browser to send the cookie only to request with
that prefix, however also consume endpoints on Path="/ws", since rfc6265
doesnt support multiple paths or regular expressions in the path field
of a cookie we are back to use Path="/" which means send the cookie to
all request under the current domain.

Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-11-18 14:42:02 -08:00
Alex
761c6529a2 Fixed issue with back arrows & navigation in object browser (#397)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2020-11-17 22:05:46 -08:00
Alex
1f832fa294 Connected Object details page to navigation (#394)
Connected Object details page to navigation schema. Also connected file details view with backend

Co-authored-by: Kaan Kabalak <kaan@minio.io>
2020-11-17 13:03:50 -08:00
Lenin Alevski
be569aee4f Support for Cookie authentication (#390)
- Added support for cookie authentication (authorization header will have priority)
- Removed local storage token management from UI
- cookie hardening (sameSite, httpOnly, secure)
- login endpoint sets cookie via header, logout endpoint expires cookie
- Refactor Routes and ProtectedRoutes components, improvement on the way
  application check if user session is valid

Future improvements

- look for all places in backend that returns 401 unauthorized, and destroy session there (not a priority since cookie its invalid anyway)
- Downloading objects in object browser can be simplified since is just a GET request and users will be authenticated via Cookies, no need to craft additional requests
2020-11-13 16:26:03 -08:00
Minio Trusted
419e94ccec update to v0.4.5 2020-11-13 11:10:13 -08:00
Alex
12bc5265b8 Fixed issue with object browser icons & long names (#389)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-11-12 14:33:56 -08:00
Kaan Kabalak
32898f0c57 Edit Searchbar styling based on mockups (#385)
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-11-12 12:05:40 -08:00
Kaan Kabalak
125c9abf56 Adjust Modal form clear button font based on mockups (#384)
The font of the clear button for Modal forms were 'sans-serif' instead
of being 'Lato' as specified in the mockups.

Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-11-12 10:28:49 -08:00
Alex
bc27db4a69 Migrated tablewrapper to use react-virtualized (#387)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2020-11-11 20:14:48 -08:00
Kaan Kabalak
dd8e2b13d3 Add disabled functionality and fix styling for RadioGroupSelector (#383)
* Adjust RadioGroupSelector label styling based on mockups

* Add disabled support for Radio Group Selector options
2020-11-10 18:59:21 -08:00
Alex
005e3b941c Fixed issue with checkbox selection in table wrapper (#380)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2020-11-10 00:08:45 -08:00
Alex
efa614c773 Fixed default value for nulls in browse buckets (#379)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2020-11-06 16:47:07 -08:00
Minio Trusted
63350e5492 update to v0.4.4 2020-11-05 18:07:46 -08:00
Alex
255c128b67 Fixed pagination un buckets lists (#371)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-11-05 10:16:03 -08:00
Cesar N
06f333395e Move trace and logs UI to Operator Console (#375)
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-11-04 21:45:48 -08:00
Alex
3cd024ea2c Changed sizes for main container & table paper (#377)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-11-04 16:36:51 -08:00
Alex
9c0a407db6 Fixed page refresh on buckets creation (#372)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2020-11-04 15:25:36 -08:00
Alex
dc3c619f3f Added animation & disabled button / fields on sending (#369)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2020-11-03 11:12:41 -08:00
Alex
5000aafba6 Added functionality for create folder & replaced icons (#368)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2020-11-02 21:45:47 -08:00
Cesar N
b9f2a39d50 Fix tenant creation (#363)
Memory size request was not being sent, hence the tenant was not being created.
2020-11-02 11:03:40 -08:00
Daniel Valdivia
df321191f4 Build assets inside the container (#357) 2020-11-01 07:34:37 -08:00
Alex
547eb41e96 Added navigation to object browser (#358)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-10-31 00:22:46 -07:00
Lenin Alevski
afbb83e081 certs-dir value was ignored because of wrong variable assigning (#362) 2020-10-30 22:36:52 -07:00
Lenin Alevski
b599968570 SNI support for Console (#352)
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-10-29 22:26:48 -07:00
Cesar N
24cc60f34e Add put object api and add list object improvements (#356) 2020-10-28 16:08:26 -07:00
Alex
f967058409 Updated Heal section (#351)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2020-10-27 21:06:24 -07:00
Alex
078e09ba76 Fixed inconsistences in create tenant modal (#349)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-10-27 12:43:12 -07:00
Lenin Alevski
d6f97841d4 return generic login error when invalid credentials (#350) 2020-10-27 10:05:16 -07:00
Lenin Alevski
619ac124b3 Bucket encryption checkbox and endpoints for Console (#343)
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-10-25 12:56:23 -07:00
Alex
a2180e123d Removed warnings on console (#345)
For Operator modules this will be removed after upgrading component to use redux/formik

Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2020-10-24 00:05:26 -07:00
Cesar N
0325bb7e2d Add put object retention api (#340) 2020-10-23 15:04:02 -07:00
Minio Trusted
fce361e5bd update to v0.4.3 2020-10-23 02:15:25 -07:00
Alex
ed6d6e8b9d Fixed audit issues (#342)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2020-10-23 02:03:49 -07:00
Alex
406709f66b Updated Watch view to have console consistent styles (#341)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-10-22 17:15:40 -07:00
Cesar N
3ac45a2211 Add Set object's legalhold status api (#339)
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-10-22 16:23:29 -07:00
Minio Trusted
716f886780 update to v0.4.2 2020-10-22 15:35:17 -07:00
Alex
4ef498f0c3 Updated Logs page to be more consistent with current styles (#338)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2020-10-22 12:08:36 -07:00
Alex
5e764e61ba Changed trace view to be a table (#337)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-10-22 11:27:24 -07:00
Cesar N
1466632fd6 Add share object api (#335) 2020-10-22 11:18:27 -07:00
Lenin Alevski
0c43e5c3f4 React Router fixes for Console (#336)
- Adding protectedRoute component
- Removed unnecessary redirect login
2020-10-21 13:13:40 -07:00
Alex
7e9d581277 Updated styles & behavior for settings page (#334)
Updated styles & behavior for settings page, also implemented a couple of performance improvements on some fields

Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2020-10-20 16:31:08 -07:00
Cesar N
c928972137 Change Users label to Tenants on Tenants Page (#330) 2020-10-20 11:24:52 -07:00
Daniel Valdivia
78884e3806 Make logs, trace and watch have fixed height (#333) 2020-10-20 09:06:23 -07:00
Lenin Alevski
f6ac7e047e Invalidate console session when minio user doesn't exists (#332) 2020-10-19 15:32:21 -07:00
Alex
e1fdf3fb28 Modals UI style changes (#331)
Implements new input styles & adjusts information on modal boxes for console.

Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2020-10-19 11:27:54 -07:00
Cesar N
e4510cbc18 Add upload api and integrate it with object browser on UI (#327) 2020-10-14 23:09:33 -07:00
Minio Trusted
2c14142e19 update to v0.4.1 2020-10-12 20:37:21 -07:00
Kaan Kabalak
1caa3f2ce8 Implement License page (#324)
* Implement License page

Fixes #320

* License Assets

* Fix endpoint tests

Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-10-12 11:56:15 -07:00
Alex
6501a4b13f First set of Modal style changes (#322)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2020-10-09 12:01:24 -07:00
Daniel Valdivia
2f51621e69 Get Tenant Secret From Tenant CR (#323)
We were assuming the Tenant Credentials Secret instead of reading it from it's .spec.credsSecret this commit addresses that
2020-10-09 11:51:02 -07:00
Cesar N
7e6e64c729 Add download objects api and integrate it with UI (#321) 2020-10-09 11:43:15 -07:00
Kaan Kabalak
9007c7dd14 Consolidate Remote Buckets and Replication modals (#317)
* Consolidate Remote Buckets and Replication modals

This commit consolidates Remote Buckets and Replication modals into a
single modal in the Add Replication Rule modal located in the Buckets
section

Fixes #301

* Remove Remote Buckets section

* Properly align tabs and button on Buckets page
2020-10-08 09:55:31 -07:00
Alex
850fd3e371 Changed buttons & search boxes styles (#318)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2020-10-06 21:37:13 -07:00
Daniel Valdivia
6d8f1c439e Handle Invalid User error coming from madmin (#314)
Right now we display `Internal Server Error` when invalid credentials are presneted, this makes it so we only present `Unauthorized`
2020-10-06 16:45:26 -07:00
Alex
7166717688 Changed styles for Login page (#316)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-10-06 16:37:25 -07:00
Cesar N
f91346dc5b Add retention mode and legal hold mode on list objects api (#312)
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-10-06 16:07:33 -07:00
Alex
dccdfb5533 Customization of Dashboard page & improved some styles (#315)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2020-10-05 21:30:52 -07:00
Daniel Valdivia
4f065bdedf Change Menu Order. (#313) 2020-10-05 20:48:10 -07:00
459 changed files with 44123 additions and 33655 deletions

View File

@@ -4,3 +4,4 @@ target/
console
!console/
portal-ui/node_modules/
.git/

View File

@@ -14,7 +14,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
go-version: [1.14.x]
go-version: [1.15.x]
os: [ubuntu-latest]
steps:
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
@@ -33,4 +33,5 @@ jobs:
run: |
make verifiers
make test
make crosscompile
make console

15
.github/workflows/react.yml vendored Normal file
View File

@@ -0,0 +1,15 @@
name: "React Tests"
on:
push:
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install modules
working-directory: ./portal-ui
run: yarn
- name: Run tests
working-directory: ./portal-ui
run: yarn test

5
.gitignore vendored
View File

@@ -24,6 +24,11 @@ console
dist/
# Ignore node_modules
portal-ui/node_modules/
portal-ui/build/
# Ignore tls cert and key
private.key
public.crt

View File

@@ -3,10 +3,12 @@
project_name: console
release:
name_template: "Version {{.Version}}"
name_template: "Release version {{.Version}}"
github:
owner: minio
name: console
extra_files:
- glob: "*.minisig"
before:
hooks:
@@ -16,72 +18,58 @@ before:
builds:
-
goos:
- freebsd
- windows
- linux
- darwin
- windows
goarch:
- amd64
- ppc64le
- s390x
- arm64
ignore:
- goos: darwin
goarch: arm64
- goos: darwin
goarch: arm
- goos: darwin
goarch: ppc64le
- goos: darwin
goarch: s390x
- goos: windows
goarch: arm64
- goos: windows
goarch: arm
- goos: windows
goarch: ppc64le
- goos: windows
goarch: s390x
- goos: freebsd
goarch: arm
- goos: freebsd
goarch: arm64
- goos: freebsd
goarch: ppc64le
- goos: freebsd
goarch: s390x
env:
- CGO_ENABLED=0
main: ./cmd/console/
flags:
- -trimpath
- --tags=kqueue
ldflags:
- -s -w -X github.com/minio/console/pkg.ReleaseTag={{.Tag}} -X github.com/minio/console/pkg.CommitID={{.FullCommit}} -X github.com/minio/console/pkg.Version={{.Version}} -X github.com/minio/console/pkg.ShortCommitID={{.ShortCommit}} -X github.com/minio/console/pkg.ReleaseTime={{.Date}}
archives:
-
name_template: "{{ .ProjectName }}-{{ .Os }}-{{ .Arch }}"
format: binary
replacements:
darwin: Darwin
linux: Linux
windows: Windows
freebsd: FreeBSD
amd64: x86_64
format_overrides:
- goos: windows
format: zip
files:
- README.md
- LICENSE
checksum:
name_template: 'checksums.txt'
arm: arm
signs:
-
signature: "${artifact}.minisig"
cmd: "sh"
args:
- '-c'
- 'minisign -s /media/${USER}/minio/minisign.key -Sm ${artifact} < /media/${USER}/minio/minisign-passphrase'
artifacts: all
snapshot:
name_template: 'snapshot-{{ time "2006-01-02" }}'
name_template: v0.0.0@{{.ShortCommit}}
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
nfpms:
-
vendor: MinIO Inc.
@@ -92,18 +80,55 @@ nfpms:
formats:
- deb
- rpm
replacements:
darwin: Darwin
linux: Linux
freebsd: FreeBSD
amd64: x86_64
dockers:
-
# GOOS of the built binary that should be used.
goos: linux
# GOARCH of the built binary that should be used.
goarch: amd64
dockerfile: Dockerfile.release
image_templates:
- "minio/console:{{ .Tag }}"
- "minio/console:latest"
- image_templates:
- "minio/console:{{ .Tag }}-amd64"
use_buildx: true
dockerfile: Dockerfile.release
extra_files:
- LICENSE
- CREDITS
build_flag_templates:
- "--platform=linux/amd64"
- image_templates:
- "minio/console:{{ .Tag }}-ppc64le"
use_buildx: true
dockerfile: Dockerfile.release
extra_files:
- LICENSE
- CREDITS
build_flag_templates:
- "--platform=linux/ppc64le"
- image_templates:
- "minio/console:{{ .Tag }}-s390x"
use_buildx: true
dockerfile: Dockerfile.release
extra_files:
- LICENSE
- CREDITS
build_flag_templates:
- "--platform=linux/s390x"
- image_templates:
- "minio/console:{{ .Tag }}-arm64"
use_buildx: true
goarch: arm64
dockerfile: Dockerfile.release
extra_files:
- LICENSE
- CREDITS
build_flag_templates:
- "--platform=linux/arm64"
docker_manifests:
- name_template: minio/console:{{ .Tag }}
image_templates:
- minio/console:{{ .Tag }}-amd64
- minio/console:{{ .Tag }}-arm64
- minio/console:{{ .Tag }}-ppc64le
- minio/console:{{ .Tag }}-s390x
- name_template: minio/console:latest
image_templates:
- minio/console:{{ .Tag }}-amd64
- minio/console:{{ .Tag }}-arm64
- minio/console:{{ .Tag }}-ppc64le
- minio/console:{{ .Tag }}-s390x

View File

@@ -11,40 +11,7 @@ $ docker run --rm -p 389:389 -p 636:636 --name my-openldap-container --detach os
Run the `billy.ldif` file using `ldapadd` command to create a new user and assign it to a group.
```
$ cat > billy.ldif << EOF
# LDIF fragment to create group branch under root
dn: uid=billy,dc=example,dc=org
uid: billy
cn: billy
sn: 3
objectClass: top
objectClass: posixAccount
objectClass: inetOrgPerson
loginShell: /bin/bash
homeDirectory: /home/billy
uidNumber: 14583102
gidNumber: 14564100
userPassword: {SSHA}j3lBh1Seqe4rqF1+NuWmjhvtAni1JC5A
mail: billy@example.org
gecos: Billy User
# Create base group
dn: ou=groups,dc=example,dc=org
objectclass:organizationalunit
ou: groups
description: generic groups branch
# create consoleAdmin group (this already exists on minio and have a policy of s3::*)
dn: cn=consoleAdmin,ou=groups,dc=example,dc=org
objectClass: top
objectClass: posixGroup
gidNumber: 678
# Assing group to new user
dn: cn=consoleAdmin,ou=groups,dc=example,dc=org
changetype: modify
add: memberuid
memberuid: billy
EOF
$ docker cp billy.ldif my-openldap-container:/container/service/slapd/assets/test/billy.ldif
$ docker cp console/docs/ldap/billy.ldif my-openldap-container:/container/service/slapd/assets/test/billy.ldif
$ docker exec my-openldap-container ldapadd -x -D "cn=admin,dc=example,dc=org" -w admin -f /container/service/slapd/assets/test/billy.ldif -H ldap://localhost -ZZ
```
@@ -119,9 +86,6 @@ export MINIO_IDENTITY_LDAP_SERVER_INSECURE=on
## Run Console
```
export CONSOLE_ACCESS_KEY=minio
export CONSOLE_SECRET_KEY=minio123
...
export CONSOLE_LDAP_ENABLED=on
./console server
```

View File

@@ -1,4 +1,25 @@
FROM golang:1.13
FROM golang:1.15 as binlayer
RUN go get github.com/go-bindata/go-bindata/... && go get github.com/elazarl/go-bindata-assetfs/...
FROM node:10 as uilayer
WORKDIR /app
COPY --from=binlayer /go/bin/go-bindata-assetfs /bin/
COPY --from=binlayer /go/bin/go-bindata /bin/
COPY ./portal-ui/package.json ./
COPY ./portal-ui/yarn.lock ./
RUN yarn install
COPY ./portal-ui .
RUN yarn install && make build-static
USER node
FROM golang:1.15 as golayer
RUN apt-get update -y && apt-get install -y ca-certificates
@@ -12,6 +33,8 @@ RUN go mod download
ADD . /go/src/github.com/minio/console/
WORKDIR /go/src/github.com/minio/console/
COPY --from=uilayer /app/bindata_assetfs.go /go/src/github.com/minio/console/portal-ui/bindata_assetfs.go
ENV CGO_ENABLED=0
RUN go build -ldflags "-w -s" -a -o console ./cmd/console
@@ -20,7 +43,7 @@ FROM scratch
MAINTAINER MinIO Development "dev@min.io"
EXPOSE 9090
COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=0 /go/src/github.com/minio/console/console .
COPY --from=golayer /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=golayer /go/src/github.com/minio/console/console .
ENTRYPOINT ["/console"]

20
Dockerfile.assets Normal file
View File

@@ -0,0 +1,20 @@
FROM golang:1.15 as binlayer
RUN go get github.com/go-bindata/go-bindata/... && go get github.com/elazarl/go-bindata-assetfs/...
FROM node:10 as uilayer
WORKDIR /app
COPY --from=binlayer /go/bin/go-bindata-assetfs /bin/
COPY --from=binlayer /go/bin/go-bindata /bin/
COPY ./portal-ui/package.json ./
COPY ./portal-ui/yarn.lock ./
RUN yarn install
COPY ./portal-ui .
RUN yarn install && make build-static
USER node

View File

@@ -1,12 +1,21 @@
FROM ubuntu:18.04 as certs
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3
RUN apt-get update -y && apt-get install -y ca-certificates
COPY CREDITS /licenses/CREDITS
COPY LICENSE /licenses/LICENSE
LABEL name="MinIO" \
vendor="MinIO Inc <dev@min.io>" \
maintainer="MinIO Inc <dev@min.io>" \
version="v0.5.1" \
release="v0.5.1" \
summary="A graphical user interface for MinIO" \
description="MinIO object storage is fundamentally different. Designed for performance and the S3 API, it is 100% open-source. MinIO is ideal for large, private cloud environments with stringent security requirements and delivers mission-critical availability across a diverse range of workloads."
RUN \
microdnf update --nodocs && \
microdnf install ca-certificates --nodocs
FROM scratch
MAINTAINER MinIO Development "dev@min.io"
EXPOSE 9090
COPY console /console
COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
ENTRYPOINT ["/console"]

View File

@@ -30,6 +30,9 @@ fmt:
@GO111MODULE=on gofmt -d cmd/
@GO111MODULE=on gofmt -d cluster/
crosscompile:
@(env bash $(PWD)/cross-compile.sh)
lint:
@echo "Running $@ check"
@GO111MODULE=on ${GOPATH}/bin/golangci-lint cache clean
@@ -47,7 +50,7 @@ swagger-gen:
@swagger generate server -A console --main-package=console --exclude-main -P models.Principal -f ./swagger.yml -r NOTICE
assets:
@(cd portal-ui; yarn install; make build-static; cd ..)
@(cd portal-ui; yarn install; make build-static; yarn prettier --write . --loglevel warn; cd ..)
test:
@(GO111MODULE=on go test -race -v github.com/minio/console/restapi/...)

View File

@@ -3,7 +3,7 @@
A graphical user interface for [MinIO](https://github.com/minio/minio)
| Dashboard | Adding A User |
| Dashboard | Creating a bucket |
| ------------- | ------------- |
| ![Dashboard](images/pic1.png) | ![Dashboard](images/pic2.png) |
@@ -13,7 +13,7 @@ All `console` needs is a MinIO user with admin privileges and URL pointing to yo
> Note: We don't recommend using MinIO's Operator Credentials
1. Create a user for `console` using `mc`.
```
```bash
$ set +o history
$ mc admin user add myminio console YOURCONSOLESECRET
$ set -o history
@@ -21,7 +21,7 @@ $ set -o history
2. Create a policy for `console` with access to everything (for testing and debugging)
```
```json
$ cat > consoleAdmin.json << EOF
{
"Version": "2012-10-17",
@@ -57,7 +57,7 @@ $ mc admin policy set myminio consoleAdmin user=console
### Note
Additionally, you can create policies to limit the privileges for `console` users, for example, if you want the user to only have access to dashboard, buckets, notifications and watch page, the policy should look like this:
```
```json
{
"Version": "2012-10-17",
"Statement": [{
@@ -100,26 +100,53 @@ Additionally, you can create policies to limit the privileges for `console` user
## Run Console server
To run the server:
```
export CONSOLE_HMAC_JWT_SECRET=YOURJWTSIGNINGSECRET
#required to encrypt jwet payload
```bash
# Salt to encrypt JWT payload
export CONSOLE_PBKDF_PASSPHRASE=SECRET
#required to encrypt jwet payload
export CONSOLE_PBKDF_SALT=SECRET
export CONSOLE_ACCESS_KEY=console
export CONSOLE_SECRET_KEY=YOURCONSOLESECRET
# MinIO endpoint
export CONSOLE_MINIO_SERVER=http://localhost:9000
./console server
```
## Connect Console to a Minio using TLS and a self-signed certificate
## Run Console with TLS enable
Copy your `public.crt` and `private.key` to `~/.console/certs`, then:
```bash
./console server
```
Additionally, `Console` has support for multiple certificates, clients can request them using `SNI`. It expects the following structure:
```bash
certs/
├─ public.crt
├─ private.key
├─ example.com/
│ │
│ ├─ public.crt
│ └─ private.key
└─ foobar.org/
├─ public.crt
└─ private.key
...
```
...
export CONSOLE_MINIO_SERVER_TLS_ROOT_CAS=<certificate_file_name>
Therefore, we read all filenames in the cert directory and check
for each directory whether it contains a public.crt and private.key.
## Connect Console to a Minio using TLS and a self-signed certificate
Copy the MinIO `ca.crt` under `~/.console/certs/CAs`, then:
```
export CONSOLE_MINIO_SERVER=https://localhost:9000
./console server
```

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
// This file is part of MinIO Kubernetes Cloud
// Copyright (c) 2019 MinIO, Inc.
// Copyright (c) 2020 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by

View File

@@ -1,5 +1,5 @@
// This file is part of MinIO Kubernetes Cloud
// Copyright (c) 2019 MinIO, Inc.
// Copyright (c) 2020 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -31,7 +31,6 @@ import (
var (
errCantDetermineMinIOImage = errors.New("can't determine MinIO Image")
errCantDetermineMCImage = errors.New("can't determine MC Image")
)
func GetK8sAPIServer() string {
@@ -64,13 +63,8 @@ func GetNsFromFile() string {
return string(dat)
}
// This operation will run only once at console startup
var namespace = GetNsFromFile()
// Returns the namespace in which the controller is installed
func GetNs() string {
return env.Get(ConsoleNamespace, namespace)
}
// Namespace will run only once at console startup
var Namespace = GetNsFromFile()
// getLatestMinIOImage returns the latest docker image for MinIO if found on the internet
func getLatestMinIOImage(client HTTPClientI) (*string, error) {
@@ -125,44 +119,3 @@ func GetLatestMinioImage(client HTTPClientI) (*string, error) {
}
return latestMinIOImage, nil
}
// getLatestMCImage returns the latest docker image for MC if found on the internet
func getLatestMCImage() (*string, error) {
// Create an http client with a 4 second timeout
client := http.Client{
Timeout: 4 * time.Second,
}
resp, err := client.Get("https://dl.min.io/client/mc/release/linux-amd64/")
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var re = regexp.MustCompile(`(?m)\.\/mc\.(RELEASE.*?Z)"`)
// look for a single match
matches := re.FindAllStringSubmatch(string(body), 1)
for i := range matches {
release := matches[i][1]
dockerImage := fmt.Sprintf("minio/mc:%s", release)
return &dockerImage, nil
}
return nil, errCantDetermineMCImage
}
var latestMCImage, errLatestMCImage = getLatestMCImage()
func GetMCImage() (*string, error) {
image := strings.TrimSpace(env.Get(ConsoleMCImage, ""))
// if there is a preferred image configured by the user we'll always return that
if image != "" {
return &image, nil
}
if errLatestMCImage != nil {
return nil, errLatestMCImage
}
return latestMCImage, nil
}

View File

@@ -1,5 +1,5 @@
// This file is part of MinIO Kubernetes Cloud
// Copyright (c) 2019 MinIO, Inc.
// Copyright (c) 2020 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -21,5 +21,4 @@ const (
ConsoleK8SAPIServerTLSRootCA = "CONSOLE_K8S_API_SERVER_TLS_ROOT_CA"
ConsoleMinioImage = "CONSOLE_MINIO_IMAGE"
ConsoleMCImage = "CONSOLE_MC_IMAGE"
ConsoleNamespace = "CONSOLE_NAMESPACE"
)

View File

@@ -17,6 +17,7 @@
package cluster
import (
"io"
"net/http"
)
@@ -25,6 +26,8 @@ import (
// that are used within this project.
type HTTPClientI interface {
Get(url string) (resp *http.Response, err error)
Post(url, contentType string, body io.Reader) (resp *http.Response, err error)
Do(req *http.Request) (*http.Response, error)
}
// HTTPClient Interface implementation
@@ -38,3 +41,13 @@ type HTTPClient struct {
func (c *HTTPClient) Get(url string) (resp *http.Response, err error) {
return c.Client.Get(url)
}
// Post implements http.Client.Post()
func (c *HTTPClient) Post(url, contentType string, body io.Reader) (resp *http.Response, err error) {
return c.Client.Post(url, contentType, body)
}
// Do implements http.Client.Do()
func (c *HTTPClient) Do(req *http.Request) (*http.Response, error) {
return c.Client.Do(req)
}

View File

@@ -20,10 +20,12 @@ import (
"fmt"
"log"
"os"
"path/filepath"
"github.com/go-openapi/loads"
"github.com/jessevdk/go-flags"
"github.com/minio/cli"
"github.com/minio/console/pkg/certs"
"github.com/minio/console/restapi"
"github.com/minio/console/restapi/operations"
)
@@ -56,14 +58,9 @@ var serverCmd = cli.Command{
Usage: "HTTPS server port",
},
cli.StringFlag{
Name: "tls-certificate",
Value: "",
Usage: "filename of public cert",
},
cli.StringFlag{
Name: "tls-key",
Value: "",
Usage: "filename of private key",
Name: "certs-dir",
Value: certs.GlobalCertsCADir.Get(),
Usage: "path to certs directory",
},
},
}
@@ -82,7 +79,9 @@ func startServer(ctx *cli.Context) error {
parser := flags.NewParser(server, flags.Default)
parser.ShortDescription = "MinIO Console Server"
parser.LongDescription = swaggerSpec.Spec().Info.Description
server.ConfigureFlags()
for _, optsGroup := range api.CommandLineOptionsGroups {
_, err := parser.AddGroup(optsGroup.ShortDescription, optsGroup.LongDescription, optsGroup.Options)
if err != nil {
@@ -106,12 +105,18 @@ func startServer(ctx *cli.Context) error {
restapi.Hostname = ctx.String("host")
restapi.Port = fmt.Sprintf("%v", ctx.Int("port"))
tlsCertificatePath := ctx.String("tls-certificate")
tlsCertificateKeyPath := ctx.String("tls-key")
// Set all certs and CAs directories path
certs.GlobalCertsDir, _ = certs.NewConfigDirFromCtx(ctx, "certs-dir", certs.DefaultCertsDir.Get)
certs.GlobalCertsCADir = &certs.ConfigDir{Path: filepath.Join(certs.GlobalCertsDir.Get(), certs.CertsCADir)}
if tlsCertificatePath != "" && tlsCertificateKeyPath != "" {
server.TLSCertificate = flags.Filename(tlsCertificatePath)
server.TLSCertificateKey = flags.Filename(tlsCertificateKeyPath)
// check if certs and CAs directories exists or can be created
if err := certs.MkdirAllIgnorePerm(certs.GlobalCertsCADir.Get()); err != nil {
log.Println(fmt.Sprintf("Unable to create certs CA directory at %s", certs.GlobalCertsCADir.Get()))
}
// load the certificates and the CAs
restapi.GlobalRootCAs, restapi.GlobalPublicCerts, restapi.GlobalTLSCertsManager = certs.GetAllCertificatesAndCAs()
if len(restapi.GlobalPublicCerts) > 0 {
// If TLS certificates are provided enforce the HTTPS schema, meaning console will redirect
// plain HTTP connections to HTTPS server
server.EnabledListeners = []string{"http", "https"}

34
cross-compile.sh Executable file
View File

@@ -0,0 +1,34 @@
#!/bin/bash
set -e
# Enable tracing if set.
[ -n "$BASH_XTRACEFD" ] && set -x
_init() {
## All binaries are static make sure to disable CGO.
export CGO_ENABLED=0
## List of architectures and OS to test coss compilation.
SUPPORTED_OSARCH="linux/ppc64le linux/mips64 linux/arm64 linux/s390x darwin/amd64 freebsd/amd64 windows/amd64 linux/arm linux/386 netbsd/amd64"
}
_build() {
local osarch=$1
IFS=/ read -r -a arr <<<"$osarch"
os="${arr[0]}"
arch="${arr[1]}"
package=$(go list -f '{{.ImportPath}}' ./cmd/console)
printf -- "--> %15s:%s\n" "${osarch}" "${package}"
# go build -trimpath to build the binary.
GOOS=$os GOARCH=$arch GO111MODULE=on go build -trimpath --tags=kqueue --ldflags "-s -w" -o /dev/null ./cmd/console
}
main() {
echo "Testing builds for OS/Arch: ${SUPPORTED_OSARCH}"
for each_osarch in ${SUPPORTED_OSARCH}; do
_build "${each_osarch}"
done
}
_init && main "$@"

View File

@@ -2,7 +2,7 @@
`Console` will authenticate against `Kubernetes`using bearer tokens via HTTP `Authorization` header. The user will provide this token once
in the login form, Console will validate it against Kubernetes (list apis) and if valid will generate and return a new Console sessions
with encrypted claims (the user Service account token will be inside the JWT in the data field)
with encrypted claims (the user Service account token will be inside the session encrypted token
# Kubernetes

35
docs/ldap/billy.ldif Normal file
View File

@@ -0,0 +1,35 @@
# LDIF fragment to create group branch under root
dn: uid=billy,dc=example,dc=org
uid: billy
cn: billy
sn: 3
objectClass: top
objectClass: posixAccount
objectClass: inetOrgPerson
loginShell: /bin/bash
homeDirectory: /home/billy
uidNumber: 14583102
gidNumber: 14564100
userPassword: {SSHA}j3lBh1Seqe4rqF1+NuWmjhvtAni1JC5A
mail: billy@example.org
gecos: Billy User
# Create base group
dn: ou=groups,dc=example,dc=org
objectclass:organizationalunit
ou: groups
description: generic groups branch
# create consoleAdmin group (this already exists on minio and have a policy of s3::*)
dn: cn=consoleAdmin,ou=groups,dc=example,dc=org
objectClass: top
objectClass: posixGroup
gidNumber: 678
# Assing group to new user
dn: cn=consoleAdmin,ou=groups,dc=example,dc=org
changetype: modify
add: memberuid
memberuid: billy

20
go.mod
View File

@@ -1,6 +1,6 @@
module github.com/minio/console
go 1.13
go 1.15
require (
github.com/coreos/go-oidc v2.2.1+incompatible
@@ -16,19 +16,23 @@ require (
github.com/jessevdk/go-flags v1.4.0
github.com/minio/cli v1.22.0
github.com/minio/kes v0.11.0
github.com/minio/mc v0.0.0-20201001165056-7f2df96e4821
github.com/minio/minio v0.0.0-20200927172404-27d9bd04e544
github.com/minio/minio-go/v7 v7.0.6-0.20200923173112-bc846cb9b089
github.com/minio/operator v0.0.0-20200930213302-ab2bbdfae96c
github.com/minio/mc v0.0.0-20201220181029-41c804b179de
github.com/minio/minio v0.0.0-20201221162327-6df6ac0f3410
github.com/minio/minio-go/v7 v7.0.7-0.20201217170524-3baf9ea06f7c
github.com/minio/operator v0.0.0-20201204220226-9901d1d0766c
github.com/minio/operator/logsearchapi v0.0.0-20201217190212-bf6546b09012
github.com/mitchellh/go-homedir v1.1.0
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
github.com/secure-io/sio-go v0.3.1
github.com/stretchr/testify v1.6.1
github.com/unrolled/secure v1.0.7
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
golang.org/x/net v0.0.0-20200904194848-62affa334b73
golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
gopkg.in/yaml.v2 v2.3.0
k8s.io/api v0.18.6
k8s.io/apimachinery v0.18.6
k8s.io/apimachinery v0.18.8
k8s.io/client-go v0.18.6
)
replace github.com/minio/operator v0.0.0-20201204220226-9901d1d0766c => github.com/dvaldivia/operator v0.0.0-20201230052356-04efc0ea5890

536
go.sum

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 635 KiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 688 KiB

After

Width:  |  Height:  |  Size: 1.6 MiB

View File

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

View File

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

View File

@@ -8,4 +8,3 @@ resources:
- console-configmap.yaml
- console-service.yaml
- console-deployment.yaml
- https://github.com/minio/operator/?ref=v3.0.19

View File

@@ -0,0 +1,9 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# beginning of customizations
#namespace: min-ns
resources:
- ../base
- https://github.com/minio/operator/?ref=v3.0.29

View File

@@ -1,5 +1,5 @@
// This file is part of MinIO Kubernetes Cloud
// Copyright (c) 2019 MinIO, Inc.
// Copyright (c) 2020 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by

View File

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

View File

@@ -23,6 +23,9 @@ 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"
)
@@ -40,10 +43,47 @@ type AdminInfoResponse struct {
// usage
Usage int64 `json:"usage,omitempty"`
// widgets
Widgets []*Widget `json:"widgets"`
}
// Validate validates this admin info response
func (m *AdminInfoResponse) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateWidgets(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *AdminInfoResponse) validateWidgets(formats strfmt.Registry) error {
if swag.IsZero(m.Widgets) { // not required
return nil
}
for i := 0; i < len(m.Widgets); i++ {
if swag.IsZero(m.Widgets[i]) { // not required
continue
}
if m.Widgets[i] != nil {
if err := m.Widgets[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("widgets" + "." + strconv.Itoa(i))
}
return err
}
}
}
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) 2020 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// BucketEncryptionInfo bucket encryption info
//
// swagger:model bucketEncryptionInfo
type BucketEncryptionInfo struct {
// algorithm
Algorithm string `json:"algorithm,omitempty"`
// kms master key ID
KmsMasterKeyID string `json:"kmsMasterKeyID,omitempty"`
}
// Validate validates this bucket encryption info
func (m *BucketEncryptionInfo) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *BucketEncryptionInfo) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *BucketEncryptionInfo) UnmarshalBinary(b []byte) error {
var res BucketEncryptionInfo
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

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

View File

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

View File

@@ -35,14 +35,44 @@ type BucketObject struct {
// content type
ContentType string `json:"content_type,omitempty"`
// expiration
Expiration string `json:"expiration,omitempty"`
// expiration rule id
ExpirationRuleID string `json:"expiration_rule_id,omitempty"`
// is delete marker
IsDeleteMarker bool `json:"is_delete_marker,omitempty"`
// is latest
IsLatest bool `json:"is_latest,omitempty"`
// last modified
LastModified string `json:"last_modified,omitempty"`
// legal hold status
LegalHoldStatus string `json:"legal_hold_status,omitempty"`
// name
Name string `json:"name,omitempty"`
// retention mode
RetentionMode string `json:"retention_mode,omitempty"`
// retention until date
RetentionUntilDate string `json:"retention_until_date,omitempty"`
// size
Size int64 `json:"size,omitempty"`
// tags
Tags map[string]string `json:"tags,omitempty"`
// user tags
UserTags map[string]string `json:"user_tags,omitempty"`
// version id
VersionID string `json:"version_id,omitempty"`
}
// Validate validates this bucket object

View File

@@ -63,6 +63,12 @@ type CreateTenantRequest struct {
// erasure coding parity
ErasureCodingParity int64 `json:"erasureCodingParity,omitempty"`
// expose console
ExposeConsole bool `json:"expose_console,omitempty"`
// expose minio
ExposeMinio bool `json:"expose_minio,omitempty"`
// idp
Idp *IdpConfiguration `json:"idp,omitempty"`
@@ -90,18 +96,15 @@ type CreateTenantRequest struct {
// Required: true
Namespace *string `json:"namespace"`
// pools
// Required: true
Pools []*Pool `json:"pools"`
// secret key
SecretKey string `json:"secret_key,omitempty"`
// service name
ServiceName string `json:"service_name,omitempty"`
// tls
TLS *TLSConfiguration `json:"tls,omitempty"`
// zones
// Required: true
Zones []*Zone `json:"zones"`
}
// Validate validates this create tenant request
@@ -132,11 +135,11 @@ func (m *CreateTenantRequest) Validate(formats strfmt.Registry) error {
res = append(res, err)
}
if err := m.validateTLS(formats); err != nil {
if err := m.validatePools(formats); err != nil {
res = append(res, err)
}
if err := m.validateZones(formats); err != nil {
if err := m.validateTLS(formats); err != nil {
res = append(res, err)
}
@@ -240,6 +243,31 @@ func (m *CreateTenantRequest) validateNamespace(formats strfmt.Registry) error {
return nil
}
func (m *CreateTenantRequest) validatePools(formats strfmt.Registry) error {
if err := validate.Required("pools", "body", m.Pools); err != nil {
return err
}
for i := 0; i < len(m.Pools); i++ {
if swag.IsZero(m.Pools[i]) { // not required
continue
}
if m.Pools[i] != nil {
if err := m.Pools[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("pools" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *CreateTenantRequest) validateTLS(formats strfmt.Registry) error {
if swag.IsZero(m.TLS) { // not required
@@ -258,31 +286,6 @@ func (m *CreateTenantRequest) validateTLS(formats strfmt.Registry) error {
return nil
}
func (m *CreateTenantRequest) validateZones(formats strfmt.Registry) error {
if err := validate.Required("zones", "body", m.Zones); err != nil {
return err
}
for i := 0; i < len(m.Zones); i++ {
if swag.IsZero(m.Zones[i]) { // not required
continue
}
if m.Zones[i] != nil {
if err := m.Zones[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("zones" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// MarshalBinary interface implementation
func (m *CreateTenantRequest) MarshalBinary() ([]byte, error) {
if m == nil {

View File

@@ -33,14 +33,8 @@ import (
// swagger:model createTenantResponse
type CreateTenantResponse struct {
// access key
AccessKey string `json:"access_key,omitempty"`
// console
Console *CreateTenantResponseConsole `json:"console,omitempty"`
// secret key
SecretKey string `json:"secret_key,omitempty"`
}
// Validate validates this create tenant response

View File

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

48
models/iam_entity.go Normal file
View File

@@ -0,0 +1,48 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2020 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/validate"
)
// IamEntity iam entity
//
// swagger:model iamEntity
type IamEntity string
// Validate validates this iam entity
func (m IamEntity) Validate(formats strfmt.Registry) error {
var res []error
if err := validate.Pattern("", "body", string(m), `^[\w+=,.@-]{1,64}$`); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

75
models/license.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) 2020 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// License license
//
// swagger:model license
type License struct {
// account id
AccountID int64 `json:"account_id,omitempty"`
// email
Email string `json:"email,omitempty"`
// expires at
ExpiresAt string `json:"expires_at,omitempty"`
// organization
Organization string `json:"organization,omitempty"`
// plan
Plan string `json:"plan,omitempty"`
// storage capacity
StorageCapacity int64 `json:"storage_capacity,omitempty"`
}
// Validate validates this license
func (m *License) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *License) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *License) UnmarshalBinary(b []byte) error {
var res License
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

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

View File

@@ -41,6 +41,9 @@ type MakeBucketRequest struct {
// quota
Quota *SetBucketQuota `json:"quota,omitempty"`
// retention
Retention *PutBucketRetentionRequest `json:"retention,omitempty"`
// versioning
Versioning bool `json:"versioning,omitempty"`
}
@@ -57,6 +60,10 @@ func (m *MakeBucketRequest) Validate(formats strfmt.Registry) error {
res = append(res, err)
}
if err := m.validateRetention(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
@@ -90,6 +97,24 @@ func (m *MakeBucketRequest) validateQuota(formats strfmt.Registry) error {
return nil
}
func (m *MakeBucketRequest) validateRetention(formats strfmt.Registry) error {
if swag.IsZero(m.Retention) { // not required
return nil
}
if m.Retention != nil {
if err := m.Retention.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("retention")
}
return err
}
}
return nil
}
// MarshalBinary interface implementation
func (m *MakeBucketRequest) MarshalBinary() ([]byte, error) {
if m == nil {

View File

@@ -0,0 +1,80 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2020 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/validate"
)
// ObjectLegalHoldStatus object legal hold status
//
// swagger:model objectLegalHoldStatus
type ObjectLegalHoldStatus string
const (
// ObjectLegalHoldStatusEnabled captures enum value "enabled"
ObjectLegalHoldStatusEnabled ObjectLegalHoldStatus = "enabled"
// ObjectLegalHoldStatusDisabled captures enum value "disabled"
ObjectLegalHoldStatusDisabled ObjectLegalHoldStatus = "disabled"
)
// for schema
var objectLegalHoldStatusEnum []interface{}
func init() {
var res []ObjectLegalHoldStatus
if err := json.Unmarshal([]byte(`["enabled","disabled"]`), &res); err != nil {
panic(err)
}
for _, v := range res {
objectLegalHoldStatusEnum = append(objectLegalHoldStatusEnum, v)
}
}
func (m ObjectLegalHoldStatus) validateObjectLegalHoldStatusEnum(path, location string, value ObjectLegalHoldStatus) error {
if err := validate.EnumCase(path, location, value, objectLegalHoldStatusEnum, true); err != nil {
return err
}
return nil
}
// Validate validates this object legal hold status
func (m ObjectLegalHoldStatus) Validate(formats strfmt.Registry) error {
var res []error
// value enum
if err := m.validateObjectLegalHoldStatusEnum("", "body", m); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -0,0 +1,80 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2020 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/validate"
)
// ObjectRetentionMode object retention mode
//
// swagger:model objectRetentionMode
type ObjectRetentionMode string
const (
// ObjectRetentionModeGovernance captures enum value "governance"
ObjectRetentionModeGovernance ObjectRetentionMode = "governance"
// ObjectRetentionModeCompliance captures enum value "compliance"
ObjectRetentionModeCompliance ObjectRetentionMode = "compliance"
)
// for schema
var objectRetentionModeEnum []interface{}
func init() {
var res []ObjectRetentionMode
if err := json.Unmarshal([]byte(`["governance","compliance"]`), &res); err != nil {
panic(err)
}
for _, v := range res {
objectRetentionModeEnum = append(objectRetentionModeEnum, v)
}
}
func (m ObjectRetentionMode) validateObjectRetentionModeEnum(path, location string, value ObjectRetentionMode) error {
if err := validate.EnumCase(path, location, value, objectRetentionModeEnum, true); err != nil {
return err
}
return nil
}
// Validate validates this object retention mode
func (m ObjectRetentionMode) Validate(formats strfmt.Registry) error {
var res []error
// value enum
if err := m.validateObjectRetentionModeEnum("", "body", m); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -0,0 +1,80 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2020 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/validate"
)
// ObjectRetentionUnit object retention unit
//
// swagger:model objectRetentionUnit
type ObjectRetentionUnit string
const (
// ObjectRetentionUnitDays captures enum value "days"
ObjectRetentionUnitDays ObjectRetentionUnit = "days"
// ObjectRetentionUnitYears captures enum value "years"
ObjectRetentionUnitYears ObjectRetentionUnit = "years"
)
// for schema
var objectRetentionUnitEnum []interface{}
func init() {
var res []ObjectRetentionUnit
if err := json.Unmarshal([]byte(`["days","years"]`), &res); err != nil {
panic(err)
}
for _, v := range res {
objectRetentionUnitEnum = append(objectRetentionUnitEnum, v)
}
}
func (m ObjectRetentionUnit) validateObjectRetentionUnitEnum(path, location string, value ObjectRetentionUnit) error {
if err := validate.EnumCase(path, location, value, objectRetentionUnitEnum, true); err != nil {
return err
}
return nil
}
// Validate validates this object retention unit
func (m ObjectRetentionUnit) Validate(formats strfmt.Registry) error {
var res []error
// value enum
if err := m.validateObjectRetentionUnitEnum("", "body", m); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -29,13 +29,13 @@ import (
"github.com/go-openapi/validate"
)
// Zone zone
// Pool pool
//
// swagger:model zone
type Zone struct {
// swagger:model pool
type Pool struct {
// affinity
Affinity *ZoneAffinity `json:"affinity,omitempty"`
Affinity *PoolAffinity `json:"affinity,omitempty"`
// name
Name string `json:"name,omitempty"`
@@ -44,26 +44,26 @@ type Zone struct {
NodeSelector map[string]string `json:"node_selector,omitempty"`
// resources
Resources *ZoneResources `json:"resources,omitempty"`
Resources *PoolResources `json:"resources,omitempty"`
// servers
// Required: true
Servers *int64 `json:"servers"`
// tolerations
Tolerations ZoneTolerations `json:"tolerations,omitempty"`
Tolerations PoolTolerations `json:"tolerations,omitempty"`
// volume configuration
// Required: true
VolumeConfiguration *ZoneVolumeConfiguration `json:"volume_configuration"`
VolumeConfiguration *PoolVolumeConfiguration `json:"volume_configuration"`
// volumes per server
// Required: true
VolumesPerServer *int32 `json:"volumes_per_server"`
}
// Validate validates this zone
func (m *Zone) Validate(formats strfmt.Registry) error {
// Validate validates this pool
func (m *Pool) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateAffinity(formats); err != nil {
@@ -96,7 +96,7 @@ func (m *Zone) Validate(formats strfmt.Registry) error {
return nil
}
func (m *Zone) validateAffinity(formats strfmt.Registry) error {
func (m *Pool) validateAffinity(formats strfmt.Registry) error {
if swag.IsZero(m.Affinity) { // not required
return nil
@@ -114,7 +114,7 @@ func (m *Zone) validateAffinity(formats strfmt.Registry) error {
return nil
}
func (m *Zone) validateResources(formats strfmt.Registry) error {
func (m *Pool) validateResources(formats strfmt.Registry) error {
if swag.IsZero(m.Resources) { // not required
return nil
@@ -132,7 +132,7 @@ func (m *Zone) validateResources(formats strfmt.Registry) error {
return nil
}
func (m *Zone) validateServers(formats strfmt.Registry) error {
func (m *Pool) validateServers(formats strfmt.Registry) error {
if err := validate.Required("servers", "body", m.Servers); err != nil {
return err
@@ -141,7 +141,7 @@ func (m *Zone) validateServers(formats strfmt.Registry) error {
return nil
}
func (m *Zone) validateTolerations(formats strfmt.Registry) error {
func (m *Pool) validateTolerations(formats strfmt.Registry) error {
if swag.IsZero(m.Tolerations) { // not required
return nil
@@ -157,7 +157,7 @@ func (m *Zone) validateTolerations(formats strfmt.Registry) error {
return nil
}
func (m *Zone) validateVolumeConfiguration(formats strfmt.Registry) error {
func (m *Pool) validateVolumeConfiguration(formats strfmt.Registry) error {
if err := validate.Required("volume_configuration", "body", m.VolumeConfiguration); err != nil {
return err
@@ -175,7 +175,7 @@ func (m *Zone) validateVolumeConfiguration(formats strfmt.Registry) error {
return nil
}
func (m *Zone) validateVolumesPerServer(formats strfmt.Registry) error {
func (m *Pool) validateVolumesPerServer(formats strfmt.Registry) error {
if err := validate.Required("volumes_per_server", "body", m.VolumesPerServer); err != nil {
return err
@@ -185,7 +185,7 @@ func (m *Zone) validateVolumesPerServer(formats strfmt.Registry) error {
}
// MarshalBinary interface implementation
func (m *Zone) MarshalBinary() ([]byte, error) {
func (m *Pool) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
@@ -193,8 +193,8 @@ func (m *Zone) MarshalBinary() ([]byte, error) {
}
// UnmarshalBinary interface implementation
func (m *Zone) UnmarshalBinary(b []byte) error {
var res Zone
func (m *Pool) UnmarshalBinary(b []byte) error {
var res Pool
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
@@ -202,10 +202,10 @@ func (m *Zone) UnmarshalBinary(b []byte) error {
return nil
}
// ZoneVolumeConfiguration zone volume configuration
// PoolVolumeConfiguration pool volume configuration
//
// swagger:model ZoneVolumeConfiguration
type ZoneVolumeConfiguration struct {
// swagger:model PoolVolumeConfiguration
type PoolVolumeConfiguration struct {
// annotations
Annotations map[string]string `json:"annotations,omitempty"`
@@ -221,8 +221,8 @@ type ZoneVolumeConfiguration struct {
StorageClassName string `json:"storage_class_name,omitempty"`
}
// Validate validates this zone volume configuration
func (m *ZoneVolumeConfiguration) Validate(formats strfmt.Registry) error {
// Validate validates this pool volume configuration
func (m *PoolVolumeConfiguration) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateSize(formats); err != nil {
@@ -235,7 +235,7 @@ func (m *ZoneVolumeConfiguration) Validate(formats strfmt.Registry) error {
return nil
}
func (m *ZoneVolumeConfiguration) validateSize(formats strfmt.Registry) error {
func (m *PoolVolumeConfiguration) validateSize(formats strfmt.Registry) error {
if err := validate.Required("volume_configuration"+"."+"size", "body", m.Size); err != nil {
return err
@@ -245,7 +245,7 @@ func (m *ZoneVolumeConfiguration) validateSize(formats strfmt.Registry) error {
}
// MarshalBinary interface implementation
func (m *ZoneVolumeConfiguration) MarshalBinary() ([]byte, error) {
func (m *PoolVolumeConfiguration) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
@@ -253,8 +253,8 @@ func (m *ZoneVolumeConfiguration) MarshalBinary() ([]byte, error) {
}
// UnmarshalBinary interface implementation
func (m *ZoneVolumeConfiguration) UnmarshalBinary(b []byte) error {
var res ZoneVolumeConfiguration
func (m *PoolVolumeConfiguration) UnmarshalBinary(b []byte) error {
var res PoolVolumeConfiguration
if err := swag.ReadJSON(b, &res); err != nil {
return err
}

View File

@@ -31,23 +31,23 @@ import (
"github.com/go-openapi/validate"
)
// ZoneAffinity If specified, affinity will define the pod's scheduling constraints
// PoolAffinity If specified, affinity will define the pod's scheduling constraints
//
// swagger:model zoneAffinity
type ZoneAffinity struct {
// swagger:model poolAffinity
type PoolAffinity struct {
// node affinity
NodeAffinity *ZoneAffinityNodeAffinity `json:"nodeAffinity,omitempty"`
NodeAffinity *PoolAffinityNodeAffinity `json:"nodeAffinity,omitempty"`
// pod affinity
PodAffinity *ZoneAffinityPodAffinity `json:"podAffinity,omitempty"`
PodAffinity *PoolAffinityPodAffinity `json:"podAffinity,omitempty"`
// pod anti affinity
PodAntiAffinity *ZoneAffinityPodAntiAffinity `json:"podAntiAffinity,omitempty"`
PodAntiAffinity *PoolAffinityPodAntiAffinity `json:"podAntiAffinity,omitempty"`
}
// Validate validates this zone affinity
func (m *ZoneAffinity) Validate(formats strfmt.Registry) error {
// Validate validates this pool affinity
func (m *PoolAffinity) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateNodeAffinity(formats); err != nil {
@@ -68,7 +68,7 @@ func (m *ZoneAffinity) Validate(formats strfmt.Registry) error {
return nil
}
func (m *ZoneAffinity) validateNodeAffinity(formats strfmt.Registry) error {
func (m *PoolAffinity) validateNodeAffinity(formats strfmt.Registry) error {
if swag.IsZero(m.NodeAffinity) { // not required
return nil
@@ -86,7 +86,7 @@ func (m *ZoneAffinity) validateNodeAffinity(formats strfmt.Registry) error {
return nil
}
func (m *ZoneAffinity) validatePodAffinity(formats strfmt.Registry) error {
func (m *PoolAffinity) validatePodAffinity(formats strfmt.Registry) error {
if swag.IsZero(m.PodAffinity) { // not required
return nil
@@ -104,7 +104,7 @@ func (m *ZoneAffinity) validatePodAffinity(formats strfmt.Registry) error {
return nil
}
func (m *ZoneAffinity) validatePodAntiAffinity(formats strfmt.Registry) error {
func (m *PoolAffinity) validatePodAntiAffinity(formats strfmt.Registry) error {
if swag.IsZero(m.PodAntiAffinity) { // not required
return nil
@@ -123,7 +123,7 @@ func (m *ZoneAffinity) validatePodAntiAffinity(formats strfmt.Registry) error {
}
// MarshalBinary interface implementation
func (m *ZoneAffinity) MarshalBinary() ([]byte, error) {
func (m *PoolAffinity) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
@@ -131,8 +131,8 @@ func (m *ZoneAffinity) MarshalBinary() ([]byte, error) {
}
// UnmarshalBinary interface implementation
func (m *ZoneAffinity) UnmarshalBinary(b []byte) error {
var res ZoneAffinity
func (m *PoolAffinity) UnmarshalBinary(b []byte) error {
var res PoolAffinity
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
@@ -140,20 +140,20 @@ func (m *ZoneAffinity) UnmarshalBinary(b []byte) error {
return nil
}
// ZoneAffinityNodeAffinity Describes node affinity scheduling rules for the pod.
// PoolAffinityNodeAffinity Describes node affinity scheduling rules for the pod.
//
// swagger:model ZoneAffinityNodeAffinity
type ZoneAffinityNodeAffinity struct {
// swagger:model PoolAffinityNodeAffinity
type PoolAffinityNodeAffinity struct {
// The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred.
PreferredDuringSchedulingIgnoredDuringExecution []*ZoneAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0 `json:"preferredDuringSchedulingIgnoredDuringExecution"`
PreferredDuringSchedulingIgnoredDuringExecution []*PoolAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0 `json:"preferredDuringSchedulingIgnoredDuringExecution"`
// required during scheduling ignored during execution
RequiredDuringSchedulingIgnoredDuringExecution *ZoneAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution `json:"requiredDuringSchedulingIgnoredDuringExecution,omitempty"`
RequiredDuringSchedulingIgnoredDuringExecution *PoolAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution `json:"requiredDuringSchedulingIgnoredDuringExecution,omitempty"`
}
// Validate validates this zone affinity node affinity
func (m *ZoneAffinityNodeAffinity) Validate(formats strfmt.Registry) error {
// Validate validates this pool affinity node affinity
func (m *PoolAffinityNodeAffinity) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validatePreferredDuringSchedulingIgnoredDuringExecution(formats); err != nil {
@@ -170,7 +170,7 @@ func (m *ZoneAffinityNodeAffinity) Validate(formats strfmt.Registry) error {
return nil
}
func (m *ZoneAffinityNodeAffinity) validatePreferredDuringSchedulingIgnoredDuringExecution(formats strfmt.Registry) error {
func (m *PoolAffinityNodeAffinity) validatePreferredDuringSchedulingIgnoredDuringExecution(formats strfmt.Registry) error {
if swag.IsZero(m.PreferredDuringSchedulingIgnoredDuringExecution) { // not required
return nil
@@ -195,7 +195,7 @@ func (m *ZoneAffinityNodeAffinity) validatePreferredDuringSchedulingIgnoredDurin
return nil
}
func (m *ZoneAffinityNodeAffinity) validateRequiredDuringSchedulingIgnoredDuringExecution(formats strfmt.Registry) error {
func (m *PoolAffinityNodeAffinity) validateRequiredDuringSchedulingIgnoredDuringExecution(formats strfmt.Registry) error {
if swag.IsZero(m.RequiredDuringSchedulingIgnoredDuringExecution) { // not required
return nil
@@ -214,7 +214,7 @@ func (m *ZoneAffinityNodeAffinity) validateRequiredDuringSchedulingIgnoredDuring
}
// MarshalBinary interface implementation
func (m *ZoneAffinityNodeAffinity) MarshalBinary() ([]byte, error) {
func (m *PoolAffinityNodeAffinity) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
@@ -222,8 +222,8 @@ func (m *ZoneAffinityNodeAffinity) MarshalBinary() ([]byte, error) {
}
// UnmarshalBinary interface implementation
func (m *ZoneAffinityNodeAffinity) UnmarshalBinary(b []byte) error {
var res ZoneAffinityNodeAffinity
func (m *PoolAffinityNodeAffinity) UnmarshalBinary(b []byte) error {
var res PoolAffinityNodeAffinity
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
@@ -231,10 +231,10 @@ func (m *ZoneAffinityNodeAffinity) UnmarshalBinary(b []byte) error {
return nil
}
// ZoneAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0 An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op).
// PoolAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0 An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op).
//
// swagger:model ZoneAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0
type ZoneAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0 struct {
// swagger:model PoolAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0
type PoolAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0 struct {
// A node selector term, associated with the corresponding weight.
// Required: true
@@ -245,8 +245,8 @@ type ZoneAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionItem
Weight *int32 `json:"weight"`
}
// Validate validates this zone affinity node affinity preferred during scheduling ignored during execution items0
func (m *ZoneAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) Validate(formats strfmt.Registry) error {
// Validate validates this pool affinity node affinity preferred during scheduling ignored during execution items0
func (m *PoolAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validatePreference(formats); err != nil {
@@ -263,7 +263,7 @@ func (m *ZoneAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecution
return nil
}
func (m *ZoneAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) validatePreference(formats strfmt.Registry) error {
func (m *PoolAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) validatePreference(formats strfmt.Registry) error {
if err := validate.Required("preference", "body", m.Preference); err != nil {
return err
@@ -281,7 +281,7 @@ func (m *ZoneAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecution
return nil
}
func (m *ZoneAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) validateWeight(formats strfmt.Registry) error {
func (m *PoolAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) validateWeight(formats strfmt.Registry) error {
if err := validate.Required("weight", "body", m.Weight); err != nil {
return err
@@ -291,7 +291,7 @@ func (m *ZoneAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecution
}
// MarshalBinary interface implementation
func (m *ZoneAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) MarshalBinary() ([]byte, error) {
func (m *PoolAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
@@ -299,8 +299,8 @@ func (m *ZoneAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecution
}
// UnmarshalBinary interface implementation
func (m *ZoneAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) UnmarshalBinary(b []byte) error {
var res ZoneAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0
func (m *PoolAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) UnmarshalBinary(b []byte) error {
var res PoolAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
@@ -308,18 +308,18 @@ func (m *ZoneAffinityNodeAffinityPreferredDuringSchedulingIgnoredDuringExecution
return nil
}
// ZoneAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node.
// PoolAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node.
//
// swagger:model ZoneAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution
type ZoneAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution struct {
// swagger:model PoolAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution
type PoolAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution struct {
// Required. A list of node selector terms. The terms are ORed.
// Required: true
NodeSelectorTerms []*NodeSelectorTerm `json:"nodeSelectorTerms"`
}
// Validate validates this zone affinity node affinity required during scheduling ignored during execution
func (m *ZoneAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution) Validate(formats strfmt.Registry) error {
// Validate validates this pool affinity node affinity required during scheduling ignored during execution
func (m *PoolAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateNodeSelectorTerms(formats); err != nil {
@@ -332,7 +332,7 @@ func (m *ZoneAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution)
return nil
}
func (m *ZoneAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution) validateNodeSelectorTerms(formats strfmt.Registry) error {
func (m *PoolAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution) validateNodeSelectorTerms(formats strfmt.Registry) error {
if err := validate.Required("nodeAffinity"+"."+"requiredDuringSchedulingIgnoredDuringExecution"+"."+"nodeSelectorTerms", "body", m.NodeSelectorTerms); err != nil {
return err
@@ -358,7 +358,7 @@ func (m *ZoneAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution)
}
// MarshalBinary interface implementation
func (m *ZoneAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution) MarshalBinary() ([]byte, error) {
func (m *PoolAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
@@ -366,8 +366,8 @@ func (m *ZoneAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution)
}
// UnmarshalBinary interface implementation
func (m *ZoneAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution) UnmarshalBinary(b []byte) error {
var res ZoneAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution
func (m *PoolAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution) UnmarshalBinary(b []byte) error {
var res PoolAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
@@ -375,20 +375,20 @@ func (m *ZoneAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution)
return nil
}
// ZoneAffinityPodAffinity Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)).
// PoolAffinityPodAffinity Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, pool, etc. as some other pod(s)).
//
// swagger:model ZoneAffinityPodAffinity
type ZoneAffinityPodAffinity struct {
// swagger:model PoolAffinityPodAffinity
type PoolAffinityPodAffinity struct {
// The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred.
PreferredDuringSchedulingIgnoredDuringExecution []*ZoneAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0 `json:"preferredDuringSchedulingIgnoredDuringExecution"`
PreferredDuringSchedulingIgnoredDuringExecution []*PoolAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0 `json:"preferredDuringSchedulingIgnoredDuringExecution"`
// If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied.
RequiredDuringSchedulingIgnoredDuringExecution []*PodAffinityTerm `json:"requiredDuringSchedulingIgnoredDuringExecution"`
}
// Validate validates this zone affinity pod affinity
func (m *ZoneAffinityPodAffinity) Validate(formats strfmt.Registry) error {
// Validate validates this pool affinity pod affinity
func (m *PoolAffinityPodAffinity) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validatePreferredDuringSchedulingIgnoredDuringExecution(formats); err != nil {
@@ -405,7 +405,7 @@ func (m *ZoneAffinityPodAffinity) Validate(formats strfmt.Registry) error {
return nil
}
func (m *ZoneAffinityPodAffinity) validatePreferredDuringSchedulingIgnoredDuringExecution(formats strfmt.Registry) error {
func (m *PoolAffinityPodAffinity) validatePreferredDuringSchedulingIgnoredDuringExecution(formats strfmt.Registry) error {
if swag.IsZero(m.PreferredDuringSchedulingIgnoredDuringExecution) { // not required
return nil
@@ -430,7 +430,7 @@ func (m *ZoneAffinityPodAffinity) validatePreferredDuringSchedulingIgnoredDuring
return nil
}
func (m *ZoneAffinityPodAffinity) validateRequiredDuringSchedulingIgnoredDuringExecution(formats strfmt.Registry) error {
func (m *PoolAffinityPodAffinity) validateRequiredDuringSchedulingIgnoredDuringExecution(formats strfmt.Registry) error {
if swag.IsZero(m.RequiredDuringSchedulingIgnoredDuringExecution) { // not required
return nil
@@ -456,7 +456,7 @@ func (m *ZoneAffinityPodAffinity) validateRequiredDuringSchedulingIgnoredDuringE
}
// MarshalBinary interface implementation
func (m *ZoneAffinityPodAffinity) MarshalBinary() ([]byte, error) {
func (m *PoolAffinityPodAffinity) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
@@ -464,8 +464,8 @@ func (m *ZoneAffinityPodAffinity) MarshalBinary() ([]byte, error) {
}
// UnmarshalBinary interface implementation
func (m *ZoneAffinityPodAffinity) UnmarshalBinary(b []byte) error {
var res ZoneAffinityPodAffinity
func (m *PoolAffinityPodAffinity) UnmarshalBinary(b []byte) error {
var res PoolAffinityPodAffinity
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
@@ -473,10 +473,10 @@ func (m *ZoneAffinityPodAffinity) UnmarshalBinary(b []byte) error {
return nil
}
// ZoneAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0 The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)
// PoolAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0 The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)
//
// swagger:model ZoneAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0
type ZoneAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0 struct {
// swagger:model PoolAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0
type PoolAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0 struct {
// pod affinity term
// Required: true
@@ -487,8 +487,8 @@ type ZoneAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems
Weight *int32 `json:"weight"`
}
// Validate validates this zone affinity pod affinity preferred during scheduling ignored during execution items0
func (m *ZoneAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) Validate(formats strfmt.Registry) error {
// Validate validates this pool affinity pod affinity preferred during scheduling ignored during execution items0
func (m *PoolAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validatePodAffinityTerm(formats); err != nil {
@@ -505,7 +505,7 @@ func (m *ZoneAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionI
return nil
}
func (m *ZoneAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) validatePodAffinityTerm(formats strfmt.Registry) error {
func (m *PoolAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) validatePodAffinityTerm(formats strfmt.Registry) error {
if err := validate.Required("podAffinityTerm", "body", m.PodAffinityTerm); err != nil {
return err
@@ -523,7 +523,7 @@ func (m *ZoneAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionI
return nil
}
func (m *ZoneAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) validateWeight(formats strfmt.Registry) error {
func (m *PoolAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) validateWeight(formats strfmt.Registry) error {
if err := validate.Required("weight", "body", m.Weight); err != nil {
return err
@@ -533,7 +533,7 @@ func (m *ZoneAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionI
}
// MarshalBinary interface implementation
func (m *ZoneAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) MarshalBinary() ([]byte, error) {
func (m *PoolAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
@@ -541,8 +541,8 @@ func (m *ZoneAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionI
}
// UnmarshalBinary interface implementation
func (m *ZoneAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) UnmarshalBinary(b []byte) error {
var res ZoneAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0
func (m *PoolAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) UnmarshalBinary(b []byte) error {
var res PoolAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
@@ -550,20 +550,20 @@ func (m *ZoneAffinityPodAffinityPreferredDuringSchedulingIgnoredDuringExecutionI
return nil
}
// ZoneAffinityPodAntiAffinity Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)).
// PoolAffinityPodAntiAffinity Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, pool, etc. as some other pod(s)).
//
// swagger:model ZoneAffinityPodAntiAffinity
type ZoneAffinityPodAntiAffinity struct {
// swagger:model PoolAffinityPodAntiAffinity
type PoolAffinityPodAntiAffinity struct {
// The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred.
PreferredDuringSchedulingIgnoredDuringExecution []*ZoneAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0 `json:"preferredDuringSchedulingIgnoredDuringExecution"`
PreferredDuringSchedulingIgnoredDuringExecution []*PoolAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0 `json:"preferredDuringSchedulingIgnoredDuringExecution"`
// If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied.
RequiredDuringSchedulingIgnoredDuringExecution []*PodAffinityTerm `json:"requiredDuringSchedulingIgnoredDuringExecution"`
}
// Validate validates this zone affinity pod anti affinity
func (m *ZoneAffinityPodAntiAffinity) Validate(formats strfmt.Registry) error {
// Validate validates this pool affinity pod anti affinity
func (m *PoolAffinityPodAntiAffinity) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validatePreferredDuringSchedulingIgnoredDuringExecution(formats); err != nil {
@@ -580,7 +580,7 @@ func (m *ZoneAffinityPodAntiAffinity) Validate(formats strfmt.Registry) error {
return nil
}
func (m *ZoneAffinityPodAntiAffinity) validatePreferredDuringSchedulingIgnoredDuringExecution(formats strfmt.Registry) error {
func (m *PoolAffinityPodAntiAffinity) validatePreferredDuringSchedulingIgnoredDuringExecution(formats strfmt.Registry) error {
if swag.IsZero(m.PreferredDuringSchedulingIgnoredDuringExecution) { // not required
return nil
@@ -605,7 +605,7 @@ func (m *ZoneAffinityPodAntiAffinity) validatePreferredDuringSchedulingIgnoredDu
return nil
}
func (m *ZoneAffinityPodAntiAffinity) validateRequiredDuringSchedulingIgnoredDuringExecution(formats strfmt.Registry) error {
func (m *PoolAffinityPodAntiAffinity) validateRequiredDuringSchedulingIgnoredDuringExecution(formats strfmt.Registry) error {
if swag.IsZero(m.RequiredDuringSchedulingIgnoredDuringExecution) { // not required
return nil
@@ -631,7 +631,7 @@ func (m *ZoneAffinityPodAntiAffinity) validateRequiredDuringSchedulingIgnoredDur
}
// MarshalBinary interface implementation
func (m *ZoneAffinityPodAntiAffinity) MarshalBinary() ([]byte, error) {
func (m *PoolAffinityPodAntiAffinity) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
@@ -639,8 +639,8 @@ func (m *ZoneAffinityPodAntiAffinity) MarshalBinary() ([]byte, error) {
}
// UnmarshalBinary interface implementation
func (m *ZoneAffinityPodAntiAffinity) UnmarshalBinary(b []byte) error {
var res ZoneAffinityPodAntiAffinity
func (m *PoolAffinityPodAntiAffinity) UnmarshalBinary(b []byte) error {
var res PoolAffinityPodAntiAffinity
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
@@ -648,10 +648,10 @@ func (m *ZoneAffinityPodAntiAffinity) UnmarshalBinary(b []byte) error {
return nil
}
// ZoneAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0 The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)
// PoolAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0 The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)
//
// swagger:model ZoneAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0
type ZoneAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0 struct {
// swagger:model PoolAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0
type PoolAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0 struct {
// pod affinity term
// Required: true
@@ -662,8 +662,8 @@ type ZoneAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecutionI
Weight *int32 `json:"weight"`
}
// Validate validates this zone affinity pod anti affinity preferred during scheduling ignored during execution items0
func (m *ZoneAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) Validate(formats strfmt.Registry) error {
// Validate validates this pool affinity pod anti affinity preferred during scheduling ignored during execution items0
func (m *PoolAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validatePodAffinityTerm(formats); err != nil {
@@ -680,7 +680,7 @@ func (m *ZoneAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecut
return nil
}
func (m *ZoneAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) validatePodAffinityTerm(formats strfmt.Registry) error {
func (m *PoolAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) validatePodAffinityTerm(formats strfmt.Registry) error {
if err := validate.Required("podAffinityTerm", "body", m.PodAffinityTerm); err != nil {
return err
@@ -698,7 +698,7 @@ func (m *ZoneAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecut
return nil
}
func (m *ZoneAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) validateWeight(formats strfmt.Registry) error {
func (m *PoolAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) validateWeight(formats strfmt.Registry) error {
if err := validate.Required("weight", "body", m.Weight); err != nil {
return err
@@ -708,7 +708,7 @@ func (m *ZoneAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecut
}
// MarshalBinary interface implementation
func (m *ZoneAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) MarshalBinary() ([]byte, error) {
func (m *PoolAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
@@ -716,8 +716,8 @@ func (m *ZoneAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecut
}
// UnmarshalBinary interface implementation
func (m *ZoneAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) UnmarshalBinary(b []byte) error {
var res ZoneAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0
func (m *PoolAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0) UnmarshalBinary(b []byte) error {
var res PoolAffinityPodAntiAffinityPreferredDuringSchedulingIgnoredDuringExecutionItems0
if err := swag.ReadJSON(b, &res); err != nil {
return err
}

View File

@@ -27,10 +27,10 @@ import (
"github.com/go-openapi/swag"
)
// ZoneResources If provided, use these requests and limit for cpu/memory resource allocation
// PoolResources If provided, use these requests and limit for cpu/memory resource allocation
//
// swagger:model zoneResources
type ZoneResources struct {
// swagger:model poolResources
type PoolResources struct {
// Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
Limits map[string]int64 `json:"limits,omitempty"`
@@ -39,13 +39,13 @@ type ZoneResources struct {
Requests map[string]int64 `json:"requests,omitempty"`
}
// Validate validates this zone resources
func (m *ZoneResources) Validate(formats strfmt.Registry) error {
// Validate validates this pool resources
func (m *PoolResources) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *ZoneResources) MarshalBinary() ([]byte, error) {
func (m *PoolResources) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
@@ -53,8 +53,8 @@ func (m *ZoneResources) MarshalBinary() ([]byte, error) {
}
// UnmarshalBinary interface implementation
func (m *ZoneResources) UnmarshalBinary(b []byte) error {
var res ZoneResources
func (m *PoolResources) UnmarshalBinary(b []byte) error {
var res PoolResources
if err := swag.ReadJSON(b, &res); err != nil {
return err
}

View File

@@ -29,18 +29,18 @@ import (
"github.com/go-openapi/validate"
)
// ZoneTolerationSeconds TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system.
// PoolTolerationSeconds TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system.
//
// swagger:model zoneTolerationSeconds
type ZoneTolerationSeconds struct {
// swagger:model poolTolerationSeconds
type PoolTolerationSeconds struct {
// seconds
// Required: true
Seconds *int64 `json:"seconds"`
}
// Validate validates this zone toleration seconds
func (m *ZoneTolerationSeconds) Validate(formats strfmt.Registry) error {
// Validate validates this pool toleration seconds
func (m *PoolTolerationSeconds) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateSeconds(formats); err != nil {
@@ -53,7 +53,7 @@ func (m *ZoneTolerationSeconds) Validate(formats strfmt.Registry) error {
return nil
}
func (m *ZoneTolerationSeconds) validateSeconds(formats strfmt.Registry) error {
func (m *PoolTolerationSeconds) validateSeconds(formats strfmt.Registry) error {
if err := validate.Required("seconds", "body", m.Seconds); err != nil {
return err
@@ -63,7 +63,7 @@ func (m *ZoneTolerationSeconds) validateSeconds(formats strfmt.Registry) error {
}
// MarshalBinary interface implementation
func (m *ZoneTolerationSeconds) MarshalBinary() ([]byte, error) {
func (m *PoolTolerationSeconds) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
@@ -71,8 +71,8 @@ func (m *ZoneTolerationSeconds) MarshalBinary() ([]byte, error) {
}
// UnmarshalBinary interface implementation
func (m *ZoneTolerationSeconds) UnmarshalBinary(b []byte) error {
var res ZoneTolerationSeconds
func (m *PoolTolerationSeconds) UnmarshalBinary(b []byte) error {
var res PoolTolerationSeconds
if err := swag.ReadJSON(b, &res); err != nil {
return err
}

View File

@@ -30,13 +30,13 @@ import (
"github.com/go-openapi/swag"
)
// ZoneTolerations Tolerations allows users to set entries like effect, key, operator, value.
// PoolTolerations Tolerations allows users to set entries like effect, key, operator, value.
//
// swagger:model zoneTolerations
type ZoneTolerations []*ZoneTolerationsItems0
// swagger:model poolTolerations
type PoolTolerations []*PoolTolerationsItems0
// Validate validates this zone tolerations
func (m ZoneTolerations) Validate(formats strfmt.Registry) error {
// Validate validates this pool tolerations
func (m PoolTolerations) Validate(formats strfmt.Registry) error {
var res []error
for i := 0; i < len(m); i++ {
@@ -61,10 +61,10 @@ func (m ZoneTolerations) Validate(formats strfmt.Registry) error {
return nil
}
// ZoneTolerationsItems0 The pod this Toleration is attached to tolerates any taint that matches the triple <key,value,effect> using the matching operator <operator>.
// PoolTolerationsItems0 The pod this Toleration is attached to tolerates any taint that matches the triple <key,value,effect> using the matching operator <operator>.
//
// swagger:model ZoneTolerationsItems0
type ZoneTolerationsItems0 struct {
// swagger:model PoolTolerationsItems0
type PoolTolerationsItems0 struct {
// Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.
Effect string `json:"effect,omitempty"`
@@ -76,14 +76,14 @@ type ZoneTolerationsItems0 struct {
Operator string `json:"operator,omitempty"`
// toleration seconds
TolerationSeconds *ZoneTolerationSeconds `json:"tolerationSeconds,omitempty"`
TolerationSeconds *PoolTolerationSeconds `json:"tolerationSeconds,omitempty"`
// Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string.
Value string `json:"value,omitempty"`
}
// Validate validates this zone tolerations items0
func (m *ZoneTolerationsItems0) Validate(formats strfmt.Registry) error {
// Validate validates this pool tolerations items0
func (m *PoolTolerationsItems0) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateTolerationSeconds(formats); err != nil {
@@ -96,7 +96,7 @@ func (m *ZoneTolerationsItems0) Validate(formats strfmt.Registry) error {
return nil
}
func (m *ZoneTolerationsItems0) validateTolerationSeconds(formats strfmt.Registry) error {
func (m *PoolTolerationsItems0) validateTolerationSeconds(formats strfmt.Registry) error {
if swag.IsZero(m.TolerationSeconds) { // not required
return nil
@@ -115,7 +115,7 @@ func (m *ZoneTolerationsItems0) validateTolerationSeconds(formats strfmt.Registr
}
// MarshalBinary interface implementation
func (m *ZoneTolerationsItems0) MarshalBinary() ([]byte, error) {
func (m *PoolTolerationsItems0) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
@@ -123,8 +123,8 @@ func (m *ZoneTolerationsItems0) MarshalBinary() ([]byte, error) {
}
// UnmarshalBinary interface implementation
func (m *ZoneTolerationsItems0) UnmarshalBinary(b []byte) error {
var res ZoneTolerationsItems0
func (m *PoolTolerationsItems0) UnmarshalBinary(b []byte) error {
var res PoolTolerationsItems0
if err := swag.ReadJSON(b, &res); err != nil {
return err
}

View File

@@ -31,21 +31,21 @@ import (
"github.com/go-openapi/validate"
)
// ZoneUpdateRequest zone update request
// PoolUpdateRequest pool update request
//
// swagger:model zoneUpdateRequest
type ZoneUpdateRequest struct {
// swagger:model poolUpdateRequest
type PoolUpdateRequest struct {
// zones
// pools
// Required: true
Zones []*Zone `json:"zones"`
Pools []*Pool `json:"pools"`
}
// Validate validates this zone update request
func (m *ZoneUpdateRequest) Validate(formats strfmt.Registry) error {
// Validate validates this pool update request
func (m *PoolUpdateRequest) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateZones(formats); err != nil {
if err := m.validatePools(formats); err != nil {
res = append(res, err)
}
@@ -55,21 +55,21 @@ func (m *ZoneUpdateRequest) Validate(formats strfmt.Registry) error {
return nil
}
func (m *ZoneUpdateRequest) validateZones(formats strfmt.Registry) error {
func (m *PoolUpdateRequest) validatePools(formats strfmt.Registry) error {
if err := validate.Required("zones", "body", m.Zones); err != nil {
if err := validate.Required("pools", "body", m.Pools); err != nil {
return err
}
for i := 0; i < len(m.Zones); i++ {
if swag.IsZero(m.Zones[i]) { // not required
for i := 0; i < len(m.Pools); i++ {
if swag.IsZero(m.Pools[i]) { // not required
continue
}
if m.Zones[i] != nil {
if err := m.Zones[i].Validate(formats); err != nil {
if m.Pools[i] != nil {
if err := m.Pools[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("zones" + "." + strconv.Itoa(i))
return ve.ValidateName("pools" + "." + strconv.Itoa(i))
}
return err
}
@@ -81,7 +81,7 @@ func (m *ZoneUpdateRequest) validateZones(formats strfmt.Registry) error {
}
// MarshalBinary interface implementation
func (m *ZoneUpdateRequest) MarshalBinary() ([]byte, error) {
func (m *PoolUpdateRequest) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
@@ -89,8 +89,8 @@ func (m *ZoneUpdateRequest) MarshalBinary() ([]byte, error) {
}
// UnmarshalBinary interface implementation
func (m *ZoneUpdateRequest) UnmarshalBinary(b []byte) error {
var res ZoneUpdateRequest
func (m *PoolUpdateRequest) UnmarshalBinary(b []byte) error {
var res PoolUpdateRequest
if err := swag.ReadJSON(b, &res); err != nil {
return err
}

View File

@@ -32,17 +32,23 @@ import (
// swagger:model principal
type Principal struct {
// access key ID
AccessKeyID string `json:"accessKeyID,omitempty"`
// s t s access key ID
STSAccessKeyID string `json:"STSAccessKeyID,omitempty"`
// s t s secret access key
STSSecretAccessKey string `json:"STSSecretAccessKey,omitempty"`
// s t s session token
STSSessionToken string `json:"STSSessionToken,omitempty"`
// account access key
AccountAccessKey string `json:"accountAccessKey,omitempty"`
// account secret key
AccountSecretKey string `json:"accountSecretKey,omitempty"`
// actions
Actions []string `json:"actions"`
// secret access key
SecretAccessKey string `json:"secretAccessKey,omitempty"`
// session token
SessionToken string `json:"sessionToken,omitempty"`
}
// Validate validates this principal

View File

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

View File

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

View File

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

View File

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

103
models/result_target.go Normal file
View File

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

View File

@@ -36,6 +36,9 @@ import (
// swagger:model sessionResponse
type SessionResponse struct {
// operator
Operator bool `json:"operator,omitempty"`
// pages
Pages []string `json:"pages"`

View File

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

View File

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

View File

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

View File

@@ -50,6 +50,9 @@ type Tenant struct {
// enable prometheus
EnablePrometheus bool `json:"enable_prometheus,omitempty"`
// endpoints
Endpoints *TenantEndpoints `json:"endpoints,omitempty"`
// image
Image string `json:"image,omitempty"`
@@ -59,18 +62,29 @@ type Tenant struct {
// namespace
Namespace string `json:"namespace,omitempty"`
// pools
Pools []*Pool `json:"pools"`
// subnet license
SubnetLicense *License `json:"subnet_license,omitempty"`
// total size
TotalSize int64 `json:"total_size,omitempty"`
// zones
Zones []*Zone `json:"zones"`
}
// Validate validates this tenant
func (m *Tenant) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateZones(formats); err != nil {
if err := m.validateEndpoints(formats); err != nil {
res = append(res, err)
}
if err := m.validatePools(formats); err != nil {
res = append(res, err)
}
if err := m.validateSubnetLicense(formats); err != nil {
res = append(res, err)
}
@@ -80,21 +94,39 @@ func (m *Tenant) Validate(formats strfmt.Registry) error {
return nil
}
func (m *Tenant) validateZones(formats strfmt.Registry) error {
func (m *Tenant) validateEndpoints(formats strfmt.Registry) error {
if swag.IsZero(m.Zones) { // not required
if swag.IsZero(m.Endpoints) { // not required
return nil
}
for i := 0; i < len(m.Zones); i++ {
if swag.IsZero(m.Zones[i]) { // not required
if m.Endpoints != nil {
if err := m.Endpoints.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("endpoints")
}
return err
}
}
return nil
}
func (m *Tenant) validatePools(formats strfmt.Registry) error {
if swag.IsZero(m.Pools) { // not required
return nil
}
for i := 0; i < len(m.Pools); i++ {
if swag.IsZero(m.Pools[i]) { // not required
continue
}
if m.Zones[i] != nil {
if err := m.Zones[i].Validate(formats); err != nil {
if m.Pools[i] != nil {
if err := m.Pools[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("zones" + "." + strconv.Itoa(i))
return ve.ValidateName("pools" + "." + strconv.Itoa(i))
}
return err
}
@@ -105,6 +137,24 @@ func (m *Tenant) validateZones(formats strfmt.Registry) error {
return nil
}
func (m *Tenant) validateSubnetLicense(formats strfmt.Registry) error {
if swag.IsZero(m.SubnetLicense) { // not required
return nil
}
if m.SubnetLicense != nil {
if err := m.SubnetLicense.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("subnet_license")
}
return err
}
}
return nil
}
// MarshalBinary interface implementation
func (m *Tenant) MarshalBinary() ([]byte, error) {
if m == nil {
@@ -122,3 +172,38 @@ func (m *Tenant) UnmarshalBinary(b []byte) error {
*m = res
return nil
}
// TenantEndpoints tenant endpoints
//
// swagger:model TenantEndpoints
type TenantEndpoints struct {
// console
Console string `json:"console,omitempty"`
// minio
Minio string `json:"minio,omitempty"`
}
// Validate validates this tenant endpoints
func (m *TenantEndpoints) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *TenantEndpoints) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *TenantEndpoints) UnmarshalBinary(b []byte) error {
var res TenantEndpoints
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -50,14 +50,14 @@ type TenantList struct {
// namespace
Namespace string `json:"namespace,omitempty"`
// pool count
PoolCount int64 `json:"pool_count,omitempty"`
// total size
TotalSize int64 `json:"total_size,omitempty"`
// volume count
VolumeCount int64 `json:"volume_count,omitempty"`
// zone count
ZoneCount int64 `json:"zone_count,omitempty"`
}
// Validate validates this tenant list

219
models/widget.go Normal file
View File

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

63
models/widget_result.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) 2020 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// WidgetResult widget result
//
// swagger:model widgetResult
type WidgetResult struct {
// metric
Metric map[string]string `json:"metric,omitempty"`
// values
Values []interface{} `json:"values"`
}
// Validate validates this widget result
func (m *WidgetResult) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *WidgetResult) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *WidgetResult) UnmarshalBinary(b []byte) error {
var res WidgetResult
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -22,26 +22,28 @@ import (
// endpoints definition
var (
configuration = "/configurations-list"
users = "/users"
groups = "/groups"
iamPolicies = "/policies"
dashboard = "/dashboard"
profiling = "/profiling"
trace = "/trace"
logs = "/logs"
watch = "/watch"
notifications = "/notification-endpoints"
buckets = "/buckets"
bucketsDetail = "/buckets/:bucketName"
serviceAccounts = "/service-accounts"
tenants = "/tenants"
tenantsDetail = "/namespaces/:tenantNamespace/tenants/:tenantName"
heal = "/heal"
remoteBuckets = "/remote-buckets"
replication = "/replication"
objectBrowser = "/object-browser/:bucket?"
mainObjectBrowser = "/object-browser"
configuration = "/settings"
users = "/users"
groups = "/groups"
iamPolicies = "/policies"
dashboard = "/dashboard"
profiling = "/profiling"
buckets = "/buckets"
bucketsDetail = "/buckets/:bucketName"
serviceAccounts = "/account"
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"
)
type ConfigurationActionSet struct {
@@ -59,16 +61,6 @@ var configurationActionSet = ConfigurationActionSet{
),
}
// logsActionSet contains the list of admin actions required for this endpoint to work
var logsActionSet = ConfigurationActionSet{
actionTypes: iampolicy.NewActionSet(
iampolicy.AllAdminActions,
),
actions: iampolicy.NewActionSet(
iampolicy.ConsoleLogAdminAction,
),
}
// dashboardActionSet contains the list of admin actions required for this endpoint to work
var dashboardActionSet = ConfigurationActionSet{
actionTypes: iampolicy.NewActionSet(
@@ -117,16 +109,6 @@ var profilingActionSet = ConfigurationActionSet{
),
}
// traceActionSet contains the list of admin actions required for this endpoint to work
var traceActionSet = ConfigurationActionSet{
actionTypes: iampolicy.NewActionSet(
iampolicy.AllAdminActions,
),
actions: iampolicy.NewActionSet(
iampolicy.TraceAdminAction,
),
}
// usersActionSet contains the list of admin actions required for this endpoint to work
var usersActionSet = ConfigurationActionSet{
actionTypes: iampolicy.NewActionSet(
@@ -142,28 +124,6 @@ var usersActionSet = ConfigurationActionSet{
),
}
// watchActionSet contains the list of admin actions required for this endpoint to work
var watchActionSet = ConfigurationActionSet{
actionTypes: iampolicy.NewActionSet(
iampolicy.AllAdminActions,
),
actions: iampolicy.NewActionSet(
iampolicy.ListenBucketNotificationAction,
),
}
// notificationsActionSet contains the list of admin actions required for this endpoint to work
var notificationsActionSet = ConfigurationActionSet{
actionTypes: iampolicy.NewActionSet(
iampolicy.AllActions,
),
actions: iampolicy.NewActionSet(
iampolicy.ListenBucketNotificationAction,
iampolicy.PutBucketNotificationAction,
iampolicy.GetBucketNotificationAction,
),
}
// bucketsActionSet contains the list of admin actions required for this endpoint to work
var bucketsActionSet = ConfigurationActionSet{
actionTypes: iampolicy.NewActionSet(
@@ -202,16 +162,6 @@ var tenantsActionSet = ConfigurationActionSet{
actions: iampolicy.NewActionSet(),
}
// healActionSet contains the list of admin actions required for this endpoint to work
var healActionSet = ConfigurationActionSet{
actionTypes: iampolicy.NewActionSet(
iampolicy.AllAdminActions,
),
actions: iampolicy.NewActionSet(
iampolicy.HealAdminAction,
),
}
var remoteBucketsActionSet = ConfigurationActionSet{
actionTypes: iampolicy.NewActionSet(
iampolicy.AllAdminActions,
@@ -236,32 +186,91 @@ var objectBrowserActionSet = ConfigurationActionSet{
actions: iampolicy.NewActionSet(),
}
// licenseActionSet no actions needed for this module to work
var licenseActionSet = ConfigurationActionSet{
actionTypes: iampolicy.NewActionSet(),
actions: iampolicy.NewActionSet(),
}
// watchActionSet contains the list of admin actions required for this endpoint to work
var watchActionSet = ConfigurationActionSet{
actionTypes: iampolicy.NewActionSet(
iampolicy.AllAdminActions,
),
actions: iampolicy.NewActionSet(
iampolicy.ListenBucketNotificationAction,
),
}
// healActionSet contains the list of admin actions required for this endpoint to work
var healActionSet = ConfigurationActionSet{
actionTypes: iampolicy.NewActionSet(
iampolicy.AllAdminActions,
),
actions: iampolicy.NewActionSet(
iampolicy.HealAdminAction,
),
}
// logsActionSet contains the list of admin actions required for this endpoint to work
var logsActionSet = ConfigurationActionSet{
actionTypes: iampolicy.NewActionSet(
iampolicy.AllAdminActions,
),
actions: iampolicy.NewActionSet(
iampolicy.ConsoleLogAdminAction,
),
}
// traceActionSet contains the list of admin actions required for this endpoint to work
var traceActionSet = ConfigurationActionSet{
actionTypes: iampolicy.NewActionSet(
iampolicy.AllAdminActions,
),
actions: iampolicy.NewActionSet(
iampolicy.TraceAdminAction,
),
}
// healthInfoActionSet contains the list of admin actions required for this endpoint to work
var healthInfoActionSet = ConfigurationActionSet{
actionTypes: iampolicy.NewActionSet(
iampolicy.AllAdminActions,
),
actions: iampolicy.NewActionSet(
iampolicy.HealthInfoAdminAction,
),
}
// endpointRules contains the mapping between endpoints and ActionSets, additional rules can be added here
var endpointRules = map[string]ConfigurationActionSet{
configuration: configurationActionSet,
users: usersActionSet,
groups: groupsActionSet,
iamPolicies: iamPoliciesActionSet,
dashboard: dashboardActionSet,
profiling: profilingActionSet,
trace: traceActionSet,
logs: logsActionSet,
watch: watchActionSet,
notifications: notificationsActionSet,
buckets: bucketsActionSet,
bucketsDetail: bucketsActionSet,
serviceAccounts: serviceAccountsActionSet,
heal: healActionSet,
remoteBuckets: remoteBucketsActionSet,
replication: replicationActionSet,
objectBrowser: objectBrowserActionSet,
mainObjectBrowser: objectBrowserActionSet,
configuration: configurationActionSet,
users: usersActionSet,
groups: groupsActionSet,
iamPolicies: iamPoliciesActionSet,
dashboard: dashboardActionSet,
profiling: profilingActionSet,
buckets: bucketsActionSet,
bucketsDetail: bucketsActionSet,
serviceAccounts: serviceAccountsActionSet,
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,
}
// operatorOnly ENV variable
@@ -322,12 +331,9 @@ func GetAuthorizedEndpoints(actions []string) []string {
rangeTake = operatorRules
}
if len(actions) == 0 {
return []string{}
}
// Prepare new ActionSet structure that will hold all the user actions
userAllowedAction := actionsStringToActionSet(actions)
allowedEndpoints := []string{}
var allowedEndpoints []string
for endpoint, rules := range rangeTake {
// check if user policy matches s3:* or admin:* typesIntersection
endpointActionTypes := rules.actionTypes

View File

@@ -50,7 +50,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
args: args{
[]string{"admin:ServerInfo"},
},
want: 4,
want: 6,
},
{
name: "policies endpoint",
@@ -63,7 +63,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
"admin:ListUserPolicies",
},
},
want: 4,
want: 6,
},
{
name: "all admin endpoints",
@@ -72,7 +72,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
"admin:*",
},
},
want: 15,
want: 18,
},
{
name: "all s3 endpoints",
@@ -81,7 +81,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
"s3:*",
},
},
want: 6,
want: 7,
},
{
name: "all admin and s3 endpoints",
@@ -91,14 +91,14 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
"s3:*",
},
},
want: 18,
want: 20,
},
{
name: "no endpoints",
name: "Console User - default endpoints",
args: args{
[]string{},
},
want: 0,
want: 5,
},
}
@@ -116,7 +116,7 @@ func TestOperatorOnlyEndpoints(t *testing.T) {
"admin:*",
},
},
want: 2,
want: 3,
},
{
name: "Operator Only - all s3 endpoints",
@@ -125,7 +125,7 @@ func TestOperatorOnlyEndpoints(t *testing.T) {
"s3:*",
},
},
want: 2,
want: 3,
},
{
name: "Operator Only - all admin and s3 endpoints",
@@ -135,14 +135,14 @@ func TestOperatorOnlyEndpoints(t *testing.T) {
"s3:*",
},
},
want: 2,
want: 3,
},
{
name: "Operator Only - no endpoints",
name: "Operator Only - default endpoints",
args: args{
[]string{},
},
want: 0,
want: 3,
},
}
@@ -177,7 +177,7 @@ func TestGetActionsStringFromPolicy(t *testing.T) {
args: args{
policy: &iampolicy.AdminDiagnostics,
},
want: 6,
want: 7,
},
}
for _, tt := range tests {

View File

@@ -20,26 +20,28 @@ import (
"context"
"github.com/minio/console/pkg/auth/idp/oauth2"
"github.com/minio/minio-go/v7/pkg/credentials"
)
// IdentityProviderClient interface with all functions to be implemented
// by mock when testing, it should include all IdentityProviderClient respective api calls
// IdentityProviderI interface with all functions to be implemented
// by mock when testing, it should include all IdentityProvider respective api calls
// that are used within this project.
type IdentityProviderClient interface {
VerifyIdentity(ctx context.Context, code, state string) (*oauth2.User, error)
type IdentityProviderI interface {
VerifyIdentity(ctx context.Context, code, state string) (*credentials.Credentials, error)
GenerateLoginURL() string
}
// Interface implementation
//
// Define the structure of a IdentityProvider Client and define the functions that are actually used
// Define the structure of a IdentityProvider with Client inside and define the functions that are used
// during the authentication flow.
type IdentityProvider struct {
Client IdentityProviderClient
Client *oauth2.Provider
}
// VerifyIdentity will verify the user identity against the idp using the authorization code flow
func (c IdentityProvider) VerifyIdentity(ctx context.Context, code, state string) (*oauth2.User, error) {
func (c IdentityProvider) VerifyIdentity(ctx context.Context, code, state string) (*credentials.Credentials, error) {
return c.Client.VerifyIdentity(ctx, code, state)
}

View File

@@ -19,10 +19,16 @@
package oauth2
import (
"strings"
"github.com/minio/console/pkg/auth/utils"
"github.com/minio/minio/pkg/env"
)
func GetSTSEndpoint() string {
return strings.TrimSpace(env.Get(ConsoleMinIOServer, "http://localhost:9000"))
}
func GetIdpURL() string {
return env.Get(ConsoleIdpURL, "")
}
@@ -40,10 +46,6 @@ func GetIdpCallbackURL() string {
return env.Get(ConsoleIdpCallbackURL, "")
}
func GetIdpAdminRoles() string {
return env.Get(ConsoleIdpAdminRoles, "")
}
func IsIdpEnabled() bool {
return GetIdpURL() != "" &&
GetIdpClientID() != "" &&
@@ -64,8 +66,3 @@ var defaultSaltForIdpHmac = utils.RandomCharString(64)
func getSaltForIdpHmac() string {
return env.Get(ConsoleIdpHmacSalt, defaultSaltForIdpHmac)
}
// GetSaltForIdpHmac returns the policy to be assigned to the users authenticating via an IDP
func GetIDPPolicyForUser() string {
return env.Get(ConsoleIdpPolicyUser, "consoleAdmin")
}

View File

@@ -18,12 +18,11 @@ package oauth2
const (
// const for idp configuration
ConsoleMinIOServer = "CONSOLE_MINIO_SERVER"
ConsoleIdpURL = "CONSOLE_IDP_URL"
ConsoleIdpClientID = "CONSOLE_IDP_CLIENT_ID"
ConsoleIdpSecret = "CONSOLE_IDP_SECRET"
ConsoleIdpCallbackURL = "CONSOLE_IDP_CALLBACK"
ConsoleIdpAdminRoles = "CONSOLE_IDP_ADMIN_ROLES"
ConsoleIdpHmacPassphrase = "CONSOLE_IDP_HMAC_PASSPHRASE"
ConsoleIdpHmacSalt = "CONSOLE_IDP_HMAC_SALT"
ConsoleIdpPolicyUser = "CONSOLE_IDP_POLICY_USER"
)

View File

@@ -26,6 +26,9 @@ import (
"net/http"
"net/url"
"strings"
"time"
"github.com/minio/minio-go/v7/pkg/credentials"
"github.com/coreos/go-oidc"
"github.com/minio/console/pkg/auth/utils"
@@ -110,14 +113,13 @@ func NewOauth2ProviderClient(ctx context.Context, scopes []string) (*Provider, e
scopes = []string{oidc.ScopeOpenID, "profile", "app_metadata", "user_metadata", "email"}
}
client := new(Provider)
config := xoauth2.Config{
client.oauth2Config = &xoauth2.Config{
ClientID: GetIdpClientID(),
ClientSecret: GetIdpSecret(),
RedirectURL: GetIdpCallbackURL(),
Endpoint: provider.Endpoint(),
Scopes: scopes,
}
client.oauth2Config = &config
client.oidcProvider = provider
client.ClientID = GetIdpClientID()
@@ -137,7 +139,7 @@ type User struct {
LastLogin string `json:"last_login"`
LastPasswordReset string `json:"last_password_reset"`
LoginsCount int `json:"logins_count"`
Mltifactor string `json:"multifactor"`
MultiFactor string `json:"multifactor"`
Name string `json:"name"`
Nickname string `json:"nickname"`
PhoneNumber string `json:"phone_number"`
@@ -150,39 +152,31 @@ type User struct {
}
// VerifyIdentity will contact the configured IDP and validate the user identity based on the authorization code
func (client *Provider) VerifyIdentity(ctx context.Context, code, state string) (*User, error) {
func (client *Provider) VerifyIdentity(ctx context.Context, code, state string) (*credentials.Credentials, error) {
// verify the provided state is valid (prevents CSRF attacks)
if !validateOauth2State(state) {
return nil, errGeneric
}
// verify the authorization code against the identity oidcProvider
// idp will return a token in exchange
token, err := client.oauth2Config.Exchange(ctx, code)
getWebTokenExpiry := func() (*credentials.WebIdentityToken, error) {
oauth2Token, err := client.oauth2Config.Exchange(ctx, code)
if err != nil {
return nil, err
}
if !oauth2Token.Valid() {
return nil, errors.New("invalid token")
}
return &credentials.WebIdentityToken{
Token: oauth2Token.Extra("id_token").(string),
Expiry: int(oauth2Token.Expiry.Sub(time.Now().UTC()).Seconds()),
}, nil
}
stsEndpoint := GetSTSEndpoint()
sts, err := credentials.NewSTSWebIdentity(stsEndpoint, getWebTokenExpiry)
if err != nil {
log.Println("Failed to verify authorization code", err)
return nil, errGeneric
return nil, err
}
// extract and check id_token field is provided in the response
rawIDToken, ok := token.Extra("id_token").(string)
if !ok {
log.Println("No id_token field in oauth2 token")
return nil, errGeneric
}
config := &oidc.Config{
ClientID: client.ClientID,
}
idToken, err := client.oidcProvider.Verifier(config).Verify(ctx, rawIDToken)
if err != nil {
log.Println("Failed to verify ID token", err)
return nil, errGeneric
}
var profile User
// Populate the profile object using the claims included in the token
if err := idToken.Claims(&profile); err != nil {
log.Println("Failed to read profile information", err)
return nil, errGeneric
}
return &profile, nil
return sts, nil
}
// validateOauth2State validates the provided state was originated using the same

View File

@@ -69,30 +69,3 @@ func TestGenerateLoginURL(t *testing.T) {
url := oauth2Provider.GenerateLoginURL()
funcAssert.NotEqual("", url)
}
func TestVerifyIdentity(t *testing.T) {
ctx := context.Background()
funcAssert := assert.New(t)
// mock data
oauth2Provider := Provider{
oauth2Config: Oauth2configMock{},
oidcProvider: &oidc.Provider{},
}
// Test-1 : VerifyIdentity() should fail because of bad state token
_, err := oauth2Provider.VerifyIdentity(ctx, "AAABBBCCCDDDEEEFFF", "badtoken")
funcAssert.NotNil(err)
// Test-2 : VerifyIdentity() should fail because no id_token is provided by the idp
oauth2ConfigExchangeMock = func(ctx context.Context, code string, opts ...oauth2.AuthCodeOption) (*oauth2.Token, error) {
return &oauth2.Token{}, nil
}
state := GetRandomStateWithHMAC(32)
code := "AAABBBCCCDDDEEEFFF"
_, err = oauth2Provider.VerifyIdentity(ctx, code, state)
funcAssert.NotNil(err)
// Test-3 : VerifyIdentity() should fail because no id_token is provided by the idp
// TODO
// Test-4 : VerifyIdentity() should fail because oidcProvider.Verifier returned an error
// TODO
// Test-5 : VerifyIdentity() should fail because idToken.Claims contains invalid fields
// TODO
}

View File

@@ -18,7 +18,7 @@ package auth
import (
"errors"
"log"
"net/http"
"github.com/minio/minio-go/v7/pkg/credentials"
)
@@ -27,13 +27,14 @@ var (
errInvalidCredentials = errors.New("invalid Login")
)
// GetConsoleCredentialsFromLDAP authenticates the user against MinIO when the LDAP integration is enabled
// GetCredentialsFromLDAP authenticates the user against MinIO when the LDAP integration is enabled
// if the authentication succeed *credentials.Login object is returned and we continue with the normal STSAssumeRole flow
func GetConsoleCredentialsFromLDAP(endpoint, ldapUser, ldapPassword string) (*credentials.Credentials, error) {
creds, err := credentials.NewLDAPIdentity(endpoint, ldapUser, ldapPassword)
if err != nil {
log.Println("LDAP authentication error: ", err)
return nil, errInvalidCredentials
}
func GetCredentialsFromLDAP(client *http.Client, endpoint, ldapUser, ldapPassword string) (*credentials.Credentials, error) {
creds := credentials.New(&credentials.LDAPIdentity{
Client: client,
STSEndpoint: endpoint,
LDAPUsername: ldapUser,
LDAPPassword: ldapPassword,
})
return creds, nil
}

View File

@@ -24,6 +24,7 @@ import (
"crypto/sha1"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io"
@@ -58,12 +59,14 @@ func IsSessionTokenValid(token string) bool {
return err == nil
}
// DecryptedClaims claims struct for decrypted credentials
type DecryptedClaims struct {
AccessKeyID string
SecretAccessKey string
SessionToken string
Actions []string
// TokenClaims claims struct for decrypted credentials
type TokenClaims struct {
STSAccessKeyID string `json:"stsAccessKeyID,omitempty"`
STSSecretAccessKey string `json:"stsSecretAccessKey,omitempty"`
STSSessionToken string `json:"stsSessionToken,omitempty"`
AccountAccessKey string `json:"accountAccessKey,omitempty"`
AccountSecretKey string `json:"accountSecretKey,omitempty"`
Actions []string `json:"actions,omitempty"`
}
// SessionTokenAuthenticate takes a session token, decode it, extract claims and validate the signature
@@ -71,12 +74,15 @@ type DecryptedClaims struct {
//
// returns claims after validation in the following format:
//
// type DecryptedClaims struct {
// AccessKeyID
// SecretAccessKey
// SessionToken
// type TokenClaims struct {
// STSAccessKeyID
// STSSecretAccessKey
// STSSessionToken
// AccountAccessKey
// AccountSecretKey
// Actions
// }
func SessionTokenAuthenticate(token string) (*DecryptedClaims, error) {
func SessionTokenAuthenticate(token string) (*TokenClaims, error) {
if token == "" {
return nil, errNoAuthToken
}
@@ -94,9 +100,16 @@ func SessionTokenAuthenticate(token string) (*DecryptedClaims, error) {
// NewEncryptedTokenForClient generates a new session token with claims based on the provided STS credentials, first
// encrypts the claims and the sign them
func NewEncryptedTokenForClient(credentials *credentials.Value, actions []string) (string, error) {
func NewEncryptedTokenForClient(credentials *credentials.Value, accountAccessKey, accountSecretKey string, actions []string) (string, error) {
if credentials != nil {
encryptedClaims, err := encryptClaims(credentials.AccessKeyID, credentials.SecretAccessKey, credentials.SessionToken, actions)
encryptedClaims, err := encryptClaims(&TokenClaims{
STSAccessKeyID: credentials.AccessKeyID,
STSSecretAccessKey: credentials.SecretAccessKey,
STSSessionToken: credentials.SessionToken,
AccountAccessKey: accountAccessKey,
AccountSecretKey: accountSecretKey,
Actions: actions,
})
if err != nil {
return "", err
}
@@ -107,8 +120,11 @@ func NewEncryptedTokenForClient(credentials *credentials.Value, actions []string
// encryptClaims() receives the STS claims, concatenate them and encrypt them using AES-GCM
// returns a base64 encoded ciphertext
func encryptClaims(accessKeyID, secretAccessKey, sessionToken string, actions []string) (string, error) {
payload := []byte(fmt.Sprintf("%s#%s#%s#%s", accessKeyID, secretAccessKey, sessionToken, strings.Join(actions, ",")))
func encryptClaims(credentials *TokenClaims) (string, error) {
payload, err := json.Marshal(credentials)
if err != nil {
return "", err
}
ciphertext, err := encrypt(payload, []byte{})
if err != nil {
log.Println(err)
@@ -117,8 +133,8 @@ func encryptClaims(accessKeyID, secretAccessKey, sessionToken string, actions []
return base64.StdEncoding.EncodeToString(ciphertext), nil
}
// decryptClaims() receives base64 encoded ciphertext, decode it, decrypt it (AES-GCM) and produces a *DecryptedClaims object
func decryptClaims(ciphertext string) (*DecryptedClaims, error) {
// decryptClaims() receives base64 encoded ciphertext, decode it, decrypt it (AES-GCM) and produces a *TokenClaims object
func decryptClaims(ciphertext string) (*TokenClaims, error) {
decoded, err := base64.StdEncoding.DecodeString(ciphertext)
if err != nil {
log.Println(err)
@@ -129,19 +145,13 @@ func decryptClaims(ciphertext string) (*DecryptedClaims, error) {
log.Println(err)
return nil, errClaimsFormat
}
s := strings.Split(string(plaintext), "#")
// Validate that the decrypted string has the right format "accessKeyID:secretAccessKey:sessionToken"
if len(s) != 4 {
tokenClaims := &TokenClaims{}
err = json.Unmarshal(plaintext, tokenClaims)
if err != nil {
log.Println(err)
return nil, errClaimsFormat
}
accessKeyID, secretAccessKey, sessionToken, actions := s[0], s[1], s[2], s[3]
actionsList := strings.Split(actions, ",")
return &DecryptedClaims{
AccessKeyID: accessKeyID,
SecretAccessKey: secretAccessKey,
SessionToken: sessionToken,
Actions: actionsList,
}, nil
return tokenClaims, nil
}
const (
@@ -315,9 +325,11 @@ func GetClaimsFromTokenInRequest(req *http.Request) (*models.Principal, error) {
return nil, err
}
return &models.Principal{
AccessKeyID: claims.AccessKeyID,
Actions: claims.Actions,
SecretAccessKey: claims.SecretAccessKey,
SessionToken: claims.SessionToken,
STSAccessKeyID: claims.STSAccessKeyID,
Actions: claims.Actions,
STSSecretAccessKey: claims.STSSecretAccessKey,
STSSessionToken: claims.STSSessionToken,
AccountAccessKey: claims.AccountAccessKey,
AccountSecretKey: claims.AccountSecretKey,
}, nil
}

View File

@@ -23,10 +23,9 @@ import (
"github.com/minio/minio/pkg/env"
)
// ConsoleSTSAndJWTDurationSeconds returns the default session duration for the STS requested tokens and the generated JWTs.
// Ideally both values should match so jwt and Minio sts sessions expires at the same time.
func GetConsoleSTSAndJWTDurationInSeconds() int {
duration, err := strconv.Atoi(env.Get(ConsoleSTSAndJWTDurationSeconds, "3600"))
// ConsoleSTSDurationSeconds returns the default session duration for the STS requested tokens.
func GetConsoleSTSDurationInSeconds() int {
duration, err := strconv.Atoi(env.Get(ConsoleSTSDurationSeconds, "3600"))
if err != nil {
duration = 3600
}

View File

@@ -17,7 +17,7 @@
package token
const (
ConsoleSTSAndJWTDurationSeconds = "CONSOLE_STS_AND_JWT_DURATION_SECONDS"
ConsolePBKDFPassphrase = "CONSOLE_PBKDF_PASSPHRASE"
ConsolePBKDFSalt = "CONSOLE_PBKDF_SALT"
ConsoleSTSDurationSeconds = "CONSOLE_STS_DURATION_SECONDS"
ConsolePBKDFPassphrase = "CONSOLE_PBKDF_PASSPHRASE"
ConsolePBKDFSalt = "CONSOLE_PBKDF_SALT"
)

View File

@@ -36,14 +36,14 @@ func TestNewJWTWithClaimsForClient(t *testing.T) {
funcAssert := assert.New(t)
// Test-1 : NewEncryptedTokenForClient() is generated correctly without errors
function := "NewEncryptedTokenForClient()"
token, err := NewEncryptedTokenForClient(creds, []string{""})
token, err := NewEncryptedTokenForClient(creds, "", "", []string{""})
if err != nil || token == "" {
t.Errorf("Failed on %s:, error occurred: %s", function, err)
}
// saving token for future tests
goodToken = token
// Test-2 : NewEncryptedTokenForClient() throws error because of empty credentials
if _, err = NewEncryptedTokenForClient(nil, []string{""}); err != nil {
if _, err = NewEncryptedTokenForClient(nil, "", "", []string{""}); err != nil {
funcAssert.Equal("provided credentials are empty", err.Error())
}
}
@@ -56,21 +56,21 @@ func TestJWTAuthenticate(t *testing.T) {
if err != nil || claims == nil {
t.Errorf("Failed on %s:, error occurred: %s", function, err)
} else {
funcAssert.Equal(claims.AccessKeyID, creds.AccessKeyID)
funcAssert.Equal(claims.SecretAccessKey, creds.SecretAccessKey)
funcAssert.Equal(claims.SessionToken, creds.SessionToken)
funcAssert.Equal(claims.STSAccessKeyID, creds.AccessKeyID)
funcAssert.Equal(claims.STSSecretAccessKey, creds.SecretAccessKey)
funcAssert.Equal(claims.STSSessionToken, creds.SessionToken)
}
// Test-2 : SessionTokenAuthenticate() return an error because of a tampered jwt
// Test-2 : SessionTokenAuthenticate() return an error because of a tampered token
if _, err := SessionTokenAuthenticate(badToken); err != nil {
funcAssert.Equal("session token internal data is malformed", err.Error())
}
// Test-3 : SessionTokenAuthenticate() return an error because of an empty jwt
// Test-3 : SessionTokenAuthenticate() return an error because of an empty token
if _, err := SessionTokenAuthenticate(""); err != nil {
funcAssert.Equal("session token missing", err.Error())
}
}
func TestIsJWTValid(t *testing.T) {
func TestSessionTokenValid(t *testing.T) {
funcAssert := assert.New(t)
// Test-1 : SessionTokenAuthenticate() provided token is valid
funcAssert.Equal(true, IsSessionTokenValid(goodToken))

230
pkg/certs/certs.go Normal file
View File

@@ -0,0 +1,230 @@
// This file is part of MinIO Console Server
// Copyright (c) 2020 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package certs
import (
"context"
"crypto/x509"
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/minio/cli"
"github.com/minio/minio/cmd/config"
"github.com/minio/minio/cmd/logger"
xcerts "github.com/minio/minio/pkg/certs"
"github.com/mitchellh/go-homedir"
)
// ConfigDir - points to a user set directory.
type ConfigDir struct {
Path string
}
// Get - returns current directory.
func (dir *ConfigDir) Get() string {
return dir.Path
}
func getDefaultConfigDir() string {
homeDir, err := homedir.Dir()
if err != nil {
return ""
}
return filepath.Join(homeDir, DefaultConsoleConfigDir)
}
func getDefaultCertsDir() string {
return filepath.Join(getDefaultConfigDir(), CertsDir)
}
func getDefaultCertsCADir() string {
return filepath.Join(getDefaultCertsDir(), CertsCADir)
}
// isFile - returns whether given Path is a file or not.
func isFile(path string) bool {
if fi, err := os.Stat(path); err == nil {
return fi.Mode().IsRegular()
}
return false
}
var (
// DefaultCertsDir certs directory.
DefaultCertsDir = &ConfigDir{Path: getDefaultCertsDir()}
// DefaultCertsCADir CA directory.
DefaultCertsCADir = &ConfigDir{Path: getDefaultCertsCADir()}
// GlobalCertsDir points to current certs directory set by user with --certs-dir
GlobalCertsDir = DefaultCertsDir
// GlobalCertsCADir points to relative Path to certs directory and is <value-of-certs-dir>/CAs
GlobalCertsCADir = DefaultCertsCADir
)
// MkdirAllIgnorePerm attempts to create all directories, ignores any permission denied errors.
func MkdirAllIgnorePerm(path string) error {
err := os.MkdirAll(path, 0700)
if err != nil {
// It is possible in kubernetes like deployments this directory
// is already mounted and is not writable, ignore any write errors.
if os.IsPermission(err) {
err = nil
}
}
return err
}
func NewConfigDirFromCtx(ctx *cli.Context, option string, getDefaultDir func() string) (*ConfigDir, bool) {
var dir string
var dirSet bool
switch {
case ctx.IsSet(option):
dir = ctx.String(option)
dirSet = true
case ctx.GlobalIsSet(option):
dir = ctx.GlobalString(option)
dirSet = true
// cli package does not expose parent's option option. Below code is workaround.
if dir == "" || dir == getDefaultDir() {
dirSet = false // Unset to false since GlobalIsSet() true is a false positive.
if ctx.Parent().GlobalIsSet(option) {
dir = ctx.Parent().GlobalString(option)
dirSet = true
}
}
default:
// Neither local nor global option is provided. In this case, try to use
// default directory.
dir = getDefaultDir()
if dir == "" {
logger.FatalIf(errors.New("invalid arguments specified"), "%s option must be provided", option)
}
}
if dir == "" {
logger.FatalIf(errors.New("empty directory"), "%s directory cannot be empty", option)
}
// Disallow relative paths, figure out absolute paths.
dirAbs, err := filepath.Abs(dir)
logger.FatalIf(err, "Unable to fetch absolute path for %s=%s", option, dir)
logger.FatalIf(MkdirAllIgnorePerm(dirAbs), "Unable to create directory specified %s=%s", option, dir)
return &ConfigDir{Path: dirAbs}, dirSet
}
func getPublicCertFile() string {
return filepath.Join(GlobalCertsDir.Get(), PublicCertFile)
}
func getPrivateKeyFile() string {
return filepath.Join(GlobalCertsDir.Get(), PrivateKeyFile)
}
func GetTLSConfig() (x509Certs []*x509.Certificate, manager *xcerts.Manager, err error) {
ctx := context.Background()
if !(isFile(getPublicCertFile()) && isFile(getPrivateKeyFile())) {
return nil, nil, nil
}
if x509Certs, err = config.ParsePublicCertFile(getPublicCertFile()); err != nil {
return nil, nil, err
}
manager, err = xcerts.NewManager(ctx, getPublicCertFile(), getPrivateKeyFile(), config.LoadX509KeyPair)
if err != nil {
return nil, nil, err
}
//Console has support for multiple certificates. It expects the following structure:
// certs/
// │
// ├─ public.crt
// ├─ private.key
// │
// ├─ example.com/
// │ │
// │ ├─ public.crt
// │ └─ private.key
// └─ foobar.org/
// │
// ├─ public.crt
// └─ private.key
// ...
//
//Therefore, we read all filenames in the cert directory and check
//for each directory whether it contains a public.crt and private.key.
// If so, we try to add it to certificate manager.
root, err := os.Open(GlobalCertsDir.Get())
if err != nil {
return nil, nil, err
}
defer root.Close()
files, err := root.Readdir(-1)
if err != nil {
return nil, nil, err
}
for _, file := range files {
// Ignore all
// - regular files
// - "CAs" directory
// - any directory which starts with ".."
if file.Mode().IsRegular() || file.Name() == "CAs" || strings.HasPrefix(file.Name(), "..") {
continue
}
if file.Mode()&os.ModeSymlink == os.ModeSymlink {
file, err = os.Stat(filepath.Join(root.Name(), file.Name()))
if err != nil {
// not accessible ignore
continue
}
if !file.IsDir() {
continue
}
}
var (
certFile = filepath.Join(root.Name(), file.Name(), PublicCertFile)
keyFile = filepath.Join(root.Name(), file.Name(), PrivateKeyFile)
)
if !isFile(certFile) || !isFile(keyFile) {
continue
}
if err = manager.AddCertificate(certFile, keyFile); err != nil {
err = fmt.Errorf("unable to load TLS certificate '%s,%s': %w", certFile, keyFile, err)
logger.LogIf(ctx, err, logger.Application)
}
}
return x509Certs, manager, nil
}
func GetAllCertificatesAndCAs() (*x509.CertPool, []*x509.Certificate, *xcerts.Manager) {
// load all CAs from ~/.console/certs/CAs
GlobalRootCAs, err := xcerts.GetRootCAs(GlobalCertsCADir.Get())
logger.FatalIf(err, "Failed to read root CAs (%v)", err)
// load all certs from ~/.console/certs
globalPublicCerts, globalTLSCertsManager, err := GetTLSConfig()
logger.FatalIf(err, "Unable to load the TLS configuration")
return GlobalRootCAs, globalPublicCerts, globalTLSCertsManager
}

34
pkg/certs/const.go Normal file
View File

@@ -0,0 +1,34 @@
// This file is part of MinIO Console Server
// Copyright (c) 2020 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package certs
const (
// Default minio configuration directory where below configuration files/directories are stored.
DefaultConsoleConfigDir = ".console"
// Directory contains below files/directories for HTTPS configuration.
CertsDir = "certs"
// Directory contains all CA certificates other than system defaults for HTTPS.
CertsCADir = "CAs"
// Public certificate file for HTTPS.
PublicCertFile = "public.crt"
// Private key file for HTTPS.
PrivateKeyFile = "private.key"
)

51
pkg/subnet/config.go Normal file
View File

@@ -0,0 +1,51 @@
// This file is part of MinIO Kubernetes Cloud
// Copyright (c) 2020 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package subnet
import (
"errors"
"log"
"github.com/minio/minio/pkg/env"
"github.com/minio/minio/pkg/licverifier"
)
// GetSubnetURL
func GetSubnetURL() string {
return env.Get(ConsoleSubnetURL, "https://subnet.min.io")
}
// GetLicenseInfoFromJWT will return license metadata from a jwt string license
func GetLicenseInfoFromJWT(license string, publicKeys []string) (*licverifier.LicenseInfo, error) {
if license == "" {
return nil, errors.New("license is not present")
}
for _, publicKey := range publicKeys {
lv, err := licverifier.NewLicenseVerifier([]byte(publicKey))
if err != nil {
log.Print(err)
continue
}
licInfo, err := lv.Verify(license)
if err != nil {
log.Print(err)
continue
}
return &licInfo, nil
}
return nil, errors.New("invalid license key")
}

88
pkg/subnet/config_test.go Normal file
View File

@@ -0,0 +1,88 @@
// This file is part of MinIO Kubernetes Cloud
// Copyright (c) 2020 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package subnet
import (
"reflect"
"testing"
"github.com/minio/minio/pkg/licverifier"
)
func TestGetLicenseInfoFromJWT(t *testing.T) {
license := "eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZW5pbitjMUBtaW5pby5pbyIsInRlYW1OYW1lIjoiY29uc29sZS1jdXN0b21lciIsImV4cCI6MS42Mzk5NTI2MTE2MDkxNDQ3MzJlOSwiaXNzIjoic3VibmV0QG1pbmlvLmlvIiwiY2FwYWNpdHkiOjI1LCJpYXQiOjEuNjA4NDE2NjExNjA5MTQ0NzMyZTksImFjY291bnRJZCI6MTc2LCJzZXJ2aWNlVHlwZSI6IlNUQU5EQVJEIn0.ndtf8V_FJTvhXeemVLlORyDev6RJaSPhZ2djkMVK9SvXD0srR_qlYJATPjC4NljkS71nXMGVDov5uCTuUL97x6FGQEKDruA-z24x_2Zr8kof4LfBb3HUHudCR8QvE--I"
publicKeys := []string{`-----BEGIN PUBLIC KEY-----
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEbo+e1wpBY4tBq9AONKww3Kq7m6QP/TBQ
mr/cKCUyBL7rcAvg0zNq1vcSrUSGlAmY3SEDCu3GOKnjG/U4E7+p957ocWSV+mQU
9NKlTdQFGF3+aO6jbQ4hX/S5qPyF+a3z
-----END PUBLIC KEY-----`}
mockLicense, _ := GetLicenseInfoFromJWT(license, publicKeys)
type args struct {
license string
publicKeys []string
}
tests := []struct {
name string
args args
want *licverifier.LicenseInfo
wantErr bool
}{
{
name: "error because missing license",
args: args{
license: "",
publicKeys: OfflinePublicKeys,
},
wantErr: true,
},
{
name: "error because invalid license",
args: args{
license: "eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZW5pbitjMUBtaW5pby5pbyIsInRlYW1OYW1lIjoiY29uc29sZS1jdXN0b21lciIsImV4cCI6MS42Mzk5NTI2MTE2MDkxNDQ3MzJlOSwiaXNzIjoic3VibmV0QG1pbmlvLmlvIiwiY2FwYWNpdHkiOjI1LCJpYXQiOjEuNjA4NDE2NjExNjA5MTQ0NzMyZTksImFjY291bnRJZCI6MTc2LCJzZXJ2aWNlVHlwZSI6IlNUQU5EQVJEIn0.ndtf8V_FJTvhXeemVLlORyDev6RJaSPhZ2djkMVK9SvXD0srR_qlYJATPjC4NljkS71nXMGVDov5uCTuUL97x6FGQEKDruA-z24x_2Zr8kof4LfBb3HUHudCR8QvE--I",
publicKeys: []string{"eaeaeae"},
},
wantErr: true,
},
{
name: "license successfully verified",
args: args{
license: "eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZW5pbitjMUBtaW5pby5pbyIsInRlYW1OYW1lIjoiY29uc29sZS1jdXN0b21lciIsImV4cCI6MS42Mzk5NTI2MTE2MDkxNDQ3MzJlOSwiaXNzIjoic3VibmV0QG1pbmlvLmlvIiwiY2FwYWNpdHkiOjI1LCJpYXQiOjEuNjA4NDE2NjExNjA5MTQ0NzMyZTksImFjY291bnRJZCI6MTc2LCJzZXJ2aWNlVHlwZSI6IlNUQU5EQVJEIn0.ndtf8V_FJTvhXeemVLlORyDev6RJaSPhZ2djkMVK9SvXD0srR_qlYJATPjC4NljkS71nXMGVDov5uCTuUL97x6FGQEKDruA-z24x_2Zr8kof4LfBb3HUHudCR8QvE--I",
publicKeys: []string{`-----BEGIN PUBLIC KEY-----
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEbo+e1wpBY4tBq9AONKww3Kq7m6QP/TBQ
mr/cKCUyBL7rcAvg0zNq1vcSrUSGlAmY3SEDCu3GOKnjG/U4E7+p957ocWSV+mQU
9NKlTdQFGF3+aO6jbQ4hX/S5qPyF+a3z
-----END PUBLIC KEY-----`},
},
wantErr: false,
want: mockLicense,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := GetLicenseInfoFromJWT(tt.args.license, tt.args.publicKeys)
if (err != nil) != tt.wantErr {
t.Errorf("GetLicenseInfoFromJWT() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("GetLicenseInfoFromJWT() got = %v, want %v", got, tt.want)
}
})
}
}

36
pkg/subnet/const.go Normal file
View File

@@ -0,0 +1,36 @@
// This file is part of MinIO Kubernetes Cloud
// Copyright (c) 2020 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package subnet
var (
OfflinePublicKeys = []string{
`-----BEGIN PUBLIC KEY-----
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEaK31xujr6/rZ7ZfXZh3SlwovjC+X8wGq
qkltaKyTLRENd4w3IRktYYCRgzpDLPn/nrf7snV/ERO5qcI7fkEES34IVEr+2Uff
JkO2PfyyAYEO/5dBlPh1Undu9WQl6J7B
-----END PUBLIC KEY-----`, // https://subnet.min.io/downloads/license-pubkey.pem
}
)
const (
// Constants for subnet configuration
ConsoleSubnetURL = "CONSOLE_SUBNET_URL"
// Subnet endpoints
publicKey = "/downloads/license-pubkey.pem"
loginEndpoint = "/api/auth/login"
licenseKeyEndpoint = "/api/auth/subscription/license-key"
)

173
pkg/subnet/subnet.go Normal file
View File

@@ -0,0 +1,173 @@
// This file is part of MinIO Console Server
// Copyright (c) 2020 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package subnet
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
"net/http"
"github.com/minio/console/cluster"
"github.com/minio/minio/pkg/licverifier"
)
// subnetLoginRequest body request for subnet login
type subnetLoginRequest struct {
Username string `json:"username"`
Password string `json:"password"`
}
// tokenInfo
type tokenInfo struct {
AccessToken string `json:"access_token"`
ExpiresIn float64 `json:"expires_in"`
TokenType string `json:"token_type"`
}
// subnetLoginResponse body resonse from subnet after login
type subnetLoginResponse struct {
HasMembership bool `json:"has_memberships"`
TokenInfo tokenInfo `json:"token_info"`
}
// LicenseMetadata claims in subnet license
type LicenseMetadata struct {
Email string `json:"email"`
Issuer string `json:"issuer"`
TeamName string `json:"teamName"`
ServiceType string `json:"serviceType"`
RequestedAt string `json:"requestedAt"`
ExpiresAt string `json:"expiresAt"`
AccountID int64 `json:"accountId"`
Capacity int64 `json:"capacity"`
}
// subnetLicenseResponse body response returned by subnet license endpoint
type subnetLicenseResponse struct {
License string `json:"license"`
Metadata LicenseMetadata `json:"metadata"`
}
// getLicenseFromCredentials will perform authentication against subnet using
// user provided credentials and return the current subnet license key
func getLicenseFromCredentials(client cluster.HTTPClientI, username, password string) (string, error) {
request := subnetLoginRequest{
Username: username,
Password: password,
}
// http body for login request
payloadBytes, err := json.Marshal(request)
if err != nil {
return "", err
}
subnetURL := GetSubnetURL()
url := fmt.Sprintf("%s%s", subnetURL, loginEndpoint)
// Authenticate against subnet using email/password provided by user
resp, err := client.Post(url, "application/json", bytes.NewReader(payloadBytes))
if err != nil {
return "", err
}
defer resp.Body.Close()
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
subnetSession := &subnetLoginResponse{}
// Parse subnet login response
err = json.Unmarshal(bodyBytes, subnetSession)
if err != nil {
return "", err
}
// Get license key using session token
token := subnetSession.TokenInfo.AccessToken
url = fmt.Sprintf("%s%s", subnetURL, licenseKeyEndpoint)
req, err := http.NewRequest("POST", url, nil)
if err != nil {
return "", err
}
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))
resp, err = client.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
bodyBytes, err = ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
userLicense := &subnetLicenseResponse{}
// Parse subnet license response
err = json.Unmarshal(bodyBytes, userLicense)
if err != nil {
return "", err
}
return userLicense.License, nil
}
// downloadSubnetPublicKey will download the current subnet public key.
func downloadSubnetPublicKey(client cluster.HTTPClientI) (string, error) {
// Get the public key directly from Subnet
url := fmt.Sprintf("%s%s", GetSubnetURL(), publicKey)
resp, err := client.Get(url)
if err != nil {
return "", err
}
defer resp.Body.Close()
buf := new(bytes.Buffer)
_, err = buf.ReadFrom(resp.Body)
if err != nil {
return "", err
}
return buf.String(), err
}
// ValidateLicense will download the current subnet public key, if the public key its not available for license
// verification then console will fall back to verification with hardcoded public keys
func ValidateLicense(client cluster.HTTPClientI, licenseKey, email, password string) (licInfo *licverifier.LicenseInfo, license string, err error) {
var publicKeys []string
if email != "" && password != "" {
// fetch subnet license key using user credentials
license, err = getLicenseFromCredentials(client, email, password)
if err != nil {
return nil, "", err
}
} else if licenseKey != "" {
license = licenseKey
} else {
return nil, "", errors.New("invalid license")
}
subnetPubKey, err := downloadSubnetPublicKey(client)
if err != nil {
log.Print(err)
// there was an issue getting the subnet public key
// use hardcoded public keys instead
publicKeys = OfflinePublicKeys
} else {
publicKeys = append(publicKeys, subnetPubKey)
}
licInfo, err = GetLicenseInfoFromJWT(license, publicKeys)
if err != nil {
return nil, "", err
}
return licInfo, license, nil
}

330
pkg/subnet/subnet_test.go Normal file
View File

@@ -0,0 +1,330 @@
// This file is part of MinIO Kubernetes Cloud
// Copyright (c) 2020 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package subnet
import (
"bytes"
"io"
"io/ioutil"
"net/http"
"testing"
"errors"
)
var HTTPGetMock func(url string) (resp *http.Response, err error)
var HTTPPostMock func(url, contentType string, body io.Reader) (resp *http.Response, err error)
var HTTPDoMock func(req *http.Request) (*http.Response, error)
type HTTPClientMock struct {
Client *http.Client
}
func (c *HTTPClientMock) Get(url string) (resp *http.Response, err error) {
return HTTPGetMock(url)
}
func (c *HTTPClientMock) Post(url, contentType string, body io.Reader) (resp *http.Response, err error) {
return HTTPPostMock(url, contentType, body)
}
func (c *HTTPClientMock) Do(req *http.Request) (*http.Response, error) {
return HTTPDoMock(req)
}
func Test_getLicenseFromCredentials(t *testing.T) {
// HTTP Client mock
clientMock := HTTPClientMock{
Client: &http.Client{},
}
type args struct {
client HTTPClientMock
username string
password string
}
tests := []struct {
name string
args args
want string
wantErr bool
mockFunc func()
}{
{
name: "error when login against subnet",
args: args{
client: clientMock,
username: "invalid",
password: "invalid",
},
want: "",
wantErr: true,
mockFunc: func() {
HTTPPostMock = func(url, contentType string, body io.Reader) (resp *http.Response, err error) {
return nil, errors.New("something went wrong")
}
},
},
{
name: "error because of malformed subnet response",
args: args{
client: clientMock,
username: "invalid",
password: "invalid",
},
want: "",
wantErr: true,
mockFunc: func() {
HTTPPostMock = func(url, contentType string, body io.Reader) (resp *http.Response, err error) {
return &http.Response{Body: ioutil.NopCloser(bytes.NewReader([]byte("foo")))}, nil
}
},
},
{
name: "error when obtaining license from subnet",
args: args{
client: clientMock,
username: "valid",
password: "valid",
},
want: "",
wantErr: true,
mockFunc: func() {
HTTPPostMock = func(url, contentType string, body io.Reader) (resp *http.Response, err error) {
// returning test jwt token
return &http.Response{Body: ioutil.NopCloser(bytes.NewReader([]byte("{\"has_memberships\":true,\"token_info\":{\"access_token\":\"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik4wRXdOa1V5UXpORU1UUkNOekU0UmpSR1JVWkJSa1UxUmtZNE9EY3lOekZHTXpjNU1qZ3hNZyJ9.eyJodHRwczovL2lkLnN1Ym5ldC5taW4uaW8vY2xhaW1zL2dyb3VwcyI6W10sImh0dHBzOi8vaWQuc3VibmV0Lm1pbi5pby9jbGFpbXMvcm9sZXMiOltdLCJodHRwczovL2lkLnN1Ym5ldC5taW4uaW8vY2xhaW1zL2VtYWlsIjoibGVuaW4rYzFAbWluaW8uaW8iLCJpc3MiOiJodHRwczovL2lkLnN1Ym5ldC5taW4uaW8vIiwic3ViIjoiYXV0aDB8NWZjZWFlYTMyNTNhZjEwMDc3NDZkMDM0IiwiYXVkIjoiaHR0cHM6Ly9zdWJuZXQubWluLmlvL2FwaSIsImlhdCI6MTYwODQxNjE5NiwiZXhwIjoxNjExMDA4MTk2LCJhenAiOiI1WTA0eVZlejNiOFgxUFVzRHVqSmxuZXVuY3ExVjZxaiIsInNjb3BlIjoib2ZmbGluZV9hY2Nlc3MiLCJndHkiOiJwYXNzd29yZCJ9.GC8DRLT0jUEteuBZBmyMXMswLSblCr_89Gu5NcVRUzKSYAaZ5VFW4UFgo1BpiC0sePuWJ0Vykitphx7znTfZfj5B3mZbOw3ejG6kxz7nm9DuYMmySJFYnwroZ9EP02vkW7-n_-YvEg8le1wXfkJ3lTUzO3aWddS4rfQRsZ2YJJUj61GiNyEK_QNP4PrYOuzLyD1wV75NejFqfcFoj7nRkT1K2BM0-89-_f2AFDGTjov6Ig6s1s-zLC9wxcYSmubNwpCJytZmQgPqIepOr065Y6OB4n0n0B5sXguuGuzb8VAkECrHhHPz8ta926fc0jC4XxVCNKdbV1_qC3-1yY7AJA\",\"expires_in\":2592000.0,\"token_type\":\"Bearer\"}}")))}, nil
}
HTTPDoMock = func(req *http.Request) (*http.Response, error) {
return nil, errors.New("something went wrong")
}
},
},
{
name: "error when obtaining license from subnet because of malformed response",
args: args{
client: clientMock,
username: "valid",
password: "valid",
},
want: "",
wantErr: true,
mockFunc: func() {
HTTPPostMock = func(url, contentType string, body io.Reader) (resp *http.Response, err error) {
// returning test jwt token
return &http.Response{Body: ioutil.NopCloser(bytes.NewReader([]byte("{\"has_memberships\":true,\"token_info\":{\"access_token\":\"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik4wRXdOa1V5UXpORU1UUkNOekU0UmpSR1JVWkJSa1UxUmtZNE9EY3lOekZHTXpjNU1qZ3hNZyJ9.eyJodHRwczovL2lkLnN1Ym5ldC5taW4uaW8vY2xhaW1zL2dyb3VwcyI6W10sImh0dHBzOi8vaWQuc3VibmV0Lm1pbi5pby9jbGFpbXMvcm9sZXMiOltdLCJodHRwczovL2lkLnN1Ym5ldC5taW4uaW8vY2xhaW1zL2VtYWlsIjoibGVuaW4rYzFAbWluaW8uaW8iLCJpc3MiOiJodHRwczovL2lkLnN1Ym5ldC5taW4uaW8vIiwic3ViIjoiYXV0aDB8NWZjZWFlYTMyNTNhZjEwMDc3NDZkMDM0IiwiYXVkIjoiaHR0cHM6Ly9zdWJuZXQubWluLmlvL2FwaSIsImlhdCI6MTYwODQxNjE5NiwiZXhwIjoxNjExMDA4MTk2LCJhenAiOiI1WTA0eVZlejNiOFgxUFVzRHVqSmxuZXVuY3ExVjZxaiIsInNjb3BlIjoib2ZmbGluZV9hY2Nlc3MiLCJndHkiOiJwYXNzd29yZCJ9.GC8DRLT0jUEteuBZBmyMXMswLSblCr_89Gu5NcVRUzKSYAaZ5VFW4UFgo1BpiC0sePuWJ0Vykitphx7znTfZfj5B3mZbOw3ejG6kxz7nm9DuYMmySJFYnwroZ9EP02vkW7-n_-YvEg8le1wXfkJ3lTUzO3aWddS4rfQRsZ2YJJUj61GiNyEK_QNP4PrYOuzLyD1wV75NejFqfcFoj7nRkT1K2BM0-89-_f2AFDGTjov6Ig6s1s-zLC9wxcYSmubNwpCJytZmQgPqIepOr065Y6OB4n0n0B5sXguuGuzb8VAkECrHhHPz8ta926fc0jC4XxVCNKdbV1_qC3-1yY7AJA\",\"expires_in\":2592000.0,\"token_type\":\"Bearer\"}}")))}, nil
}
HTTPDoMock = func(req *http.Request) (*http.Response, error) {
return &http.Response{Body: ioutil.NopCloser(bytes.NewReader([]byte("foo")))}, nil
}
},
},
{
name: "license obtained successfully",
args: args{
client: clientMock,
username: "valid",
password: "valid",
},
want: "eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZW5pbitjMUBtaW5pby5pbyIsInRlYW1OYW1lIjoiY29uc29sZS1jdXN0b21lciIsImV4cCI6MS42Mzk5NTI2MTE2MDkxNDQ3MzJlOSwiaXNzIjoic3VibmV0QG1pbmlvLmlvIiwiY2FwYWNpdHkiOjI1LCJpYXQiOjEuNjA4NDE2NjExNjA5MTQ0NzMyZTksImFjY291bnRJZCI6MTc2LCJzZXJ2aWNlVHlwZSI6IlNUQU5EQVJEIn0.ndtf8V_FJTvhXeemVLlORyDev6RJaSPhZ2djkMVK9SvXD0srR_qlYJATPjC4NljkS71nXMGVDov5uCTuUL97x6FGQEKDruA-z24x_2Zr8kof4LfBb3HUHudCR8QvE--I",
wantErr: false,
mockFunc: func() {
HTTPPostMock = func(url, contentType string, body io.Reader) (resp *http.Response, err error) {
// returning test jwt token
return &http.Response{Body: ioutil.NopCloser(bytes.NewReader([]byte("{\"has_memberships\":true,\"token_info\":{\"access_token\":\"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik4wRXdOa1V5UXpORU1UUkNOekU0UmpSR1JVWkJSa1UxUmtZNE9EY3lOekZHTXpjNU1qZ3hNZyJ9.eyJodHRwczovL2lkLnN1Ym5ldC5taW4uaW8vY2xhaW1zL2dyb3VwcyI6W10sImh0dHBzOi8vaWQuc3VibmV0Lm1pbi5pby9jbGFpbXMvcm9sZXMiOltdLCJodHRwczovL2lkLnN1Ym5ldC5taW4uaW8vY2xhaW1zL2VtYWlsIjoibGVuaW4rYzFAbWluaW8uaW8iLCJpc3MiOiJodHRwczovL2lkLnN1Ym5ldC5taW4uaW8vIiwic3ViIjoiYXV0aDB8NWZjZWFlYTMyNTNhZjEwMDc3NDZkMDM0IiwiYXVkIjoiaHR0cHM6Ly9zdWJuZXQubWluLmlvL2FwaSIsImlhdCI6MTYwODQxNjE5NiwiZXhwIjoxNjExMDA4MTk2LCJhenAiOiI1WTA0eVZlejNiOFgxUFVzRHVqSmxuZXVuY3ExVjZxaiIsInNjb3BlIjoib2ZmbGluZV9hY2Nlc3MiLCJndHkiOiJwYXNzd29yZCJ9.GC8DRLT0jUEteuBZBmyMXMswLSblCr_89Gu5NcVRUzKSYAaZ5VFW4UFgo1BpiC0sePuWJ0Vykitphx7znTfZfj5B3mZbOw3ejG6kxz7nm9DuYMmySJFYnwroZ9EP02vkW7-n_-YvEg8le1wXfkJ3lTUzO3aWddS4rfQRsZ2YJJUj61GiNyEK_QNP4PrYOuzLyD1wV75NejFqfcFoj7nRkT1K2BM0-89-_f2AFDGTjov6Ig6s1s-zLC9wxcYSmubNwpCJytZmQgPqIepOr065Y6OB4n0n0B5sXguuGuzb8VAkECrHhHPz8ta926fc0jC4XxVCNKdbV1_qC3-1yY7AJA\",\"expires_in\":2592000.0,\"token_type\":\"Bearer\"}}")))}, nil
}
HTTPDoMock = func(req *http.Request) (*http.Response, error) {
// returning test jwt license
return &http.Response{Body: ioutil.NopCloser(bytes.NewReader([]byte("{\"license\":\"eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZW5pbitjMUBtaW5pby5pbyIsInRlYW1OYW1lIjoiY29uc29sZS1jdXN0b21lciIsImV4cCI6MS42Mzk5NTI2MTE2MDkxNDQ3MzJlOSwiaXNzIjoic3VibmV0QG1pbmlvLmlvIiwiY2FwYWNpdHkiOjI1LCJpYXQiOjEuNjA4NDE2NjExNjA5MTQ0NzMyZTksImFjY291bnRJZCI6MTc2LCJzZXJ2aWNlVHlwZSI6IlNUQU5EQVJEIn0.ndtf8V_FJTvhXeemVLlORyDev6RJaSPhZ2djkMVK9SvXD0srR_qlYJATPjC4NljkS71nXMGVDov5uCTuUL97x6FGQEKDruA-z24x_2Zr8kof4LfBb3HUHudCR8QvE--I\",\"metadata\":{\"email\":\"lenin+c1@minio.io\",\"issuer\":\"subnet@minio.io\",\"accountId\":176,\"teamName\":\"console-customer\",\"serviceType\":\"STANDARD\",\"capacity\":25,\"requestedAt\":\"2020-12-19T22:23:31.609144732Z\",\"expiresAt\":\"2021-12-19T22:23:31.609144732Z\"}}")))}, nil
}
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.mockFunc != nil {
tt.mockFunc()
}
got, err := getLicenseFromCredentials(&tt.args.client, tt.args.username, tt.args.password)
if (err != nil) != tt.wantErr {
t.Errorf("getLicenseFromCredentials() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("getLicenseFromCredentials() got = %v, want %v", got, tt.want)
}
})
}
}
func Test_downloadSubnetPublicKey(t *testing.T) {
// HTTP Client mock
clientMock := HTTPClientMock{
Client: &http.Client{},
}
type args struct {
client HTTPClientMock
}
tests := []struct {
name string
args args
want string
wantErr bool
mockFunc func()
}{
{
name: "error downloading public key",
args: args{
client: clientMock,
},
mockFunc: func() {
HTTPGetMock = func(url string) (resp *http.Response, err error) {
return nil, errors.New("something went wrong")
}
},
wantErr: true,
want: "",
},
{
name: "public key download successfully",
args: args{
client: clientMock,
},
mockFunc: func() {
HTTPGetMock = func(url string) (resp *http.Response, err error) {
return &http.Response{Body: ioutil.NopCloser(bytes.NewReader([]byte("foo")))}, nil
}
},
wantErr: false,
want: "foo",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.mockFunc != nil {
tt.mockFunc()
}
got, err := downloadSubnetPublicKey(&tt.args.client)
if (err != nil) != tt.wantErr {
t.Errorf("downloadSubnetPublicKey() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("downloadSubnetPublicKey() got = %v, want %v", got, tt.want)
}
})
}
}
func TestValidateLicense(t *testing.T) {
// HTTP Client mock
clientMock := HTTPClientMock{
Client: &http.Client{},
}
type args struct {
client HTTPClientMock
licenseKey string
email string
password string
}
tests := []struct {
name string
args args
wantLicense string
wantErr bool
mockFunc func()
}{
{
name: "error because nor license nor user or password was provided",
args: args{
client: clientMock,
licenseKey: "",
email: "",
password: "",
},
wantErr: true,
},
{
name: "error because could not get license from credentials",
args: args{
client: clientMock,
licenseKey: "",
email: "email",
password: "password",
},
wantErr: true,
mockFunc: func() {
HTTPPostMock = func(url, contentType string, body io.Reader) (resp *http.Response, err error) {
return nil, errors.New("something went wrong")
}
},
},
{
name: "error because invalid license",
args: args{
client: clientMock,
licenseKey: "invalid license",
email: "",
password: "",
},
wantErr: true,
mockFunc: func() {
HTTPGetMock = func(url string) (resp *http.Response, err error) {
return &http.Response{Body: ioutil.NopCloser(bytes.NewReader([]byte(`-----BEGIN PUBLIC KEY-----
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEbo+e1wpBY4tBq9AONKww3Kq7m6QP/TBQ
mr/cKCUyBL7rcAvg0zNq1vcSrUSGlAmY3SEDCu3GOKnjG/U4E7+p957ocWSV+mQU
9NKlTdQFGF3+aO6jbQ4hX/S5qPyF+a3z
-----END PUBLIC KEY-----`)))}, nil
}
},
},
{
name: "license validated successfully",
args: args{
client: clientMock,
licenseKey: "eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZW5pbitjMUBtaW5pby5pbyIsInRlYW1OYW1lIjoiY29uc29sZS1jdXN0b21lciIsImV4cCI6MS42Mzk5NTI2MTE2MDkxNDQ3MzJlOSwiaXNzIjoic3VibmV0QG1pbmlvLmlvIiwiY2FwYWNpdHkiOjI1LCJpYXQiOjEuNjA4NDE2NjExNjA5MTQ0NzMyZTksImFjY291bnRJZCI6MTc2LCJzZXJ2aWNlVHlwZSI6IlNUQU5EQVJEIn0.ndtf8V_FJTvhXeemVLlORyDev6RJaSPhZ2djkMVK9SvXD0srR_qlYJATPjC4NljkS71nXMGVDov5uCTuUL97x6FGQEKDruA-z24x_2Zr8kof4LfBb3HUHudCR8QvE--I",
email: "",
password: "",
},
wantErr: false,
mockFunc: func() {
HTTPGetMock = func(url string) (resp *http.Response, err error) {
return &http.Response{Body: ioutil.NopCloser(bytes.NewReader([]byte(`-----BEGIN PUBLIC KEY-----
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEbo+e1wpBY4tBq9AONKww3Kq7m6QP/TBQ
mr/cKCUyBL7rcAvg0zNq1vcSrUSGlAmY3SEDCu3GOKnjG/U4E7+p957ocWSV+mQU
9NKlTdQFGF3+aO6jbQ4hX/S5qPyF+a3z
-----END PUBLIC KEY-----`)))}, nil
}
},
wantLicense: "eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZW5pbitjMUBtaW5pby5pbyIsInRlYW1OYW1lIjoiY29uc29sZS1jdXN0b21lciIsImV4cCI6MS42Mzk5NTI2MTE2MDkxNDQ3MzJlOSwiaXNzIjoic3VibmV0QG1pbmlvLmlvIiwiY2FwYWNpdHkiOjI1LCJpYXQiOjEuNjA4NDE2NjExNjA5MTQ0NzMyZTksImFjY291bnRJZCI6MTc2LCJzZXJ2aWNlVHlwZSI6IlNUQU5EQVJEIn0.ndtf8V_FJTvhXeemVLlORyDev6RJaSPhZ2djkMVK9SvXD0srR_qlYJATPjC4NljkS71nXMGVDov5uCTuUL97x6FGQEKDruA-z24x_2Zr8kof4LfBb3HUHudCR8QvE--I",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.mockFunc != nil {
tt.mockFunc()
}
_, gotLicense, err := ValidateLicense(&tt.args.client, tt.args.licenseKey, tt.args.email, tt.args.password)
if (err != nil) != tt.wantErr {
t.Errorf("ValidateLicense() error = %v, wantErr %v", err, tt.wantErr)
return
}
if gotLicense != tt.wantLicense {
t.Errorf("ValidateLicense() gotLicense = %v, want %v", gotLicense, tt.wantLicense)
}
})
}
}

View File

@@ -185,9 +185,9 @@ func getTotalSizes(argPatterns []ellipses.ArgPattern) []uint64 {
}
// PossibleParityValues returns possible parities for input args,
// parties are calculated in uniform manner for one zone or
// multiple zones, ensuring that parities returned are common
// and applicable across all zones.
// parties are calculated in uniform manner for one pool or
// multiple pools, ensuring that parities returned are common
// and applicable across all pools.
func PossibleParityValues(args ...string) ([]string, error) {
setIndexes, err := parseEndpointSet(args...)
if err != nil {

View File

@@ -0,0 +1,2 @@
build
coverage

View File

@@ -0,0 +1 @@
{}

File diff suppressed because one or more lines are too long

View File

@@ -1,10 +1,10 @@
const rewireReactHotLoader = require('react-app-rewire-hot-loader');
const rewireReactHotLoader = require("react-app-rewire-hot-loader");
/* config-overrides.js */
module.exports = function override(config, env) {
if (env === 'development') {
config.resolve.alias['react-dom'] = '@hot-loader/react-dom';
}
config = rewireReactHotLoader(config, env);
return config;
if (env === "development") {
config.resolve.alias["react-dom"] = "@hot-loader/react-dom";
}
config = rewireReactHotLoader(config, env);
return config;
};

17848
portal-ui/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,20 +3,23 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.7.4",
"@babel/plugin-transform-react-jsx-development": "^7.9.0",
"@hot-loader/react-dom": "^16.9.0",
"@date-io/moment": "1.x",
"@hot-loader/react-dom": "17.0.1",
"@material-ui/core": "^4.9.12",
"@material-ui/icons": "^4.9.1",
"@material-ui/pickers": "^3.2.10",
"@types/history": "^4.7.3",
"@types/jest": "24.0.23",
"@types/lodash": "^4.14.149",
"@types/node": "12.12.8",
"@types/react": "16.9.11",
"@types/react": "17.0.0",
"@types/react-copy-to-clipboard": "^4.3.0",
"@types/react-dom": "16.9.4",
"@types/react-grid-layout": "^1.1.1",
"@types/react-redux": "^7.1.5",
"@types/react-router": "^5.1.3",
"@types/react-router-dom": "^5.1.2",
"@types/react-virtualized": "^9.21.10",
"@types/recharts": "^1.8.9",
"@types/superagent": "^4.1.4",
"@types/webpack-env": "^1.14.1",
@@ -27,26 +30,28 @@
"history": "^4.10.1",
"local-storage-fallback": "^4.1.1",
"lodash": "^4.17.19",
"moment": "^2.24.0",
"npm": "^6.14.4",
"react": "^16.13.1",
"moment": "^2.29.1",
"react": "17.0.1",
"react-app-rewire-hot-loader": "^2.0.1",
"react-app-rewired": "^2.1.6",
"react-async-hook": "^3.6.1",
"react-chartjs-2": "^2.9.0",
"react-codemirror2": "^7.1.0",
"react-dom": "^16.12.0",
"react-copy-to-clipboard": "^5.0.2",
"react-dom": "17.0.1",
"react-grid-layout": "^1.2.0",
"react-hot-loader": "^4.13.0",
"react-moment": "^0.9.7",
"react-redux": "^7.1.3",
"react-router-dom": "^5.1.2",
"react-scripts": "3.4.1",
"react-scripts": "3.4.4",
"react-virtualized": "^9.22.2",
"react-window-infinite-loader": "^1.0.5",
"recharts": "^1.8.5",
"redux": "^4.0.4",
"redux-thunk": "^2.3.0",
"superagent": "^5.1.0",
"typeface-roboto": "^0.0.75",
"typescript": "3.6.4",
"use-debounce": "^5.0.1",
"websocket": "^1.0.31"
},
@@ -73,6 +78,8 @@
},
"proxy": "http://localhost:9090/",
"devDependencies": {
"prettier": "^1.19.1"
"jest": "^24.9.0",
"prettier": "2.2.1",
"typescript": "^4.1.2"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@@ -0,0 +1,67 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 368.999 192.934">
<defs>
<style>
.cls-1{opacity:0.35;}.cls-12,.cls-15,.cls-16,.cls-17,.cls-2,.cls-5,.cls-6,.cls-7,.cls-8{opacity:0.5;}.cls-10,.cls-11,.cls-12,.cls-13,.cls-14,.cls-15,.cls-16,.cls-17,.cls-3,.cls-4,.cls-5,.cls-6,.cls-7,.cls-9{fill:none;stroke:#707070;stroke-miterlimit:10;}.cls-4{stroke-width:1px;}.cls-10,.cls-11,.cls-5,.cls-9{stroke-width:1.2px;}.cls-5{stroke-dasharray:2.619
2.182;}.cls-12,.cls-15,.cls-16,.cls-17,.cls-5,.cls-6,.cls-7,.cls-8{isolation:isolate;}.cls-6{stroke-width:1.6px;stroke-dasharray:2.144
1.786;}.cls-7{stroke-width:1.6px;stroke-dasharray:2.23 1.858;}.cls-10{stroke-dasharray:2.646
2.204;}.cls-11{stroke-dasharray:2.585 2.154;}.cls-12{stroke-width:1.8px;stroke-dasharray:2.484
2.07;}.cls-13{stroke-dasharray:2.984 2.487;}.cls-14{stroke-dasharray:2.773
2.311;}.cls-16{stroke-width:1.8px;}.cls-17{stroke-width:1.8px;}
</style>
</defs>
<title>BG_Illustration</title>
<g id="Layer_2" data-name="Layer 2">
<g id="Layer_1-2" data-name="Layer 1">
<g id="BG_Illustration" data-name="BG Illustration" class="cls-1">
<g id="Group_118" data-name="Group 118" class="cls-2">
<path id="Path_56" data-name="Path 56" class="cls-3"
d="M211.5,140.678l-52.726,29.078L79.687,126.139V29.652L132.411.571,211.5,44.188Z"/>
<path id="Path_58" data-name="Path 58" class="cls-3"
d="M158.776,169.756V73.271L211.5,44.193,158.776,73.271,79.688,29.654"/>
<path id="Path_59" data-name="Path 59" class="cls-4" d="M84.681,41l69.1,38.11v79.3l-69.1-38.11Z"/>
<line id="Line_37" data-name="Line 37" class="cls-4" x1="106.25" y1="52.782" x2="106.25"
y2="132.086"/>
<line id="Line_38" data-name="Line 38" class="cls-4" x1="153.783" y1="92.327" x2="106.25"
y2="65.999"/>
<line id="Line_39" data-name="Line 39" class="cls-4" x1="153.783" y1="105.545" x2="106.25"
y2="79.217"/>
<line id="Line_40" data-name="Line 40" class="cls-4" x1="153.783" y1="118.762" x2="106.25"
y2="92.434"/>
<line id="Line_41" data-name="Line 41" class="cls-4" x1="153.783" y1="131.979" x2="106.25"
y2="105.651"/>
<line id="Line_42" data-name="Line 42" class="cls-4" x1="153.783" y1="145.197" x2="106.25"
y2="118.869"/>
<path id="Path_60" data-name="Path 60" class="cls-4"
d="M166.723,151.031l38.8-22.487V62.916L166.723,85.4Z"/>
</g>
<path id="Path_62" data-name="Path 62" class="cls-5" d="M117.106,148.062l-76.18,43.33"/>
<path id="Path_63" data-name="Path 63" class="cls-6" d="M271.394,167.271l-44.483,25.3"/>
<path id="Path_64" data-name="Path 64" class="cls-7" d="M190.722,155.708l61.951,36.031"/>
<path id="Path_65" data-name="Path 65" class="cls-5" d="M237.7,36.385l28.182,17.229"/>
<g id="Path_66" data-name="Path 66" class="cls-8">
<line class="cls-9" x1="362.563" y1="69.327" x2="361.42" y2="68.688"/>
<line class="cls-10" x1="359.496" y1="67.613" x2="305.418" y2="37.39"/>
<polyline class="cls-9" points="304.456 36.852 303.313 36.213 302.158 36.83"/>
<line class="cls-11" x1="300.258" y1="37.844" x2="213.418" y2="84.213"/>
<line class="cls-9" x1="212.468" y1="84.72" x2="211.313" y2="85.337"/>
</g>
<path id="Path_67" data-name="Path 67" class="cls-12"
d="M79.648,192.571,31.786,166.344h-.868l-23.579,14.2"/>
<g id="Path_68" data-name="Path 68" class="cls-8">
<line class="cls-3" x1="22.871" y1="84.641" x2="24.156" y2="83.867"/>
<line class="cls-13" x1="26.286" y1="82.584" x2="48.654" y2="69.113"/>
<polyline class="cls-3" points="49.719 68.471 51.004 67.698 52.307 68.441"/>
<line class="cls-14" x1="54.315" y1="69.585" x2="75.395" y2="81.606"/>
<line class="cls-3" x1="76.399" y1="82.178" x2="77.702" y2="82.921"/>
</g>
<circle id="Ellipse_11" data-name="Ellipse 11" class="cls-15" cx="4.092" cy="183.59" r="3.592"/>
<circle id="Ellipse_12" data-name="Ellipse 12" class="cls-15" cx="274.986" cy="165.477" r="3.592"/>
<ellipse id="Ellipse_13" data-name="Ellipse 13" class="cls-16" cx="364.957" cy="71.922" rx="3.592"
ry="2.904"/>
<circle id="Ellipse_14" data-name="Ellipse 14" class="cls-15" cx="19.279" cy="87.681" r="3.592"/>
<ellipse id="Ellipse_15" data-name="Ellipse 15" class="cls-17" cx="234.106" cy="32.58" rx="3.592"
ry="2.649"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="11.174" height="11" viewBox="0 0 11.174 11">
<defs>
<style>.a{fill:none;stroke:#081c42;stroke-linecap:round;}</style>
</defs>
<path class="a" d="M8.392,10H1.608L0,0H10Z" transform="translate(0.587 0.5)"/>
</svg>

After

Width:  |  Height:  |  Size: 279 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="11.174" height="11" viewBox="0 0 11.174 11">
<defs>
<style>.a{fill:#081c42;stroke:#081c42;stroke-linecap:round;}</style>
</defs>
<path class="a" d="M8.392,10H1.608L0,0H10Z" transform="translate(0.587 0.5)"/>
</svg>

After

Width:  |  Height:  |  Size: 282 B

View File

@@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" width="11.442" height="15.302" viewBox="0 0 11.442 15.302">
<defs>
<style>.a,.b{fill:none;stroke:#081c42;}.b{stroke-linejoin:round;}</style>
</defs>
<g transform="translate(0.5 0.5)">
<path class="a" d="M-12060-11667.842v14.261h10.442v-10.591l-3.671-3.67Z"
transform="translate(12059.999 11667.883)"/>
<path class="b" d="M-12051.353-11664.255v-3.639l3.528,3.639Z" transform="translate(12058.188 11667.894)"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 515 B

View File

@@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" width="11.442" height="15.302" viewBox="0 0 11.442 15.302">
<defs>
<style>.a,.b{fill:#081c42;stroke:#081c42;}.b{stroke-linejoin:round;fill:#fff}</style>
</defs>
<g transform="translate(0.5 0.5)">
<path class="a" d="M-12060-11667.842v14.261h10.442v-10.591l-3.671-3.67Z"
transform="translate(12059.999 11667.883)"/>
<path class="b" d="M-12051.353-11664.255v-3.639l3.528,3.639Z" transform="translate(12058.188 11667.894)"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 527 B

View File

@@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" width="15.999" height="13.999" viewBox="0 0 15.999 13.999">
<defs>
<style>.a{fill:none;stroke-linecap:square;}.b,.c{stroke:none;}.c{fill:#081c42;}</style>
</defs>
<g class="a" transform="translate(-0.001 0.001)">
<path class="b" d="M0,14V0H8.572V2.411H16V14Z"/>
<path class="c"
d="M 15.00020027160645 12.99860000610352 L 15.00020027160645 3.411099910736084 L 8.571599960327148 3.411099910736084 L 7.571600437164307 3.411099910736084 L 7.571600437164307 2.411099910736084 L 7.571600437164307 0.9990998506546021 L 1.000900268554688 0.9990998506546021 L 1.000900268554688 2.411099910736084 L 1.000900268554688 12.99860000610352 L 15.00020027160645 12.99860000610352 M 16.00020027160645 13.99860000610352 L 0.0009002700680866838 13.99860000610352 L 0.0009002700680866838 2.411099910736084 L 0.0009002700680866838 -0.0009001312428154051 L 8.571599960327148 -0.0009001312428154051 L 8.571599960327148 2.411099910736084 L 16.00020027160645 2.411099910736084 L 16.00020027160645 13.99860000610352 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

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