Compare commits

...

73 Commits

Author SHA1 Message Date
Daniel Valdivia
fbed90224f Release v0.17.0 (#2014)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2022-05-19 01:07:54 -07:00
Prakash Senthil Vel
64fe3a1dae Store bucket path if it is redirected to restore on login (#2006) 2022-05-19 02:01:47 -05:00
Alex
a160b92529 Display temporal paths when a policy has prefixes to allow navigation (#2011)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>

Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
Co-authored-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2022-05-19 00:40:52 -05:00
Daniel Valdivia
dc3e7f5888 Fix Versions Browsing Clicking on Chrome (#2013)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2022-05-18 23:58:17 -05:00
Daniel Valdivia
30d23d8555 Tweaks to Preview Max Height (#2012)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2022-05-18 23:40:47 -05:00
Prakash Senthil Vel
42deb992e6 License page updates (#2009)
Address conflicts review comments
2022-05-18 23:18:32 -05:00
Daniel Valdivia
6e31a42886 Redux Toolkit Redux Rewrite (#2003)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2022-05-18 17:02:26 -05:00
Javier Adriel
f6cab5a65b Add PVC describe API (#2007) 2022-05-17 19:02:53 -05:00
jinapurapu
448a80af4a Users screen UI revision (#1961)
* Changed Users screen UI to selector based delete, table layout changes, updated testcafe permissions test to reflect new delete User sequence, fixed ListUsers checkbox permission issue
2022-05-16 13:28:57 -05:00
Javier Adriel
6e4b8884e6 Add describe pod section to console UI (#2001) 2022-05-15 19:33:05 -07:00
Lenin Alevski
076e44e39a implement semgrep in github worflow for project (#1979) 2022-05-15 18:54:22 -07:00
Harshavardhana
1d23bf3d04 update to latest mc (#2002) 2022-05-14 15:50:59 -07:00
Daniel Valdivia
85b7f8c5d7 Update Padding on Policy Details (#2000)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2022-05-13 17:02:29 -05:00
jinapurapu
e4bf6ffd18 Fixed spacing of Bucket Events helpbox (#1999) 2022-05-13 13:58:20 -07:00
Lenin Alevski
1532cc0e70 Support for special characters and remove buggy functions (#1977)
- remove the use of encodeURI and encodeURIComponent functions and
  instead use encodeFileName and decodeFileName functions
- support for users with special characters
- support for users with special characters
- support for users with special characters
- fixed incorrectly group list display for policies

Signed-off-by: Lenin Alevski <alevsk.8772@gmail.com>
2022-05-13 13:13:56 -07:00
Prakash Senthil Vel
bd63817e37 UX Policy Summary (#1996) 2022-05-13 12:48:48 -07:00
jinapurapu
e8ccfeafe1 Fixed disabled Change Password button and added clarifying text (#1973) 2022-05-13 12:10:00 -07:00
adfost
6c892f095d Add access rules test (#1995) 2022-05-13 10:58:50 -05:00
Alex
e192623c22 Simplified layout effect for closing the menu on resize (#1992)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
2022-05-12 22:11:41 -07:00
Cesar Celis Hernandez
c20e9adaeb correcting sso token port for coverage (#1981) 2022-05-12 19:27:35 -05:00
Alex
fdb6d210d6 Added copy path button to breadcrumbs bar (#1990) 2022-05-12 16:01:54 -07:00
Alex
3473a10159 Changed styles of Object versions for small screens (#1988)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
2022-05-12 12:23:49 -05:00
Daniel Valdivia
2d8551f0d0 Upload latest coverge to the latest prefix (#1989)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2022-05-12 11:06:25 -05:00
adfost
38c74bdfa7 Reset config test and verb change to POST (#1986) 2022-05-11 22:31:40 -07:00
adfost
117da114dc Integration Tests for Get config (#1966) 2022-05-11 22:06:19 -07:00
Daniel Valdivia
d1f67ea7ac Release v0.16.3 (#1985)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2022-05-11 17:29:49 -07:00
jinapurapu
6f6846ee2a Fixed disabled Assign Policy button for multiple group selection (#1984) 2022-05-11 15:14:03 -07:00
Alex
6409d36df0 Changed styles for object browser in small screens (#1974)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
2022-05-11 14:57:43 -07:00
Prakash Senthil Vel
10f8aed021 Fix route navigation paths to match menus (#1978) 2022-05-11 13:02:01 -07:00
Daniel Valdivia
5ee9213ad0 Move Tiers, Notifications and Site Replication out of Settings Menu (#1975)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2022-05-11 12:41:56 -07:00
Daniel Valdivia
6be7527424 Upload Coverage as HTML to build bucket (#1982)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2022-05-11 12:03:23 -07:00
Harshavardhana
9edeafb0ec remove additional {} from prometheus query 2022-05-11 11:25:29 -07:00
Prakash Senthil Vel
09b0ea9a30 KBar buckets search (#1980) 2022-05-11 12:01:52 -05:00
Daniel Valdivia
f409049a51 Tests for delete bucket and config functions (#1976)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2022-05-11 09:39:43 -07:00
adfost
94b4725e24 adding set test (#1970) 2022-05-10 19:47:56 -07:00
Prakash Senthil Vel
2922a35fd2 Integration tests for inspect (#1968) 2022-05-10 19:33:24 -07:00
Cesar Celis Hernandez
d417874608 put the coverage file in play bucket (#1972) 2022-05-10 21:12:32 -05:00
Cesar Celis Hernandez
bc4abe100e increase coverage (#1971) 2022-05-10 17:03:23 -05:00
Daniel Valdivia
393f0cd2f4 Fix Icons Clipping (#1969)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2022-05-10 12:50:58 -05:00
Cesar Celis Hernandez
0c822ffa98 Add CSR end point (#1893) 2022-05-09 11:35:19 -07:00
Harshavardhana
624d9d9c4a start using xnet and simplify URL handling (#1960) 2022-05-09 11:24:43 -07:00
Alex
0d7fc0904e Removed error snack for versioning, quota & object locking in List Objects panel (#1964) 2022-05-07 23:08:50 -07:00
Alex
e5cc4a3d3a Fixed loader visibility in object details page (#1962) 2022-05-07 16:51:50 -07:00
Alex
f51763fc88 Added margin in date time picker to avoid jumpy effect (#1963)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
2022-05-06 16:06:05 -07:00
jinapurapu
22390a6781 Groups UI revision (#1959)
Co-authored-by: Prakash Senthil Vel <23444145+prakashsvmx@users.noreply.github.com>
2022-05-06 11:48:04 -07:00
Alex
3854372f4d Fixed multiple issues on object browser upload (#1955)
- Fixed issue with double slashes on upload manager
- Fixed sub folders not uploading in the correct subpaths location
- Fixed an issue upload when a file is already selected
- Fixed an issue with create path button with paths finished on slash
- Simplified path handling  for object browser

Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
2022-05-06 11:33:13 -07:00
Klaus Post
6d22aa9955 Add streaming zip downloads (#1956)
Do not keep either objects nor the intermediate zip file in memory, and stream both the final zip and the objects as they are read.

Existing code can easily OOM the server.
2022-05-06 11:14:05 -07:00
Cesar Celis Hernandez
9d052703ad Focus on testing Diag UI only, if BE fails, we skip that (#1958) 2022-05-06 09:27:54 -07:00
Harshavardhana
3bfdbb5ec7 add support for additional prometheus labels for query (#1936) 2022-05-05 13:44:10 -07:00
jinapurapu
9103ea9d70 Fixed Watch start button to show stop button once watch has started (#1957) 2022-05-05 12:45:26 -07:00
Cesar Celis Hernandez
4c99b0d1d9 Simplify SSO Integration Test (#1954) 2022-05-05 10:29:41 -07:00
Alex
16474cbd81 Disabled versioning button when site replication is enabled (#1951)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
2022-05-04 19:09:47 -07:00
Alex
f0c123932d Fixed loader issue object versions page (#1953)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
2022-05-04 17:05:27 -05:00
jinapurapu
0cdff7dc0e Add User Service Account screen (#1947) 2022-05-04 14:39:21 -07:00
Prakash Senthil Vel
3c659a29ae Table tests for site replication apis (#1944) 2022-05-04 14:40:44 -05:00
Alex
42beef408c Added versions multiselection & delete selected versions buttons (#1948) 2022-05-04 09:14:52 -07:00
jinapurapu
c43d84f14b Added clarifying text to AddGroupHelpBox (#1950) 2022-05-03 21:07:58 -07:00
Alex
394a728b98 Fixed issue with quota assignation in create bucket wizard (#1949)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
2022-05-03 20:35:10 -07:00
Daniel Valdivia
c741e9ccae Release v0.16.2 (#1945)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2022-05-03 11:33:42 -07:00
jinapurapu
ab835286b0 Add Service Account Policy restriction improvement (#1921) 2022-05-03 11:03:57 -07:00
Alex
6485718a97 Changed Share modal styles (#1942)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
2022-05-02 22:30:48 -05:00
adfost
00bcb54b67 Describe pod API (#1861) 2022-05-02 18:35:36 -07:00
Alex
fef7863810 Adjusted edit / delete tags modal styles (#1939) 2022-05-02 17:01:34 -07:00
jinapurapu
427b9b4892 Integration test for PolicyNameContainsSpace (#1940) 2022-05-02 17:35:01 -05:00
jinapurapu
34adc5451d Disabled Save button on Add Policy Screen if policy name contains space (#1937) 2022-05-02 15:08:11 -07:00
adfost
224e8d4bba More groups tests (#1923) 2022-05-02 11:25:21 -05:00
Prakash Senthil Vel
07d75e19d5 UX KBar Style (#1935) 2022-05-02 11:04:07 -05:00
Daniel Valdivia
31871f54d4 Update HelpBox for Create Bucket. Add spacing. (#1934) 2022-04-30 12:00:58 -07:00
Alex
6069991405 Improvements for download / upload manager (#1933)
- Changed styles on progress bars & items
- Fixed some issues in error state & handling
- Added cancel capability to objects
- Added visual indicators when new objects are added to pool

Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
2022-04-29 20:54:12 -07:00
Daniel Valdivia
a017c71d20 Release v0.16.1 (#1928)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2022-04-29 18:55:43 -07:00
Harshavardhana
4001f14953 keep lookupMap for easy reading for relevant publicKey file (#1930)
Co-authored-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2022-04-29 15:14:04 -07:00
Cesar Celis Hernandez
130413cbef having idp configured via env variable only (#1931) 2022-04-29 14:48:21 -07:00
Lenin Alevski
0622cc658b fix: parseTenantCertificates was ignoring cert-manager secrets (#1929)
Signed-off-by: Lenin Alevski <alevsk.8772@gmail.com>

Co-authored-by: Cesar Celis Hernandez <celis.hernandez.cesar@gmail.com>
2022-04-29 11:55:07 -07:00
986 changed files with 21446 additions and 16841 deletions

View File

@@ -24,6 +24,7 @@ jobs:
- no-warnings-and-make-assets
- reuse-golang-dependencies
- vulnerable-dependencies-checks
- semgrep-static-code-analysis
runs-on: ubuntu-latest
strategy:
@@ -92,6 +93,7 @@ jobs:
- no-warnings-and-make-assets
- reuse-golang-dependencies
- vulnerable-dependencies-checks
- semgrep-static-code-analysis
runs-on: ubuntu-latest
strategy:
@@ -160,6 +162,7 @@ jobs:
- no-warnings-and-make-assets
- reuse-golang-dependencies
- vulnerable-dependencies-checks
- semgrep-static-code-analysis
runs-on: ubuntu-latest
strategy:
@@ -256,6 +259,22 @@ jobs:
curl -L -o nancy https://github.com/sonatype-nexus-community/nancy/releases/download/${nancy_version}/nancy-${nancy_version}-linux-amd64 && chmod +x nancy
go list -deps -json ./... | jq -s 'unique_by(.Module.Path)|.[]|select(has("Module"))|.Module' | ./nancy sleuth
semgrep-static-code-analysis:
name: "semgrep checks"
runs-on: ${{ matrix.os }}
container:
image: "returntocorp/semgrep"
strategy:
matrix:
os: [ ubuntu-latest ]
steps:
- name: Check out source code
uses: actions/checkout@v2
- name: Scanning code on ${{ matrix.os }}
continue-on-error: false
run: |
semgrep --config semgrep.yaml $(pwd)/portal-ui --error
no-warnings-and-make-assets:
name: "React Code Has No Warnings and then Make Assets"
runs-on: ${{ matrix.os }}
@@ -350,6 +369,7 @@ jobs:
- no-warnings-and-make-assets
- reuse-golang-dependencies
- vulnerable-dependencies-checks
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
@@ -428,6 +448,7 @@ jobs:
- no-warnings-and-make-assets
- reuse-golang-dependencies
- vulnerable-dependencies-checks
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
@@ -506,6 +527,7 @@ jobs:
- no-warnings-and-make-assets
- reuse-golang-dependencies
- vulnerable-dependencies-checks
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
@@ -585,6 +607,7 @@ jobs:
- no-warnings-and-make-assets
- reuse-golang-dependencies
- vulnerable-dependencies-checks
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
timeout-minutes: 5
strategy:
@@ -654,6 +677,7 @@ jobs:
- no-warnings-and-make-assets
- reuse-golang-dependencies
- vulnerable-dependencies-checks
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
@@ -722,6 +746,7 @@ jobs:
- no-warnings-and-make-assets
- reuse-golang-dependencies
- vulnerable-dependencies-checks
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
@@ -790,6 +815,7 @@ jobs:
- no-warnings-and-make-assets
- reuse-golang-dependencies
- vulnerable-dependencies-checks
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
@@ -863,6 +889,7 @@ jobs:
- no-warnings-and-make-assets
- reuse-golang-dependencies
- vulnerable-dependencies-checks
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
@@ -900,6 +927,7 @@ jobs:
- no-warnings-and-make-assets
- reuse-golang-dependencies
- vulnerable-dependencies-checks
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
@@ -937,6 +965,7 @@ jobs:
- no-warnings-and-make-assets
- reuse-golang-dependencies
- vulnerable-dependencies-checks
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
@@ -974,6 +1003,7 @@ jobs:
- no-warnings-and-make-assets
- reuse-golang-dependencies
- vulnerable-dependencies-checks
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
@@ -1011,6 +1041,7 @@ jobs:
- no-warnings-and-make-assets
- reuse-golang-dependencies
- vulnerable-dependencies-checks
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
@@ -1048,6 +1079,7 @@ jobs:
- no-warnings-and-make-assets
- reuse-golang-dependencies
- vulnerable-dependencies-checks
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
@@ -1085,6 +1117,7 @@ jobs:
- no-warnings-and-make-assets
- reuse-golang-dependencies
- vulnerable-dependencies-checks
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
@@ -1122,6 +1155,7 @@ jobs:
- no-warnings-and-make-assets
- reuse-golang-dependencies
- vulnerable-dependencies-checks
- semgrep-static-code-analysis
runs-on: ${{ matrix.os }}
strategy:
matrix:
@@ -1167,6 +1201,7 @@ jobs:
- no-warnings-and-make-assets
- reuse-golang-dependencies
- vulnerable-dependencies-checks
- semgrep-static-code-analysis
runs-on: ubuntu-latest
strategy:
@@ -1235,6 +1270,7 @@ jobs:
- no-warnings-and-make-assets
- reuse-golang-dependencies
- vulnerable-dependencies-checks
- semgrep-static-code-analysis
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
@@ -1340,16 +1376,31 @@ jobs:
go build gocovmerge.go
echo "put together the outs for final coverage resolution"
./gocovmerge ../integration/coverage/system.out ../replication/coverage/replication.out ../sso-integration/coverage/sso-system.out ../restapi/coverage/coverage.out ../pkg/coverage/coverage-pkg.out ../operator-integration/coverage/operator-api.out > all.out
echo "Download mc for Ubuntu"
wget -q https://dl.min.io/client/mc/release/linux-amd64/mc
echo "Change the permissions to execute mc command"
chmod +x mc
echo "Create the folder to put the all.out file"
./mc mb --ignore-existing play/builds/
echo "Copy the all.out file to play bucket"
echo ${{ github.repository }}
echo ${{ github.event.number }}
echo ${{ github.run_id }}
./mc cp all.out play/builds/${{ github.repository }}/${{ github.event.number }}/${{ github.run_id }}/
./mc cp all.out play/builds/${{ github.repository }}/${{ github.event.number }}/latest/
go tool cover -html=all.out -o coverage.html
./mc cp coverage.html play/builds/${{ github.repository }}/${{ github.event.number }}/${{ github.run_id }}/
./mc cp coverage.html play/builds/${{ github.repository }}/${{ github.event.number }}/latest/
echo "grep to obtain the result"
go tool cover -func=all.out | grep total > tmp2
result=`cat tmp2 | awk 'END {print $3}'`
result=${result%\%}
echo "result:"
echo $result
threshold=41.2
threshold=46.6
echo "Result:"
echo "$result%"
if (( $(echo "$result >= $threshold" |bc -l) )); then
echo "It is equal or greater than threshold, passed!"
echo "It is equal or greater than threshold ($threshold%), passed!"
else
echo "It is smaller than threshold value, failed!"
echo "It is smaller than threshold ($threshold%) value, failed!"
exit 1
fi

View File

@@ -16,10 +16,17 @@ linters:
- ineffassign
- gosimple
- deadcode
- unparam
- structcheck
- gomodguard
- gofmt
- unused
- structcheck
- goheader
- unconvert
- varcheck
- gocritic
- gofumpt
- tenv
- durationcheck
linters-settings:
goheader:

33
.semgrepignore Normal file
View File

@@ -0,0 +1,33 @@
# Ignore git items
.gitignore
.git/
:include .gitignore
# Common large paths
node_modules/
portal-ui/node_modules/
build/
dist/
.idea/
vendor/
.env/
.venv/
.tox/
*.min.js
# Common test paths
test/
tests/
*_test.go
# Semgrep rules folder
.semgrep
# Semgrep-action log folder
.semgrep_logs/
# Ignore VsCode files
.vscode/
*.code-workspace
*~
.eslintcache

View File

@@ -131,29 +131,25 @@ test-replication:
test-sso-integration:
@echo "create the network in bridge mode to communicate all containers"
@(docker network create my-net)
@echo "execute latest keycloak container"
@echo "run openldap container using MinIO Image: quay.io/minio/openldap:latest"
@(docker run \
--rm \
--name keycloak-container \
--network my-net \
-p 8080:8080 \
-e KEYCLOAK_USER=admin \
-e KEYCLOAK_PASSWORD=admin jboss/keycloak:latest -b 0.0.0.0 -bprivate 127.0.0.1 &)
@echo "wait 60 sec until keycloak is listenning on port, then go for minio server"
@(sleep 60)
@echo "execute keycloak-config-cli container to configure keycloak for Single Sign On with MinIO"
-e LDAP_ORGANIZATION="MinIO Inc" \
-e LDAP_DOMAIN="min.io" \
-e LDAP_ADMIN_PASSWORD="admin" \
--network my-net \
-p 389:389 \
-p 636:636 \
--name openldap \
--detach quay.io/minio/openldap:latest)
@echo "Run Dex container using MinIO Image: quay.io/minio/dex:latest"
@(docker run \
--rm \
--network my-net \
--name keycloak-config-cli \
-e KEYCLOAK_URL=http://keycloak-container:8080/auth \
-e KEYCLOAK_USER="admin" \
-e KEYCLOAK_PASSWORD="admin" \
-e KEYCLOAK_AVAILABILITYCHECK_ENABLED=true \
-e KEYCLOAK_AVAILABILITYCHECK_TIMEOUT=120s \
-e IMPORT_FILES_LOCATIONS='/config/realm-export.json' \
-v /home/runner/work/console/console/sso-integration/config:/config \
adorsys/keycloak-config-cli:latest)
-e DEX_ISSUER=http://dex:5556/dex \
-e DEX_CLIENT_REDIRECT_URI=http://127.0.0.1:9090/oauth_callback \
-e DEX_LDAP_SERVER=openldap:389 \
--network my-net \
-p 5556:5556 \
--name dex \
--detach quay.io/minio/dex:latest)
@echo "running minio server"
@(docker run \
-v /data1 -v /data2 -v /data3 -v /data4 \
@@ -163,19 +159,22 @@ test-sso-integration:
--rm \
-p 9000:9000 \
-p 9001:9001 \
-e MINIO_IDENTITY_OPENID_CLIENT_SECRET=0nfJuqIt0iPnRIUJkvetve5l38C6gi9W \
-e MINIO_IDENTITY_OPENID_CLIENT_ID="minio-client-app" \
-e MINIO_IDENTITY_OPENID_CLIENT_SECRET="minio-client-app-secret" \
-e MINIO_IDENTITY_OPENID_CLAIM_NAME=name \
-e MINIO_IDENTITY_OPENID_CONFIG_URL=http://dex:5556/dex/.well-known/openid-configuration \
-e MINIO_IDENTITY_OPENID_REDIRECT_URI=http://127.0.0.1:9090/oauth_callback \
-e MINIO_ROOT_USER=minio \
-e MINIO_ROOT_PASSWORD=minio123 $(MINIO_VERSION) server /data{1...4} --address :9000 --console-address :9001)
@(sleep 60)
@echo "run mc commands"
@echo "run mc commands to set the policy"
@(docker run --name minio-client --network my-net -dit --entrypoint=/bin/sh minio/mc)
@(docker exec minio-client mc alias set myminio/ http://minio:9000 minio minio123)
@(docker exec minio-client mc admin config set myminio identity_openid config_url="http://keycloak-container:8080/auth/realms/myrealm/.well-known/openid-configuration" client_id="account")
@(docker exec minio-client mc admin service restart myminio)
@echo "adding policy to Dillon Harper to be able to login:"
@(cd sso-integration && docker cp allaccess.json minio-client:/ && docker exec minio-client mc admin policy add myminio "Dillon Harper" allaccess.json)
@echo "starting bash script"
@(env bash $(PWD)/sso-integration/set-sso.sh)
@echo "install jq"
@(sudo apt install jq)
@echo "add python module"
@(pip3 install bs4)
@echo "Executing the test:"
@(cd sso-integration && go test -coverpkg=../restapi -c -tags testrunmain . && mkdir -p coverage && ./sso-integration.test -test.v -test.run "^Test*" -test.coverprofile=coverage/sso-system.out)

View File

@@ -25,8 +25,8 @@ import (
// getTLSClientConfig will return the right TLS configuration for the K8S client based on the configured TLS certificate
func getTLSClientConfig() rest.TLSClientConfig {
var defaultRootCAFile = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
var customRootCAFile = getK8sAPIServerTLSRootCA()
defaultRootCAFile := "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
customRootCAFile := getK8sAPIServerTLSRootCA()
tlsClientConfig := rest.TLSClientConfig{}
// if console is running inside k8s by default he will have access to the CA Cert from the k8s local authority
if _, err := certutil.NewPool(defaultRootCAFile); err == nil {

View File

@@ -40,7 +40,6 @@ var appCmds = []cli.Command{
// StartServer starts the console service
func StartServer(ctx *cli.Context) error {
// Load all certificates
if err := loadAllCerts(ctx); err != nil {
// Log this as a warning and continue running console without TLS certificates

View File

@@ -189,7 +189,6 @@ func loadOperatorAllCerts(ctx *cli.Context) error {
// StartServer starts the console service
func startOperatorServer(ctx *cli.Context) error {
if err := loadAllCerts(ctx); err != nil {
// Log this as a warning and continue running console without TLS certificates
restapi.LogError("Unable to load certs: %v", err)

14
go.mod
View File

@@ -22,11 +22,11 @@ require (
github.com/minio/cli v1.22.0
github.com/minio/highwayhash v1.0.2
github.com/minio/kes v0.19.2
github.com/minio/madmin-go v1.3.12
github.com/minio/mc v0.0.0-20220419155441-cc4ff3a0cc82
github.com/minio/minio-go/v7 v7.0.24
github.com/minio/madmin-go v1.3.14
github.com/minio/mc v0.0.0-20220512134321-aa60a8db1e4d
github.com/minio/minio-go/v7 v7.0.26
github.com/minio/operator v0.0.0-20220414212219-ba4c097324b2
github.com/minio/pkg v1.1.21
github.com/minio/pkg v1.1.23
github.com/minio/selfupdate v0.4.0
github.com/mitchellh/go-homedir v1.1.0
github.com/rs/xid v1.4.0
@@ -41,6 +41,7 @@ require (
k8s.io/api v0.23.5
k8s.io/apimachinery v0.23.5
k8s.io/client-go v0.23.5
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9
)
require (
@@ -104,6 +105,7 @@ require (
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/montanaflynn/stats v0.6.6 // indirect
github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70 // indirect
github.com/muesli/reflow v0.3.0 // indirect
github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739 // indirect
@@ -118,8 +120,9 @@ require (
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // indirect
github.com/prometheus/client_golang v1.12.1 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/common v0.33.0 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/prometheus/prom2json v1.3.1 // indirect
github.com/rivo/tview v0.0.0-20220216162559-96063d6082f3 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/rjeczalik/notify v0.9.2 // indirect
@@ -153,7 +156,6 @@ require (
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
k8s.io/klog/v2 v2.40.1 // indirect
k8s.io/kube-openapi v0.0.0-20220124234850-424119656bbf // indirect
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
maze.io/x/duration v0.0.0-20160924141736-faac084b6075 // indirect
sigs.k8s.io/controller-runtime v0.11.1 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect

880
go.sum

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,96 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 integration
import (
"bytes"
"encoding/json"
"fmt"
"log"
"net/http"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func Test_AddAccessRuleAPI(t *testing.T) {
assert := assert.New(t)
AddBucket("testaccessruleadd", false, false, nil, nil)
type args struct {
prefix string
access string
}
tests := []struct {
name string
args args
expectedStatus int
expectedError error
}{
{
name: "Create Access Rule - Valid",
args: args{
prefix: "/test/",
access: "readonly",
},
expectedStatus: 200,
expectedError: nil,
},
{
name: "Create Group - Invalid",
args: args{
prefix: "/test/",
access: "readonl",
},
expectedStatus: 500,
expectedError: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &http.Client{
Timeout: 3 * time.Second,
}
requestDataPolicy := map[string]interface{}{}
requestDataPolicy["prefix"] = tt.args.prefix
requestDataPolicy["access"] = tt.args.access
requestDataJSON, _ := json.Marshal(requestDataPolicy)
requestDataBody := bytes.NewReader(requestDataJSON)
request, err := http.NewRequest(
"PUT", "http://localhost:9090/api/v1/bucket/testaccessruleadd/access-rules", requestDataBody)
if err != nil {
log.Println(err)
return
}
request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
request.Header.Add("Content-Type", "application/json")
response, err := client.Do(request)
if err != nil {
log.Println(err)
return
}
if response != nil {
assert.Equal(tt.expectedStatus, response.StatusCode, "Status Code is incorrect")
}
})
}
}

View File

@@ -154,7 +154,6 @@ func NotifyPostgres() (*http.Response, error) {
}
func TestNotifyPostgres(t *testing.T) {
// Variables
assert := assert.New(t)
@@ -170,11 +169,9 @@ func TestNotifyPostgres(t *testing.T) {
if response != nil {
assert.Equal(200, response.StatusCode, finalResponse)
}
}
func TestRestartService(t *testing.T) {
assert := assert.New(t)
restartResponse, restartError := RestartService()
assert.Nil(restartError)
@@ -190,7 +187,6 @@ func TestRestartService(t *testing.T) {
addObjRsp,
)
}
}
func ListPoliciesWithBucket(bucketName string) (*http.Response, error) {
@@ -214,7 +210,6 @@ func ListPoliciesWithBucket(bucketName string) (*http.Response, error) {
}
func TestListPoliciesWithBucket(t *testing.T) {
// Test Variables
bucketName := "testlistpolicieswithbucket"
assert := assert.New(t)
@@ -234,7 +229,6 @@ func TestListPoliciesWithBucket(t *testing.T) {
parsedResponse,
)
}
}
func ListUsersWithAccessToBucket(bucketName string) (*http.Response, error) {
@@ -258,7 +252,6 @@ func ListUsersWithAccessToBucket(bucketName string) (*http.Response, error) {
}
func TestListUsersWithAccessToBucket(t *testing.T) {
// Test Variables
bucketName := "testlistuserswithaccesstobucket1"
assert := assert.New(t)
@@ -278,11 +271,9 @@ func TestListUsersWithAccessToBucket(t *testing.T) {
parsedResponse,
)
}
}
func TestGetNodes(t *testing.T) {
assert := assert.New(t)
getNodesResponse, getNodesError := GetNodes()
assert.Nil(getNodesError)
@@ -298,7 +289,6 @@ func TestGetNodes(t *testing.T) {
addObjRsp,
)
}
}
func ArnList() (*http.Response, error) {

View File

@@ -56,8 +56,7 @@ func inspectHTTPResponse(httpResponse *http.Response) string {
}
func initConsoleServer() (*restapi.Server, error) {
//os.Setenv("CONSOLE_MINIO_SERVER", "localhost:9000")
// os.Setenv("CONSOLE_MINIO_SERVER", "localhost:9000")
swaggerSpec, err := loads.Embedded(restapi.SwaggerJSON, restapi.FlatSwaggerJSON)
if err != nil {
@@ -79,7 +78,7 @@ func initConsoleServer() (*restapi.Server, error) {
// register all APIs
server.ConfigureAPI()
//restapi.GlobalRootCAs, restapi.GlobalPublicCerts, restapi.GlobalTLSCertsManager = globalRootCAs, globalPublicCerts, globalTLSCerts
// restapi.GlobalRootCAs, restapi.GlobalPublicCerts, restapi.GlobalTLSCertsManager = globalRootCAs, globalPublicCerts, globalTLSCerts
consolePort, _ := strconv.Atoi("9090")
@@ -92,7 +91,6 @@ func initConsoleServer() (*restapi.Server, error) {
}
func TestMain(m *testing.M) {
// start console server
go func() {
fmt.Println("start server")
@@ -103,7 +101,6 @@ func TestMain(m *testing.M) {
return
}
srv.Serve()
}()
fmt.Println("sleeping")
@@ -132,7 +129,6 @@ func TestMain(m *testing.M) {
request.Header.Add("Content-Type", "application/json")
response, err := client.Do(request)
if err != nil {
log.Println(err)
return
@@ -162,7 +158,7 @@ func TestMain(m *testing.M) {
requestDataBody = bytes.NewReader(requestDataJSON)
// get list of buckets
// delete bucket
request, err = http.NewRequest("DELETE", "http://localhost:9090/api/v1/buckets/test1", requestDataBody)
if err != nil {
log.Println(err)

View File

@@ -31,38 +31,206 @@ import (
func Test_ConfigAPI(t *testing.T) {
assert := assert.New(t)
type args struct {
api string
}
tests := []struct {
name string
args args
expectedStatus int
expectedError error
}{
{
name: "Config - Valid",
args: args{
api: "/configs",
},
name: "Config - Valid",
expectedStatus: 200,
expectedError: nil,
},
}
client := &http.Client{
Timeout: 3 * time.Second,
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &http.Client{
Timeout: 3 * time.Second,
}
requestDataPolicy := map[string]interface{}{}
requestDataJSON, _ := json.Marshal(requestDataPolicy)
requestDataBody := bytes.NewReader(requestDataJSON)
request, err := http.NewRequest(
"GET", fmt.Sprintf("http://localhost:9090/api/v1%s", tt.args.api), requestDataBody)
request, err := http.NewRequest("GET", "http://localhost:9090/api/v1/configs", nil)
if err != nil {
log.Println(err)
return
}
request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
request.Header.Add("Content-Type", "application/json")
response, err := client.Do(request)
if err != nil {
log.Println(err)
return
}
if response != nil {
assert.Equal(tt.expectedStatus, response.StatusCode, tt.name+" Failed")
}
})
}
}
func Test_GetConfigAPI(t *testing.T) {
assert := assert.New(t)
type args struct {
name string
}
tests := []struct {
name string
args args
expectedStatus int
expectedError error
}{
{
name: "Get Config - Valid",
args: args{
name: "storage_class",
},
expectedStatus: 200,
expectedError: nil,
},
{
name: "Get Config - Invalid",
args: args{
name: "asdf",
},
expectedStatus: 404,
expectedError: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &http.Client{
Timeout: 3 * time.Second,
}
request, err := http.NewRequest(
"GET", fmt.Sprintf("http://localhost:9090/api/v1/configs/%s", tt.args.name), nil)
if err != nil {
log.Println(err)
return
}
request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
request.Header.Add("Content-Type", "application/json")
response, err := client.Do(request)
if err != nil {
log.Println(err)
return
}
if response != nil {
assert.Equal(tt.expectedStatus, response.StatusCode, tt.name+" Failed")
}
})
}
}
func Test_SetConfigAPI(t *testing.T) {
assert := assert.New(t)
type args struct {
name string
keyValues []map[string]interface{}
}
tests := []struct {
name string
args args
expectedStatus int
expectedError error
}{
{
name: "Set Config - Valid",
args: args{
name: "region",
keyValues: []map[string]interface{}{{"key": "name", "value": "testServer"}, {"key": "region", "value": "us-west-1"}},
},
expectedStatus: 200,
expectedError: nil,
},
{
name: "Set Config - Invalid",
args: args{
name: "regiontest",
keyValues: []map[string]interface{}{{"key": "name", "value": "testServer"}, {"key": "region", "value": "us-west-1"}},
},
expectedStatus: 500,
expectedError: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &http.Client{
Timeout: 3 * time.Second,
}
requestDataPolicy := map[string]interface{}{}
requestDataPolicy["key_values"] = tt.args.keyValues
requestDataJSON, _ := json.Marshal(requestDataPolicy)
requestDataBody := bytes.NewReader(requestDataJSON)
request, err := http.NewRequest(
"PUT", fmt.Sprintf("http://localhost:9090/api/v1/configs/%s", tt.args.name), requestDataBody)
if err != nil {
log.Println(err)
return
}
request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
request.Header.Add("Content-Type", "application/json")
response, err := client.Do(request)
if err != nil {
log.Println(err)
return
}
if response != nil {
assert.Equal(tt.expectedStatus, response.StatusCode, tt.name+" Failed")
}
})
}
}
func Test_ResetConfigAPI(t *testing.T) {
assert := assert.New(t)
type args struct {
name string
}
tests := []struct {
name string
args args
expectedStatus int
expectedError error
}{
{
name: "Reset Config - Valid",
args: args{
name: "region",
},
expectedStatus: 200,
expectedError: nil,
},
{
name: "Reset Config - Invalid",
args: args{
name: "regiontest",
},
expectedStatus: 500,
expectedError: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &http.Client{
Timeout: 3 * time.Second,
}
requestDataPolicy := map[string]interface{}{}
requestDataJSON, _ := json.Marshal(requestDataPolicy)
requestDataBody := bytes.NewReader(requestDataJSON)
request, err := http.NewRequest(
"POST", fmt.Sprintf("http://localhost:9090/api/v1/configs/%s/reset", tt.args.name), requestDataBody)
if err != nil {
log.Println(err)
return
@@ -79,5 +247,4 @@ func Test_ConfigAPI(t *testing.T) {
}
})
}
}

View File

@@ -18,6 +18,7 @@ package integration
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"log"
@@ -34,7 +35,6 @@ func Test_AddGroupAPI(t *testing.T) {
AddUser("member1", "testtest", []string{}, []string{"consoleAdmin"})
type args struct {
api string
group string
members []string
}
@@ -47,7 +47,6 @@ func Test_AddGroupAPI(t *testing.T) {
{
name: "Create Group - Valid",
args: args{
api: "/groups",
group: "test",
members: []string{"member1"},
},
@@ -57,7 +56,6 @@ func Test_AddGroupAPI(t *testing.T) {
{
name: "Create Group - Invalid",
args: args{
api: "/groups",
group: "test",
members: []string{},
},
@@ -68,13 +66,10 @@ func Test_AddGroupAPI(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &http.Client{
Timeout: 3 * time.Second,
}
// Add policy
requestDataPolicy := map[string]interface{}{}
requestDataPolicy["group"] = tt.args.group
requestDataPolicy["members"] = tt.args.members
@@ -82,7 +77,7 @@ func Test_AddGroupAPI(t *testing.T) {
requestDataJSON, _ := json.Marshal(requestDataPolicy)
requestDataBody := bytes.NewReader(requestDataJSON)
request, err := http.NewRequest(
"POST", fmt.Sprintf("http://localhost:9090/api/v1%s", tt.args.api), requestDataBody)
"POST", "http://localhost:9090/api/v1/groups", requestDataBody)
if err != nil {
log.Println(err)
return
@@ -97,10 +92,188 @@ func Test_AddGroupAPI(t *testing.T) {
if response != nil {
assert.Equal(tt.expectedStatus, response.StatusCode, "Status Code is incorrect")
}
})
}
}
func Test_GetGroupAPI(t *testing.T) {
assert := assert.New(t)
AddUser("member2", "testtest", []string{}, []string{"consoleAdmin"})
AddGroup("getgroup1", []string{"member2"})
type args struct {
api string
}
tests := []struct {
name string
args args
expectedStatus int
expectedError error
}{
{
name: "Get Group - Valid",
args: args{
api: base64.StdEncoding.EncodeToString([]byte("getgroup1")),
},
expectedStatus: 200,
expectedError: nil,
},
{
name: "Get Group - Invalid",
args: args{
api: base64.StdEncoding.EncodeToString([]byte("askfjalkd")),
},
expectedStatus: 500,
expectedError: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &http.Client{
Timeout: 3 * time.Second,
}
requestDataPolicy := map[string]interface{}{}
requestDataJSON, _ := json.Marshal(requestDataPolicy)
requestDataBody := bytes.NewReader(requestDataJSON)
request, err := http.NewRequest(
"GET", fmt.Sprintf("http://localhost:9090/api/v1/group/%s", tt.args.api), requestDataBody)
if err != nil {
log.Println(err)
return
}
request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
request.Header.Add("Content-Type", "application/json")
response, err := client.Do(request)
if err != nil {
log.Println(err)
return
}
if response != nil {
assert.Equal(tt.expectedStatus, response.StatusCode, "Status Code is incorrect")
}
})
}
}
func Test_ListGroupsAPI(t *testing.T) {
assert := assert.New(t)
tests := []struct {
name string
expectedStatus int
expectedError error
}{
{
name: "Get Group - Valid",
expectedStatus: 200,
expectedError: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &http.Client{
Timeout: 3 * time.Second,
}
requestDataPolicy := map[string]interface{}{}
requestDataJSON, _ := json.Marshal(requestDataPolicy)
requestDataBody := bytes.NewReader(requestDataJSON)
request, err := http.NewRequest(
"GET", "http://localhost:9090/api/v1/groups", requestDataBody)
if err != nil {
log.Println(err)
return
}
request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
request.Header.Add("Content-Type", "application/json")
response, err := client.Do(request)
if err != nil {
log.Println(err)
return
}
if response != nil {
assert.Equal(tt.expectedStatus, response.StatusCode, "Status Code is incorrect")
}
})
}
}
func Test_PutGroupsAPI(t *testing.T) {
assert := assert.New(t)
AddUser("member3", "testtest", []string{}, []string{"consoleAdmin"})
AddGroup("putgroup1", []string{})
type args struct {
api string
members []string
status string
}
tests := []struct {
name string
args args
expectedStatus int
expectedError error
}{
{
name: "Put Group - Valid",
args: args{
api: base64.StdEncoding.EncodeToString([]byte("putgroup1")),
members: []string{"member3"},
status: "enabled",
},
expectedStatus: 200,
expectedError: nil,
},
{
name: "Put Group - Invalid",
args: args{
api: base64.StdEncoding.EncodeToString([]byte("gdgfdfgd")),
members: []string{"member3"},
status: "enabled",
},
expectedStatus: 500,
expectedError: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &http.Client{
Timeout: 3 * time.Second,
}
requestDataPolicy := map[string]interface{}{}
requestDataPolicy["members"] = tt.args.members
requestDataPolicy["status"] = tt.args.status
requestDataJSON, _ := json.Marshal(requestDataPolicy)
requestDataBody := bytes.NewReader(requestDataJSON)
request, err := http.NewRequest(
"PUT", fmt.Sprintf("http://localhost:9090/api/v1/group/%s", tt.args.api), requestDataBody)
if err != nil {
log.Println(err)
return
}
request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
request.Header.Add("Content-Type", "application/json")
response, err := client.Do(request)
if err != nil {
log.Println(err)
return
}
if response != nil {
assert.Equal(tt.expectedStatus, response.StatusCode, "Status Code is incorrect")
}
})
}
}
func Test_DeleteGroupAPI(t *testing.T) {
@@ -120,19 +293,28 @@ func Test_DeleteGroupAPI(t *testing.T) {
}{
{
name: "Delete Group - Valid",
verb: "DELETE",
args: args{
api: "/group?name=grouptests1",
api: base64.StdEncoding.EncodeToString([]byte("grouptests1")),
},
verb: "DELETE",
expectedStatus: 204,
expectedError: nil,
},
{
name: "Access Group After Delete - Invalid",
verb: "GET",
name: "Delete Group - Invalid",
args: args{
api: "/group?name=grouptests1",
api: base64.StdEncoding.EncodeToString([]byte("grouptests12345")),
},
verb: "DELETE",
expectedStatus: 404,
expectedError: nil,
},
{
name: "Access Group After Delete - Invalid",
args: args{
api: base64.StdEncoding.EncodeToString([]byte("grouptests1")),
},
verb: "GET",
expectedStatus: 500,
expectedError: nil,
},
@@ -140,19 +322,16 @@ func Test_DeleteGroupAPI(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &http.Client{
Timeout: 3 * time.Second,
}
// Add policy
requestDataPolicy := map[string]interface{}{}
requestDataJSON, _ := json.Marshal(requestDataPolicy)
requestDataBody := bytes.NewReader(requestDataJSON)
request, err := http.NewRequest(
tt.verb, fmt.Sprintf("http://localhost:9090/api/v1%s", tt.args.api), requestDataBody)
tt.verb, fmt.Sprintf("http://localhost:9090/api/v1/group/%s", tt.args.api), requestDataBody)
if err != nil {
log.Println(err)
return
@@ -167,8 +346,6 @@ func Test_DeleteGroupAPI(t *testing.T) {
if response != nil {
assert.Equal(tt.expectedStatus, response.StatusCode, "Status Code is incorrect")
}
})
}
}

106
integration/inspect_test.go Normal file
View File

@@ -0,0 +1,106 @@
package integration
import (
"fmt"
"log"
"net/http"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func Inspect(volume string, file string, enc bool) (*http.Response, error) {
requestURL := fmt.Sprintf("http://localhost:9090/api/v1/admin/inspect?volume=%s&file=%s&encrypt=%t", volume, file, enc)
request, err := http.NewRequest(
"GET", requestURL, nil)
if err != nil {
log.Println(err)
}
request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
request.Header.Add("Content-Type", "application/json")
client := &http.Client{
Timeout: 2 * time.Second,
}
response, err := client.Do(request)
return response, err
}
func TestInspect(t *testing.T) {
assert := assert.New(t)
type args struct {
volume string
file string
encrypt bool
}
// Inspect returns successful response always
tests := []struct {
name string
args args
expStatusCode int
expectedError bool
}{
{
name: "Test Invalid Path",
args: args{
volume: "/test-with-slash",
file: "/test-with-slash",
encrypt: false,
},
expStatusCode: 200,
expectedError: false,
},
{
name: "Test Invalid characters in Path",
args: args{
volume: "//test",
file: "//bucket",
encrypt: false,
},
expStatusCode: 200,
expectedError: true,
},
{
name: "Test valid bucket",
args: args{
volume: "test-bucket",
file: "test.txt",
encrypt: true,
},
expStatusCode: 200,
expectedError: false,
},
{
name: "Test Empty Path", // Un processable entity error
args: args{
volume: "",
file: "",
encrypt: false,
},
expStatusCode: 422,
expectedError: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
resp, err := Inspect(tt.args.volume, tt.args.file, tt.args.encrypt)
if tt.expectedError {
assert.Nil(err)
if err != nil {
log.Println(err)
return
}
}
if resp != nil {
assert.Equal(
tt.expStatusCode,
resp.StatusCode,
)
}
})
}
}

View File

@@ -32,7 +32,6 @@ import (
)
func TestLoginStrategy(t *testing.T) {
assert := assert.New(t)
// image for now:
@@ -70,11 +69,9 @@ func TestLoginStrategy(t *testing.T) {
assert.Equal(models.LoginDetailsLoginStrategyForm, loginDetails.LoginStrategy, "Login Details don't match")
}
}
func TestLogout(t *testing.T) {
assert := assert.New(t)
// image for now:
@@ -133,5 +130,34 @@ func TestLogout(t *testing.T) {
assert.NotNil(response, "Logout response is nil")
assert.Nil(err, "Logout errored out")
assert.Equal(response.StatusCode, 200)
}
func TestBadLogin(t *testing.T) {
assert := assert.New(t)
client := &http.Client{
Timeout: 2 * time.Second,
}
requestData := map[string]string{
"accessKey": "minioadmin",
"secretKey": "minioadminbad",
}
requestDataJSON, _ := json.Marshal(requestData)
requestDataBody := bytes.NewReader(requestDataJSON)
request, err := http.NewRequest("POST", "http://localhost:9090/api/v1/login", requestDataBody)
if err != nil {
log.Println(err)
return
}
request.Header.Add("Content-Type", "application/json")
response, err := client.Do(request)
assert.Equal(response.StatusCode, 500, "Login request not rejected")
assert.NotNil(response, "Login response is nil")
assert.Nil(err, "Login errored out")
}

View File

@@ -34,7 +34,6 @@ import (
)
func TestObjectGet(t *testing.T) {
// for setup we'll create a bucket and upload a file
endpoint := "localhost:9000"
accessKeyID := "minioadmin"
@@ -194,5 +193,4 @@ func TestObjectGet(t *testing.T) {
}
})
}
}

View File

@@ -18,6 +18,7 @@ package integration
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
@@ -31,7 +32,7 @@ import (
"github.com/stretchr/testify/assert"
)
func AddPolicy(name string, definition string) (*http.Response, error) {
func AddPolicy(name, definition string) (*http.Response, error) {
/*
This is an atomic function to add user and can be reused across
different functions.
@@ -59,7 +60,7 @@ func AddPolicy(name string, definition string) (*http.Response, error) {
return response, err
}
func SetPolicy(policies []string, entityName string, entityType string) (*http.Response, error) {
func SetPolicy(policies []string, entityName, entityType string) (*http.Response, error) {
/*
This is an atomic function to add user and can be reused across
different functions.
@@ -153,11 +154,35 @@ func Test_AddPolicyAPI(t *testing.T) {
expectedStatus: 500,
expectedError: nil,
},
{
name: "Create Policy - Space in Name",
args: args{
api: "/policies",
name: "space test",
policy: swag.String(`
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::*"
]
}
]
}`),
},
expectedStatus: 400,
expectedError: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &http.Client{
Timeout: 3 * time.Second,
}
@@ -188,7 +213,6 @@ func Test_AddPolicyAPI(t *testing.T) {
}
})
}
}
func Test_SetPolicyAPI(t *testing.T) {
@@ -273,7 +297,6 @@ func Test_SetPolicyAPI(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &http.Client{
Timeout: 3 * time.Second,
}
@@ -305,7 +328,6 @@ func Test_SetPolicyAPI(t *testing.T) {
}
})
}
}
func Test_SetPolicyMultipleAPI(t *testing.T) {
@@ -387,7 +409,6 @@ func Test_SetPolicyMultipleAPI(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &http.Client{
Timeout: 3 * time.Second,
}
@@ -417,7 +438,6 @@ func Test_SetPolicyMultipleAPI(t *testing.T) {
}
})
}
}
func Test_ListPoliciesAPI(t *testing.T) {
@@ -444,7 +464,6 @@ func Test_ListPoliciesAPI(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &http.Client{
Timeout: 3 * time.Second,
}
@@ -467,7 +486,6 @@ func Test_ListPoliciesAPI(t *testing.T) {
}
})
}
}
func Test_GetPolicyAPI(t *testing.T) {
@@ -502,7 +520,7 @@ func Test_GetPolicyAPI(t *testing.T) {
{
name: "Get Policies - Invalid",
args: args{
api: "/policy?name=test3",
api: base64.StdEncoding.EncodeToString([]byte("test3")),
},
expectedStatus: 500,
expectedError: nil,
@@ -510,7 +528,7 @@ func Test_GetPolicyAPI(t *testing.T) {
{
name: "Get Policies - Valid",
args: args{
api: "/policy?name=getpolicytest",
api: base64.StdEncoding.EncodeToString([]byte("getpolicytest")),
},
expectedStatus: 200,
expectedError: nil,
@@ -519,13 +537,12 @@ func Test_GetPolicyAPI(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &http.Client{
Timeout: 3 * time.Second,
}
request, err := http.NewRequest(
"GET", fmt.Sprintf("http://localhost:9090/api/v1%s", tt.args.api), nil)
"GET", fmt.Sprintf("http://localhost:9090/api/v1/policy/%s", tt.args.api), nil)
if err != nil {
log.Println(err)
return
@@ -542,7 +559,6 @@ func Test_GetPolicyAPI(t *testing.T) {
}
})
}
}
func Test_PolicyListUsersAPI(t *testing.T) {
@@ -579,7 +595,7 @@ func Test_PolicyListUsersAPI(t *testing.T) {
{
name: "List Users for Policy - Valid",
args: args{
api: "/policies/policylistusers/users",
api: "/policies/" + base64.StdEncoding.EncodeToString([]byte("policylistusers")) + "/users",
},
expectedStatus: 200,
expectedError: nil,
@@ -587,7 +603,7 @@ func Test_PolicyListUsersAPI(t *testing.T) {
{
name: "List Users for Policy - Invalid",
args: args{
api: "/policies/test2/users",
api: "/policies/" + base64.StdEncoding.EncodeToString([]byte("test2")) + "/users",
},
expectedStatus: 404,
expectedError: nil,
@@ -596,7 +612,6 @@ func Test_PolicyListUsersAPI(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &http.Client{
Timeout: 3 * time.Second,
}
@@ -621,10 +636,8 @@ func Test_PolicyListUsersAPI(t *testing.T) {
assert.Equal("[\"policyuser4\"]\n", string(bodyBytes))
}
}
})
}
}
func Test_PolicyListGroupsAPI(t *testing.T) {
@@ -661,7 +674,8 @@ func Test_PolicyListGroupsAPI(t *testing.T) {
{
name: "List Users for Policy - Valid",
args: args{
api: "/policies/policylistgroups/groups",
api: "/policies/" + base64.StdEncoding.EncodeToString([]byte("policylistgroups")) + "/groups",
},
expectedStatus: 200,
expectedError: nil,
@@ -669,7 +683,7 @@ func Test_PolicyListGroupsAPI(t *testing.T) {
{
name: "List Users for Policy - Invalid",
args: args{
api: "/policies/test3/groups",
api: "/policies/" + base64.StdEncoding.EncodeToString([]byte("test3")) + "/groups",
},
expectedStatus: 404,
expectedError: nil,
@@ -678,7 +692,6 @@ func Test_PolicyListGroupsAPI(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &http.Client{
Timeout: 3 * time.Second,
}
@@ -703,10 +716,8 @@ func Test_PolicyListGroupsAPI(t *testing.T) {
assert.Equal("[\"testgroup12345\"]\n", string(bodyBytes))
}
}
})
}
}
func Test_DeletePolicyAPI(t *testing.T) {
@@ -741,7 +752,7 @@ func Test_DeletePolicyAPI(t *testing.T) {
{
name: "Delete Policies - Valid",
args: args{
api: "/policy?name=testdelete",
api: base64.StdEncoding.EncodeToString([]byte("testdelete")),
method: "DELETE",
},
expectedStatus: 204,
@@ -750,7 +761,7 @@ func Test_DeletePolicyAPI(t *testing.T) {
{
name: "Get Policy After Delete - Invalid",
args: args{
api: "/policy?name=testdelete",
api: base64.StdEncoding.EncodeToString([]byte("testdelete")),
method: "GET",
},
expectedStatus: 500,
@@ -760,13 +771,12 @@ func Test_DeletePolicyAPI(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &http.Client{
Timeout: 3 * time.Second,
}
request, err := http.NewRequest(
tt.args.method, fmt.Sprintf("http://localhost:9090/api/v1%s", tt.args.api), nil)
tt.args.method, fmt.Sprintf("http://localhost:9090/api/v1/policy/%s", tt.args.api), nil)
if err != nil {
log.Println(err)
return
@@ -783,5 +793,4 @@ func Test_DeletePolicyAPI(t *testing.T) {
}
})
}
}

View File

@@ -43,7 +43,6 @@ func TestStartProfiling(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
files := map[string]bool{
"profile-127.0.0.1:9000-goroutines.txt": false,
"profile-127.0.0.1:9000-goroutines-before.txt": false,

View File

@@ -18,6 +18,7 @@ package integration
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"log"
@@ -74,7 +75,8 @@ func TestAddServiceAccount(t *testing.T) {
assert.Equal(201, response.StatusCode, "Status Code is incorrect")
}
requestDataPolicy := map[string]interface{}{"policy": `
requestDataPolicy := map[string]interface{}{
"policy": `
{
"Version": "2012-10-17",
"Statement": [
@@ -94,7 +96,7 @@ func TestAddServiceAccount(t *testing.T) {
requestDataJSON, _ = json.Marshal(requestDataPolicy)
requestDataBody = bytes.NewReader(requestDataJSON)
request, err = http.NewRequest(
"PUT", "http://localhost:9090/api/v1/service-accounts/testuser1/policy", requestDataBody)
"PUT", "http://localhost:9090/api/v1/service-accounts/"+base64.StdEncoding.EncodeToString([]byte("testuser1"))+"/policy", requestDataBody)
if err != nil {
log.Println(err)
return
@@ -113,7 +115,7 @@ func TestAddServiceAccount(t *testing.T) {
// Test policy
request, err = http.NewRequest(
"GET", "http://localhost:9090/api/v1/service-accounts/testuser1/policy", nil)
"GET", "http://localhost:9090/api/v1/service-accounts/"+base64.StdEncoding.EncodeToString([]byte("testuser1"))+"/policy", nil)
if err != nil {
log.Println(err)
return
@@ -145,7 +147,7 @@ func TestAddServiceAccount(t *testing.T) {
// {{baseUrl}}/user?name=proident velit
// Investiga como se borra en el browser.
request, err = http.NewRequest(
"DELETE", "http://localhost:9090/api/v1/service-accounts/testuser1", nil)
"DELETE", "http://localhost:9090/api/v1/service-accounts/"+base64.StdEncoding.EncodeToString([]byte("testuser1")), nil)
if err != nil {
log.Println(err)
return
@@ -161,7 +163,6 @@ func TestAddServiceAccount(t *testing.T) {
fmt.Println("DELETE StatusCode:", response.StatusCode)
assert.Equal(204, response.StatusCode, "has to be 204 when delete user")
}
}
func Test_ServiceAccountsAPI(t *testing.T) {
@@ -238,7 +239,6 @@ func Test_ServiceAccountsAPI(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &http.Client{
Timeout: 3 * time.Second,
}
@@ -268,10 +268,8 @@ func Test_ServiceAccountsAPI(t *testing.T) {
if response != nil {
assert.Equal(tt.expectedStatus, response.StatusCode, "Status Code is incorrect")
}
})
}
}
func DeleteMultipleServiceAccounts(serviceAccounts []string) (*http.Response, error) {
@@ -310,9 +308,9 @@ func TestCreateServiceAccountForUserWithCredentials(t *testing.T) {
serviceAccountLengthInBytes := 40 // As observed, update as needed
// 1. Create the user
var groups = []string{}
var policies = []string{}
var secretKey = "testcreateserviceaccountforuserwithcrede"
groups := []string{}
policies := []string{}
secretKey := "testcreateserviceaccountforuserwithcrede"
response, err := AddUser(userName, "secretKey", groups, policies)
if err != nil {
log.Println(err)
@@ -405,5 +403,4 @@ func TestCreateServiceAccountForUserWithCredentials(t *testing.T) {
inspectHTTPResponse(response),
)
}
}

View File

@@ -27,7 +27,6 @@ import (
)
func TestTiersList(t *testing.T) {
assert := assert.New(t)
// image for now:
@@ -51,5 +50,4 @@ func TestTiersList(t *testing.T) {
assert.NotNil(response, "Tiers List response is nil")
assert.Nil(err, "Tiers List errored out")
assert.Equal(response.StatusCode, 200)
}

View File

@@ -20,6 +20,7 @@ package integration
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
@@ -34,10 +35,12 @@ import (
"time"
"github.com/minio/console/models"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
"github.com/stretchr/testify/assert"
)
func AddBucket(name string, locking bool, versioning bool, quota map[string]interface{}, retention map[string]interface{}) (*http.Response, error) {
func AddBucket(name string, locking, versioning bool, quota, retention map[string]interface{}) (*http.Response, error) {
/*
This is an atomic function that we can re-use to create a bucket on any
desired test.
@@ -69,7 +72,7 @@ func AddBucket(name string, locking bool, versioning bool, quota map[string]inte
return response, err
}
func BucketGotAdded(name string, locking bool, versioning bool, quota map[string]interface{}, retention map[string]interface{}, assert *assert.Assertions, expected int) bool {
func BucketGotAdded(name string, locking, versioning bool, quota, retention map[string]interface{}, assert *assert.Assertions, expected int) bool {
/*
The intention of this function is to return either true or false to
reduce the code by performing the verification in one place only.
@@ -148,7 +151,7 @@ func BucketInfo(name string) (*http.Response, error) {
return response, err
}
func SetBucketRetention(bucketName string, mode string, unit string, validity int) (*http.Response, error) {
func SetBucketRetention(bucketName, mode, unit string, validity int) (*http.Response, error) {
/*
Helper function to set bucket's retention
PUT: {{baseUrl}}/buckets/:bucket_name/retention
@@ -199,7 +202,7 @@ func GetBucketRetention(bucketName string) (*http.Response, error) {
return response, err
}
func PutObjectTags(bucketName string, prefix string, tags map[string]string, versionID string) (*http.Response, error) {
func PutObjectTags(bucketName, prefix string, tags map[string]string, versionID string) (*http.Response, error) {
/*
Helper function to put object's tags.
PUT: /buckets/{bucket_name}/objects/tags?prefix=prefix
@@ -267,7 +270,7 @@ func DeleteMultipleObjects(bucketName string, files []map[string]interface{}) (*
return response, err
}
func DownloadObject(bucketName string, path string) (*http.Response, error) {
func DownloadObject(bucketName, path string) (*http.Response, error) {
/*
Helper function to download an object from a bucket.
GET: {{baseUrl}}/buckets/bucketName/objects/download?prefix=file
@@ -290,7 +293,7 @@ func DownloadObject(bucketName string, path string) (*http.Response, error) {
return response, err
}
func UploadAnObject(bucketName string, fileName string) (*http.Response, error) {
func UploadAnObject(bucketName, fileName string) (*http.Response, error) {
/*
Helper function to upload a file to a bucket for testing.
POST {{baseUrl}}/buckets/:bucket_name/objects/upload
@@ -299,10 +302,10 @@ func UploadAnObject(bucketName string, fileName string) (*http.Response, error)
boundaryStart := "------" + boundary + "\r\n"
contentDispositionOne := "Content-Disposition: form-data; name=\"2\"; "
contentDispositionTwo := "filename=\"" + fileName + "\"\r\n"
contenType := "Content-Type: text/plain\r\n\r\na\n\r\n"
contentType := "Content-Type: text/plain\r\n\r\na\n\r\n"
boundaryEnd := "------" + boundary + "--\r\n"
file := boundaryStart + contentDispositionOne + contentDispositionTwo +
contenType + boundaryEnd
contentType + boundaryEnd
arrayOfBytes := []byte(file)
requestDataBody := bytes.NewReader(arrayOfBytes)
request, err := http.NewRequest(
@@ -325,7 +328,7 @@ func UploadAnObject(bucketName string, fileName string) (*http.Response, error)
return response, err
}
func DeleteObject(bucketName string, path string, recursive bool, allVersions bool) (*http.Response, error) {
func DeleteObject(bucketName, path string, recursive, allVersions bool) (*http.Response, error) {
/*
Helper function to delete an object from a given bucket.
DELETE:
@@ -351,7 +354,7 @@ func DeleteObject(bucketName string, path string, recursive bool, allVersions bo
return response, err
}
func ListObjects(bucketName string, prefix string, withVersions string) (*http.Response, error) {
func ListObjects(bucketName, prefix, withVersions string) (*http.Response, error) {
/*
Helper function to list objects in a bucket.
GET: {{baseUrl}}/buckets/:bucket_name/objects
@@ -371,7 +374,7 @@ func ListObjects(bucketName string, prefix string, withVersions string) (*http.R
return response, err
}
func SharesAnObjectOnAUrl(bucketName string, prefix string, versionID string, expires string) (*http.Response, error) {
func SharesAnObjectOnAUrl(bucketName, prefix, versionID, expires string) (*http.Response, error) {
// Helper function to share an object on a url
request, err := http.NewRequest(
"GET",
@@ -390,7 +393,7 @@ func SharesAnObjectOnAUrl(bucketName string, prefix string, versionID string, ex
return response, err
}
func PutObjectsRetentionStatus(bucketName string, prefix string, versionID string, mode string, expires string, governanceBypass bool) (*http.Response, error) {
func PutObjectsRetentionStatus(bucketName, prefix, versionID, mode, expires string, governanceBypass bool) (*http.Response, error) {
requestDataAdd := map[string]interface{}{
"mode": mode,
"expires": expires,
@@ -415,7 +418,7 @@ func PutObjectsRetentionStatus(bucketName string, prefix string, versionID strin
return response, err
}
func GetsTheMetadataOfAnObject(bucketName string, prefix string) (*http.Response, error) {
func GetsTheMetadataOfAnObject(bucketName, prefix string) (*http.Response, error) {
/*
Gets the metadata of an object
GET
@@ -466,7 +469,7 @@ func PutBucketsTags(bucketName string, tags map[string]string) (*http.Response,
return response, err
}
func RestoreObjectToASelectedVersion(bucketName string, prefix string, versionID string) (*http.Response, error) {
func RestoreObjectToASelectedVersion(bucketName, prefix, versionID string) (*http.Response, error) {
request, err := http.NewRequest(
"PUT",
"http://localhost:9090/api/v1/buckets/"+bucketName+"/objects/restore?prefix="+prefix+"&version_id="+versionID,
@@ -484,7 +487,7 @@ func RestoreObjectToASelectedVersion(bucketName string, prefix string, versionID
return response, err
}
func BucketSetPolicy(bucketName string, access string, definition string) (*http.Response, error) {
func BucketSetPolicy(bucketName, access, definition string) (*http.Response, error) {
/*
Helper function to set policy on a bucket
Name: Bucket Set Policy
@@ -519,7 +522,7 @@ func BucketSetPolicy(bucketName string, access string, definition string) (*http
return response, err
}
func DeleteObjectsRetentionStatus(bucketName string, prefix string, versionID string) (*http.Response, error) {
func DeleteObjectsRetentionStatus(bucketName, prefix, versionID string) (*http.Response, error) {
/*
Helper function to Delete Object Retention Status
DELETE:
@@ -629,7 +632,7 @@ func GetBucketQuota(bucketName string) (*http.Response, error) {
return response, err
}
func PutObjectsLegalholdStatus(bucketName string, prefix string, status string, versionID string) (*http.Response, error) {
func PutObjectsLegalholdStatus(bucketName, prefix, status, versionID string) (*http.Response, error) {
// Helper function to test "Put Object's legalhold status" end point
requestDataAdd := map[string]interface{}{
"status": status,
@@ -654,7 +657,6 @@ func PutObjectsLegalholdStatus(bucketName string, prefix string, status string,
}
func TestPutObjectsLegalholdStatus(t *testing.T) {
// Variables
assert := assert.New(t)
bucketName := "testputobjectslegalholdstatus"
@@ -742,11 +744,9 @@ func TestPutObjectsLegalholdStatus(t *testing.T) {
}
})
}
}
func TestGetBucketQuota(t *testing.T) {
// Variables
assert := assert.New(t)
validBucket := "testgetbucketquota"
@@ -821,11 +821,9 @@ func TestGetBucketQuota(t *testing.T) {
}
})
}
}
func TestPutBucketQuota(t *testing.T) {
// Variables
assert := assert.New(t)
validBucket := "testputbucketquota"
@@ -882,11 +880,9 @@ func TestPutBucketQuota(t *testing.T) {
}
})
}
}
func TestListBucketEvents(t *testing.T) {
// Variables
assert := assert.New(t)
validBucket := "testlistbucketevents"
@@ -922,7 +918,6 @@ func TestListBucketEvents(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
restResp, restErr := ListBucketEvents(
tt.args.bucketName,
)
@@ -939,14 +934,11 @@ func TestListBucketEvents(t *testing.T) {
finalResponse,
)
}
})
}
}
func TestDeleteObjectsRetentionStatus(t *testing.T) {
// Variables
assert := assert.New(t)
bucketName := "testdeleteobjectslegalholdstatus"
@@ -1053,11 +1045,9 @@ func TestDeleteObjectsRetentionStatus(t *testing.T) {
}
})
}
}
func TestBucketSetPolicy(t *testing.T) {
// Variables
assert := assert.New(t)
validBucketName := "testbucketsetpolicy"
@@ -1093,7 +1083,6 @@ func TestBucketSetPolicy(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Set Policy
restResp, restErr := BucketSetPolicy(
tt.args.bucketName,
@@ -1113,14 +1102,11 @@ func TestBucketSetPolicy(t *testing.T) {
finalResponse,
)
}
})
}
}
func TestRestoreObjectToASelectedVersion(t *testing.T) {
// Variables
assert := assert.New(t)
bucketName := "testrestoreobjectstoselectedversion"
@@ -1208,11 +1194,9 @@ func TestRestoreObjectToASelectedVersion(t *testing.T) {
}
})
}
}
func TestPutBucketsTags(t *testing.T) {
// Focused test for "Put Bucket's tags" endpoint
// 1. Create the bucket
@@ -1247,7 +1231,6 @@ func TestPutBucketsTags(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// 2. Add a tag to the bucket
tags := make(map[string]string)
tags["tag2"] = "tag2"
@@ -1263,14 +1246,11 @@ func TestPutBucketsTags(t *testing.T) {
tt.expectedStatus, putBucketTagResponse.StatusCode,
inspectHTTPResponse(putBucketTagResponse))
}
})
}
}
func TestGetsTheMetadataOfAnObject(t *testing.T) {
// Vars
assert := assert.New(t)
bucketName := "testgetsthemetadataofanobject"
@@ -1324,7 +1304,6 @@ func TestGetsTheMetadataOfAnObject(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// 3. Get the metadata from an object
getRsp, getErr := GetsTheMetadataOfAnObject(
bucketName, tt.args.prefix)
@@ -1340,14 +1319,11 @@ func TestGetsTheMetadataOfAnObject(t *testing.T) {
inspectHTTPResponse(getRsp),
)
}
})
}
}
func TestPutObjectsRetentionStatus(t *testing.T) {
// Variables
assert := assert.New(t)
bucketName := "testputobjectsretentionstatus"
@@ -1436,7 +1412,6 @@ func TestPutObjectsRetentionStatus(t *testing.T) {
}
})
}
}
func TestShareObjectOnURL(t *testing.T) {
@@ -1498,7 +1473,6 @@ func TestShareObjectOnURL(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// 3. Share the object on a URL
shareResponse, shareError := SharesAnObjectOnAUrl(bucketName, tt.args.prefix, versionID, "604800s")
assert.Nil(shareError)
@@ -1514,10 +1488,8 @@ func TestShareObjectOnURL(t *testing.T) {
finalResponse,
)
}
})
}
}
func TestListObjects(t *testing.T) {
@@ -1564,7 +1536,6 @@ func TestListObjects(t *testing.T) {
assert.True(
strings.Contains(finalResponse, "testlistobjecttobucket1"),
finalResponse)
}
func TestDeleteObject(t *testing.T) {
@@ -1633,7 +1604,6 @@ func TestDeleteObject(t *testing.T) {
strings.Contains(
finalResponse,
"testdeleteobjectfile1.txt"), finalResponse) // Gone
}
func TestUploadObjectToBucket(t *testing.T) {
@@ -1664,7 +1634,6 @@ func TestUploadObjectToBucket(t *testing.T) {
if uploadResponse != nil {
assert.Equal(200, uploadResponse.StatusCode, finalResponse)
}
}
func TestDownloadObject(t *testing.T) {
@@ -1731,7 +1700,6 @@ func TestDownloadObject(t *testing.T) {
// path/to/whatever does not exist
assert.Fail("File wasn't downloaded")
}
}
func TestDeleteMultipleObjects(t *testing.T) {
@@ -1806,7 +1774,6 @@ func TestDeleteMultipleObjects(t *testing.T) {
// 5. Verify empty list is obtained as we deleted all the objects
expected := "Http Response: {\"objects\":null}\n"
assert.Equal(expected, finalResponse, finalResponse)
}
func TestPutObjectTag(t *testing.T) {
@@ -1872,7 +1839,6 @@ func TestPutObjectTag(t *testing.T) {
assert.True(
strings.Contains(finalResponse, tags["tag"]),
finalResponse)
}
func TestBucketRetention(t *testing.T) {
@@ -1941,7 +1907,6 @@ func TestBucketRetention(t *testing.T) {
}
expected := "Http Response: {\"mode\":\"compliance\",\"unit\":\"years\",\"validity\":3}\n"
assert.Equal(expected, finalResponse, finalResponse)
}
func TestBucketInformationGenericErrorResponse(t *testing.T) {
@@ -1987,7 +1952,6 @@ func TestBucketInformationGenericErrorResponse(t *testing.T) {
// Since bucketinformation3 hasn't been created, then it is expected that
// tag2 is not part of the response, this is why assert.False is used.
assert.False(strings.Contains(finalResponse, "tag2"), finalResponse)
}
func TestBucketInformationSuccessfulResponse(t *testing.T) {
@@ -2038,51 +2002,66 @@ func TestBucketInformationSuccessfulResponse(t *testing.T) {
assert.True(
strings.Contains(debugResponse, "tag1"),
inspectHTTPResponse(bucketInfoResponse))
}
func TestDeleteBucket(t *testing.T) {
/*
Test to delete a bucket
*/
// 1. Create the bucket
assert := assert.New(t)
if !BucketGotAdded("testdeletebucket1", false, false, nil, nil, assert, 201) {
return
type args struct {
bucketName string
createBucketName string
}
tests := []struct {
name string
args args
expectedStatus int
}{
{
name: "Delete a bucket",
expectedStatus: 204,
args: args{
bucketName: "testdeletebucket1",
createBucketName: "testdeletebucket1",
},
}, {
name: "Delete invalid bucket",
expectedStatus: 404,
args: args{
bucketName: "nonexistingbucket",
createBucketName: "",
},
},
}
// 2. Delete the bucket
deleteBucketResponse, deleteBucketError := DeleteBucket("testdeletebucket1")
assert.Nil(deleteBucketError)
if deleteBucketError != nil {
log.Println(deleteBucketError)
return
}
if deleteBucketResponse != nil {
assert.Equal(
204, deleteBucketResponse.StatusCode, "Status Code is incorrect")
// Initialize minio client object.
minioClient, err := minio.New("localhost:9000", &minio.Options{
Creds: credentials.NewStaticV4("minioadmin", "minioadmin", ""),
Secure: false,
})
if err != nil {
log.Fatalln(err)
}
// 3. Verify the bucket is gone by trying to put a tag
tags := make(map[string]string)
tags["tag1"] = "tag1"
putBucketTagResponse, putBucketTagError := PutBucketsTags(
"testdeletebucket1", tags)
if putBucketTagError != nil {
log.Println(putBucketTagError)
assert.Fail("Error adding a tag to the bucket")
return
}
finalResponse := inspectHTTPResponse(putBucketTagResponse)
if putBucketTagResponse != nil {
assert.Equal(
500, putBucketTagResponse.StatusCode,
finalResponse)
}
assert.True(
strings.Contains(finalResponse, "The specified bucket does not exist"))
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Create bucket if needed for the test
if tt.args.createBucketName != "" {
if err := minioClient.MakeBucket(context.Background(), tt.args.createBucketName, minio.MakeBucketOptions{}); err != nil {
assert.Failf("Failed to create bucket", "Could not create bucket %s: %v", tt.args.createBucketName, err)
}
}
// Delete the bucket
deleteBucketResponse, deleteBucketError := DeleteBucket(tt.args.bucketName)
assert.Nil(deleteBucketError)
if deleteBucketResponse != nil {
assert.Equal(
tt.expectedStatus, deleteBucketResponse.StatusCode, "Status Code is incorrect")
}
})
}
}
func TestListBuckets(t *testing.T) {
@@ -2093,7 +2072,7 @@ func TestListBuckets(t *testing.T) {
assert := assert.New(t)
// 1. Create buckets
var numberOfBuckets = 3
numberOfBuckets := 3
for i := 1; i <= numberOfBuckets; i++ {
if !BucketGotAdded("testlistbuckets"+strconv.Itoa(i), false, false, nil, nil, assert, 201) {
return
@@ -2122,11 +2101,9 @@ func TestListBuckets(t *testing.T) {
assert.True(strings.Contains(string(b),
"testlistbuckets"+strconv.Itoa(i)))
}
}
func TestBucketsGet(t *testing.T) {
assert := assert.New(t)
client := &http.Client{
@@ -2164,11 +2141,9 @@ func TestBucketsGet(t *testing.T) {
assert.Greater(listBuckets.Total, int64(0), "Total buckets is 0")
}
}
func TestBucketVersioning(t *testing.T) {
assert := assert.New(t)
client := &http.Client{
@@ -2268,11 +2243,9 @@ func TestBucketVersioning(t *testing.T) {
if response != nil {
fmt.Println("DELETE StatusCode:", response.StatusCode)
}
}
func TestSetBucketTags(t *testing.T) {
assert := assert.New(t)
client := &http.Client{
@@ -2338,11 +2311,9 @@ func TestSetBucketTags(t *testing.T) {
}
assert.Equal("TAG", bucket.Details.Tags["test"], "Failed to add tag")
}
func TestGetBucket(t *testing.T) {
assert := assert.New(t)
client := &http.Client{
@@ -2373,11 +2344,9 @@ func TestGetBucket(t *testing.T) {
if response != nil {
assert.Equal(200, response.StatusCode, "Status Code is incorrect")
}
}
func TestAddBucket(t *testing.T) {
assert := assert.New(t)
type args struct {
bucketName string
@@ -2409,10 +2378,9 @@ func TestAddBucket(t *testing.T) {
}
})
}
}
func CreateBucketEvent(bucketName string, ignoreExisting bool, arn string, prefix string, suffix string, events []string) (*http.Response, error) {
func CreateBucketEvent(bucketName string, ignoreExisting bool, arn, prefix, suffix string, events []string) (*http.Response, error) {
/*
Helper function to create bucket event
POST: /buckets/{bucket_name}/events
@@ -2456,7 +2424,7 @@ func CreateBucketEvent(bucketName string, ignoreExisting bool, arn string, prefi
return response, err
}
func DeleteBucketEvent(bucketName string, arn string, events []string, prefix string, suffix string) (*http.Response, error) {
func DeleteBucketEvent(bucketName, arn string, events []string, prefix, suffix string) (*http.Response, error) {
/*
Helper function to test Delete Bucket Event
DELETE: /buckets/{bucket_name}/events/{arn}
@@ -2491,7 +2459,6 @@ func DeleteBucketEvent(bucketName string, arn string, events []string, prefix st
}
func TestDeleteBucketEvent(t *testing.T) {
// Variables
assert := assert.New(t)
@@ -2571,10 +2538,9 @@ func TestDeleteBucketEvent(t *testing.T) {
efinalResponseEvent,
)
}
}
func SetMultiBucketReplication(accessKey string, secretKey string, targetURL string, region string, originBucket string, destinationBucket string, syncMode string, bandwidth int, healthCheckPeriod int, prefix string, tags string, replicateDeleteMarkers bool, replicateDeletes bool, priority int, storageClass string, replicateMetadata bool) (*http.Response, error) {
func SetMultiBucketReplication(accessKey, secretKey, targetURL, region, originBucket, destinationBucket, syncMode string, bandwidth, healthCheckPeriod int, prefix, tags string, replicateDeleteMarkers, replicateDeletes bool, priority int, storageClass string, replicateMetadata bool) (*http.Response, error) {
/*
Helper function
URL: /buckets-replication
@@ -2716,7 +2682,7 @@ func DeleteMultipleReplicationRules(bucketName string, rules []string) (*http.Re
return response, err
}
func DeleteBucketReplicationRule(bucketName string, ruleID string) (*http.Response, error) {
func DeleteBucketReplicationRule(bucketName, ruleID string) (*http.Response, error) {
/*
Helper function to delete a bucket's replication rule
URL: /buckets/{bucket_name}/replication/{rule_id}
@@ -2740,7 +2706,6 @@ func DeleteBucketReplicationRule(bucketName string, ruleID string) (*http.Respon
}
func TestReplication(t *testing.T) {
// Vars
assert := assert.New(t)
originBucket := "testputobjectslegalholdstatus"
@@ -2898,7 +2863,7 @@ func ReturnsTheStatusOfObjectLockingSupportOnTheBucket(bucketName string) (*http
return BaseGetFunction(bucketName, endPoint)
}
func BaseGetFunction(bucketName string, endPoint string) (*http.Response, error) {
func BaseGetFunction(bucketName, endPoint string) (*http.Response, error) {
request, err := http.NewRequest(
"GET",
"http://localhost:9090/api/v1/buckets/"+bucketName+"/"+endPoint, nil)
@@ -2947,7 +2912,6 @@ func TestReturnsTheStatusOfObjectLockingSupportOnTheBucket(t *testing.T) {
true,
structBucketLocking,
)
}
func SetBucketVersioning(bucketName string, versioning bool) (*http.Response, error) {
@@ -2975,7 +2939,6 @@ func SetBucketVersioning(bucketName string, versioning bool) (*http.Response, er
}
func TestSetBucketVersioning(t *testing.T) {
// Variables
assert := assert.New(t)
bucket := "test-set-bucket-versioning"
@@ -3018,20 +2981,17 @@ func TestSetBucketVersioning(t *testing.T) {
assert.Nil(err)
}
assert.Equal(false, result.IsVersioned, result)
}
func EnableBucketEncryption(bucketName string, encType string, kmsKeyID string) (*http.Response, error) {
/*
Helper function to enable bucket encryption
HTTP Verb: POST
URL: /buckets/{bucket_name}/encryption/enable
Body:
{
"encType":"sse-s3",
"kmsKeyID":""
}
*/
func EnableBucketEncryption(bucketName, encType, kmsKeyID string) (*http.Response, error) {
// Helper function to enable bucket encryption
// HTTP Verb: POST
// URL: /buckets/{bucket_name}/encryption/enable
// Body:
// {
// "encType":"sse-s3",
// "kmsKeyID":""
// }
requestDataAdd := map[string]interface{}{
"encType": encType,
"kmsKeyID": kmsKeyID,
@@ -3055,7 +3015,6 @@ func EnableBucketEncryption(bucketName string, encType string, kmsKeyID string)
}
func TestEnableBucketEncryption(t *testing.T) {
// Variables
assert := assert.New(t)
bucketName := "test-enable-bucket-encryption"
@@ -3133,7 +3092,6 @@ func TestEnableBucketEncryption(t *testing.T) {
}
dereferencedPointerDetailedMessage := *result2.DetailedMessage
assert.Equal("error server side encryption configuration not found", dereferencedPointerDetailedMessage, dereferencedPointerDetailedMessage)
}
func GetBucketEncryptionInformation(bucketName string) (*http.Response, error) {
@@ -3180,24 +3138,23 @@ func DisableBucketEncryption(bucketName string) (*http.Response, error) {
return response, err
}
func UpdateLifecycleRule(bucketName string, Type string, disable bool, prefix string, tags string, expiredObjectDeleteMarker bool, expiryDays int64, noncurrentversionExpirationDays int64, lifecycleID string) (*http.Response, error) {
/*
Helper function to update lifecycle rule
HTTP Verb: PUT
URL: /buckets/{bucket_name}/lifecycle/{lifecycle_id}
Body Example:
{
"type":"expiry",
"disable":false,
"prefix":"",
"tags":"",
"expired_object_delete_marker":false,
"expiry_days":2,
"noncurrentversion_expiration_days":0
}
*/
func UpdateLifecycleRule(bucketName, ltype string, disable bool, prefix, tags string, expiredObjectDeleteMarker bool, expiryDays, noncurrentversionExpirationDays int64, lifecycleID string) (*http.Response, error) {
// Helper function to update lifecycle rule
// HTTP Verb: PUT
// URL: /buckets/{bucket_name}/lifecycle/{lifecycle_id}
// Body Example:
// {
// "type":"expiry",
// "disable":false,
// "prefix":"",
// "tags":"",
// "expired_object_delete_marker":false,
// "expiry_days":2,
// "noncurrentversion_expiration_days":0
// }
requestDataAdd := map[string]interface{}{
"type": Type,
"type": ltype,
"disable": disable,
"prefix": prefix,
"tags": tags,
@@ -3223,28 +3180,26 @@ func UpdateLifecycleRule(bucketName string, Type string, disable bool, prefix st
}
func GetBucketLifeCycle(bucketName string) (*http.Response, error) {
/*
Get Bucket Lifecycle
HTTP Verb: GET
URL: /buckets/{bucket_name}/lifecycle
Response Example:
{
"lifecycle": [
{
"expiration": {
"date": "0001-01-01T00:00:00Z",
"days": 1
},
"id": "c8nmpte49b3m6uu3pac0",
"status": "Enabled",
"tags": null,
"transition": {
"date": "0001-01-01T00:00:00Z"
}
}
]
}
*/
// Get Bucket Lifecycle
// HTTP Verb: GET
// URL: /buckets/{bucket_name}/lifecycle
// Response Example:
// {
// "lifecycle": [
// {
// "expiration": {
// "date": "0001-01-01T00:00:00Z",
// "days": 1
// },
// "id": "c8nmpte49b3m6uu3pac0",
// "status": "Enabled",
// "tags": null,
// "transition": {
// "date": "0001-01-01T00:00:00Z"
// }
// }
// ]
// }
request, err := http.NewRequest(
"GET", "http://localhost:9090/api/v1/buckets/"+bucketName+"/lifecycle", nil)
if err != nil {
@@ -3259,24 +3214,22 @@ func GetBucketLifeCycle(bucketName string) (*http.Response, error) {
return response, err
}
func AddBucketLifecycle(bucketName string, Type string, prefix string, tags string, expiredObjectDeleteMarker bool, expiryDays int64, noncurrentversionExpirationDays int64) (*http.Response, error) {
/*
Helper function to add bucket lifecycle
URL: /buckets/{bucket_name}/lifecycle
HTTP Verb: POST
Body Example:
{
"type":"expiry",
"prefix":"",
"tags":"",
"expired_object_delete_marker":false,
"expiry_days":1,
"noncurrentversion_expiration_days":null
}
*/
func AddBucketLifecycle(bucketName, ltype, prefix, tags string, expiredObjectDeleteMarker bool, expiryDays, noncurrentversionExpirationDays int64) (*http.Response, error) {
// Helper function to add bucket lifecycle
// URL: /buckets/{bucket_name}/lifecycle
// HTTP Verb: POST
// Body Example:
// {
// "type":"expiry",
// "prefix":"",
// "tags":"",
// "expired_object_delete_marker":false,
// "expiry_days":1,
// "noncurrentversion_expiration_days":null
// }
// Needed Parameters for API Call
requestDataAdd := map[string]interface{}{
"type": Type,
"type": ltype,
"prefix": prefix,
"tags": tags,
"expired_object_delete_marker": expiredObjectDeleteMarker,
@@ -3306,12 +3259,10 @@ func AddBucketLifecycle(bucketName string, Type string, prefix string, tags stri
return response, err
}
func DeleteLifecycleRule(bucketName string, lifecycleID string) (*http.Response, error) {
/*
Helper function to delete lifecycle rule
HTTP Verb: DELETE
URL: /buckets/{bucket_name}/lifecycle/{lifecycle_id}
*/
func DeleteLifecycleRule(bucketName, lifecycleID string) (*http.Response, error) {
// Helper function to delete lifecycle rule
// HTTP Verb: DELETE
// URL: /buckets/{bucket_name}/lifecycle/{lifecycle_id}
request, err := http.NewRequest(
"DELETE", "http://localhost:9090/api/v1/buckets/"+bucketName+"/lifecycle/"+lifecycleID, nil)
if err != nil {
@@ -3327,13 +3278,12 @@ func DeleteLifecycleRule(bucketName string, lifecycleID string) (*http.Response,
}
func TestBucketLifeCycle(t *testing.T) {
// Variables
assert := assert.New(t)
bucketName := "test-bucket-life-cycle"
locking := false
versioning := false
Type := "expiry"
ltype := "expiry"
prefix := ""
tags := ""
var expiryDays int64 = 1
@@ -3350,7 +3300,7 @@ func TestBucketLifeCycle(t *testing.T) {
// 2. Add Bucket Lifecycle
resp, err := AddBucketLifecycle(
bucketName,
Type,
ltype,
prefix,
tags,
expiredObjectDeleteMarker,
@@ -3394,7 +3344,7 @@ func TestBucketLifeCycle(t *testing.T) {
// 4. Update from 1 day expiration to 2 days expiration
resp, err = UpdateLifecycleRule(
bucketName,
Type,
ltype,
disable,
prefix,
tags,
@@ -3457,10 +3407,9 @@ func TestBucketLifeCycle(t *testing.T) {
assert.Equal(
404, resp.StatusCode, "Status Code is incorrect")
}
}
func SetAccessRuleWithBucket(bucketName string, prefix string, access string) (*http.Response, error) {
func SetAccessRuleWithBucket(bucketName, prefix, access string) (*http.Response, error) {
/*
Helper function to Set Access Rule within Bucket
HTTP Verb: PUT
@@ -3515,7 +3464,7 @@ func ListAccessRulesWithBucket(bucketName string) (*http.Response, error) {
return response, err
}
func DeleteAccessRuleWithBucket(bucketName string, prefix string) (*http.Response, error) {
func DeleteAccessRuleWithBucket(bucketName, prefix string) (*http.Response, error) {
/*
Helper function to Delete Access Rule With Bucket
HTTP Verb: DELETE
@@ -3545,7 +3494,6 @@ func DeleteAccessRuleWithBucket(bucketName string, prefix string) (*http.Respons
}
func TestAccessRule(t *testing.T) {
// Variables
assert := assert.New(t)
bucketName := "test-access-rule-bucket"
@@ -3637,10 +3585,9 @@ func TestAccessRule(t *testing.T) {
} else {
assert.Fail("Access Rule not deleted")
}
}
func GetBucketRewind(bucketName string, date string) (*http.Response, error) {
func GetBucketRewind(bucketName, date string) (*http.Response, error) {
/*
Helper function to get objects in a bucket for a rewind date
HTTP Verb: GET
@@ -3664,7 +3611,6 @@ func GetBucketRewind(bucketName string, date string) (*http.Response, error) {
}
func TestGetBucketRewind(t *testing.T) {
// Variables
assert := assert.New(t)
bucketName := "test-get-bucket-rewind"
@@ -3681,5 +3627,4 @@ func TestGetBucketRewind(t *testing.T) {
assert.Equal(
200, resp.StatusCode, inspectHTTPResponse(resp))
}
}

View File

@@ -18,6 +18,7 @@ package integration
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"io"
@@ -31,7 +32,7 @@ import (
"github.com/stretchr/testify/assert"
)
func AddUser(accessKey string, secretKey string, groups []string, policies []string) (*http.Response, error) {
func AddUser(accessKey, secretKey string, groups, policies []string) (*http.Response, error) {
/*
This is an atomic function to add user and can be reused across
different functions.
@@ -62,6 +63,7 @@ func AddUser(accessKey string, secretKey string, groups []string, policies []str
}
func DeleteUser(userName string) (*http.Response, error) {
userName = base64.StdEncoding.EncodeToString([]byte(userName))
/*
This is an atomic function to delete user and can be reused across
different functions.
@@ -70,7 +72,7 @@ func DeleteUser(userName string) (*http.Response, error) {
Timeout: 3 * time.Second,
}
request, err := http.NewRequest(
"DELETE", "http://localhost:9090/api/v1/user?name="+userName, nil)
"DELETE", "http://localhost:9090/api/v1/user/"+userName, nil)
if err != nil {
log.Println(err)
}
@@ -80,7 +82,7 @@ func DeleteUser(userName string) (*http.Response, error) {
return response, err
}
func ListUsers(offset string, limit string) (*http.Response, error) {
func ListUsers(offset, limit string) (*http.Response, error) {
/*
This is an atomic function to list users.
{{baseUrl}}/users?offset=-5480083&limit=-5480083
@@ -102,6 +104,7 @@ func ListUsers(offset string, limit string) (*http.Response, error) {
}
func GetUserInformation(userName string) (*http.Response, error) {
userName = base64.StdEncoding.EncodeToString([]byte(userName))
/*
Helper function to get user information via API:
{{baseUrl}}/user?name=proident velit
@@ -111,7 +114,7 @@ func GetUserInformation(userName string) (*http.Response, error) {
}
request, err := http.NewRequest(
"GET",
"http://localhost:9090/api/v1/user?name="+userName,
"http://localhost:9090/api/v1/user/"+userName,
nil)
if err != nil {
log.Println(err)
@@ -122,7 +125,8 @@ func GetUserInformation(userName string) (*http.Response, error) {
return response, err
}
func UpdateUserInformation(name string, status string, groups []string) (*http.Response, error) {
func UpdateUserInformation(name, status string, groups []string) (*http.Response, error) {
name = base64.StdEncoding.EncodeToString([]byte(name))
/*
Helper function to update user information:
PUT: {{baseUrl}}/user?name=proident velit
@@ -145,7 +149,7 @@ func UpdateUserInformation(name string, status string, groups []string) (*http.R
requestDataJSON, _ := json.Marshal(requestDataAdd)
requestDataBody := bytes.NewReader(requestDataJSON)
request, err := http.NewRequest(
"PUT", "http://localhost:9090/api/v1/user?name="+name, requestDataBody)
"PUT", "http://localhost:9090/api/v1/user/"+name, requestDataBody)
if err != nil {
log.Println(err)
}
@@ -156,6 +160,7 @@ func UpdateUserInformation(name string, status string, groups []string) (*http.R
}
func RemoveUser(name string) (*http.Response, error) {
name = base64.StdEncoding.EncodeToString([]byte(name))
/*
Helper function to remove user.
DELETE: {{baseUrl}}/user?name=proident velit
@@ -164,7 +169,7 @@ func RemoveUser(name string) (*http.Response, error) {
Timeout: 3 * time.Second,
}
request, err := http.NewRequest(
"DELETE", "http://localhost:9090/api/v1/user?name="+name, nil)
"DELETE", "http://localhost:9090/api/v1/user/"+name, nil)
if err != nil {
log.Println(err)
}
@@ -175,6 +180,7 @@ func RemoveUser(name string) (*http.Response, error) {
}
func UpdateGroupsForAUser(userName string, groups []string) (*http.Response, error) {
userName = base64.StdEncoding.EncodeToString([]byte(userName))
/*
Helper function to update groups for a user
PUT: {{baseUrl}}/user/groups?name=username
@@ -195,7 +201,7 @@ func UpdateGroupsForAUser(userName string, groups []string) (*http.Response, err
requestDataBody := bytes.NewReader(requestDataJSON)
request, err := http.NewRequest(
"PUT",
"http://localhost:9090/api/v1/user/groups?name="+userName,
"http://localhost:9090/api/v1/user/"+userName+"/groups",
requestDataBody,
)
if err != nil {
@@ -207,7 +213,8 @@ func UpdateGroupsForAUser(userName string, groups []string) (*http.Response, err
return response, err
}
func CreateServiceAccountForUser(userName string, policy string) (*http.Response, error) {
func CreateServiceAccountForUser(userName, policy string) (*http.Response, error) {
userName = base64.StdEncoding.EncodeToString([]byte(userName))
/*
Helper function to Create Service Account for user
POST: api/v1/user/username/service-accounts
@@ -237,7 +244,8 @@ func CreateServiceAccountForUser(userName string, policy string) (*http.Response
return response, err
}
func CreateServiceAccountForUserWithCredentials(userName string, policy string, accessKey string, secretKey string) (*http.Response, error) {
func CreateServiceAccountForUserWithCredentials(userName, policy, accessKey, secretKey string) (*http.Response, error) {
userName = base64.StdEncoding.EncodeToString([]byte(userName))
// Helper function to test "Create Service Account for User With Credentials" end point.
client := &http.Client{
Timeout: 3 * time.Second,
@@ -264,6 +272,7 @@ func CreateServiceAccountForUserWithCredentials(userName string, policy string,
}
func ReturnsAListOfServiceAccountsForAUser(userName string) (*http.Response, error) {
userName = base64.StdEncoding.EncodeToString([]byte(userName))
/*
Helper function to return a list of service accounts for a user.
GET: {{baseUrl}}/user/:name/service-accounts
@@ -312,7 +321,7 @@ func AddGroup(group string, members []string) (*http.Response, error) {
return response, err
}
func UsersGroupsBulk(users []string, groups []string) (*http.Response, error) {
func UsersGroupsBulk(users, groups []string) (*http.Response, error) {
/*
Helper function to test Bulk functionality to Add Users to Groups.
PUT: {{baseUrl}}/users-groups-bulk
@@ -363,8 +372,8 @@ func TestAddUser(t *testing.T) {
assert := assert.New(t)
// With no groups & no policies
var groups = []string{}
var policies = []string{}
groups := []string{}
policies := []string{}
response, err := AddUser("accessKey", "secretKey", groups, policies)
if err != nil {
log.Println(err)
@@ -384,7 +393,6 @@ func TestAddUser(t *testing.T) {
fmt.Println("DELETE StatusCode:", response.StatusCode)
assert.Equal(204, response.StatusCode, "has to be 204 when delete user")
}
}
func TestListUsers(t *testing.T) {
@@ -398,8 +406,8 @@ func TestListUsers(t *testing.T) {
assert := assert.New(t)
// With no groups & no policies
var groups = []string{}
var policies = []string{}
groups := []string{}
policies := []string{}
// 1. Create the users
numberOfUsers := 5
@@ -454,7 +462,6 @@ func TestListUsers(t *testing.T) {
response.StatusCode, "has to be 204 when delete user")
}
}
}
func TestGetUserInfo(t *testing.T) {
@@ -465,8 +472,8 @@ func TestGetUserInfo(t *testing.T) {
// 1. Create the user
fmt.Println("TestGetUserInfo(): 1. Create the user")
assert := assert.New(t)
var groups = []string{}
var policies = []string{}
groups := []string{}
policies := []string{}
response, err := AddUser("accessKey", "secretKey", groups, policies)
if err != nil {
log.Println(err)
@@ -500,7 +507,6 @@ func TestGetUserInfo(t *testing.T) {
expected := "{\"accessKey\":\"accessKey\",\"memberOf\":null,\"policy\":[],\"status\":\"enabled\"}\n"
obtained := string(b)
assert.Equal(expected, obtained, "User Information is wrong")
}
func TestUpdateUserInfoSuccessfulResponse(t *testing.T) {
@@ -511,8 +517,8 @@ func TestUpdateUserInfoSuccessfulResponse(t *testing.T) {
assert := assert.New(t)
// 1. Create an active user
var groups = []string{}
var policies = []string{}
groups := []string{}
policies := []string{}
addUserResponse, addUserError := AddUser(
"updateuser", "secretKey", groups, policies)
if addUserError != nil {
@@ -545,7 +551,6 @@ func TestUpdateUserInfoSuccessfulResponse(t *testing.T) {
log.Fatalln(err)
}
assert.True(strings.Contains(string(b), "disabled"))
}
func TestUpdateUserInfoGenericErrorResponse(t *testing.T) {
@@ -556,8 +561,8 @@ func TestUpdateUserInfoGenericErrorResponse(t *testing.T) {
assert := assert.New(t)
// 1. Create an active user
var groups = []string{}
var policies = []string{}
groups := []string{}
policies := []string{}
addUserResponse, addUserError := AddUser(
"updateusererror", "secretKey", groups, policies)
if addUserError != nil {
@@ -590,7 +595,6 @@ func TestUpdateUserInfoGenericErrorResponse(t *testing.T) {
log.Fatalln(err)
}
assert.True(strings.Contains(string(b), "status not valid"))
}
func TestRemoveUserSuccessfulResponse(t *testing.T) {
@@ -601,8 +605,8 @@ func TestRemoveUserSuccessfulResponse(t *testing.T) {
assert := assert.New(t)
// 1. Create an active user
var groups = []string{}
var policies = []string{}
groups := []string{}
policies := []string{}
addUserResponse, addUserError := AddUser(
"testremoveuser1", "secretKey", groups, policies)
if addUserError != nil {
@@ -644,7 +648,6 @@ func TestRemoveUserSuccessfulResponse(t *testing.T) {
fmt.Println(finalResponse)
assert.True(strings.Contains(
finalResponse, "The specified user does not exist"), finalResponse)
}
func TestUpdateGroupsForAUser(t *testing.T) {
@@ -657,8 +660,8 @@ func TestUpdateGroupsForAUser(t *testing.T) {
groupName := "updategroupforausergroup"
userName := "updategroupsforauser1"
assert := assert.New(t)
var groups = []string{}
var policies = []string{}
groups := []string{}
policies := []string{}
response, err := AddUser(userName, "secretKey", groups, policies)
if err != nil {
log.Println(err)
@@ -670,7 +673,7 @@ func TestUpdateGroupsForAUser(t *testing.T) {
}
// 2. Update the groups of the created user with newGroups
var newGroups = make([]string, 3)
newGroups := make([]string, 3)
for i := 0; i < numberOfGroups; i++ {
newGroups[i] = groupName + strconv.Itoa(i)
}
@@ -701,7 +704,6 @@ func TestUpdateGroupsForAUser(t *testing.T) {
assert.True(strings.Contains(
finalResponse, groupName+strconv.Itoa(i)), finalResponse)
}
}
func TestCreateServiceAccountForUser(t *testing.T) {
@@ -716,8 +718,8 @@ func TestCreateServiceAccountForUser(t *testing.T) {
serviceAccountLengthInBytes := 40 // As observed, update as needed
// 1. Create the user
var groups = []string{}
var policies = []string{}
groups := []string{}
policies := []string{}
response, err := AddUser(userName, "secretKey", groups, policies)
if err != nil {
log.Println(err)
@@ -747,8 +749,10 @@ func TestCreateServiceAccountForUser(t *testing.T) {
}
// 3. Verify the service account for the user
listOfAccountsResponse,
listOfAccountsError := ReturnsAListOfServiceAccountsForAUser(userName)
listOfAccountsResponse, listOfAccountsError := ReturnsAListOfServiceAccountsForAUser(userName)
fmt.Println(listOfAccountsResponse, listOfAccountsError)
if listOfAccountsError != nil {
log.Println(listOfAccountsError)
assert.Fail("Error in listOfAccountsError")
@@ -761,8 +765,8 @@ func TestCreateServiceAccountForUser(t *testing.T) {
finalResponse,
)
}
assert.Equal(len(finalResponse), serviceAccountLengthInBytes, finalResponse)
assert.Equal(len(finalResponse), serviceAccountLengthInBytes, finalResponse)
}
func TestUsersGroupsBulk(t *testing.T) {
@@ -774,11 +778,11 @@ func TestUsersGroupsBulk(t *testing.T) {
assert := assert.New(t)
numberOfUsers := 5
numberOfGroups := 1
//var groups = []string{}
var policies = []string{}
// var groups = []string{}
policies := []string{}
username := "testusersgroupbulk"
groupName := "testusersgroupsbulkgroupone"
var members = []string{}
members := []string{}
users := make([]string, numberOfUsers)
groups := make([]string, numberOfGroups)
@@ -850,7 +854,69 @@ func TestUsersGroupsBulk(t *testing.T) {
assert.Equal(200, responseGetUserInfo.StatusCode, finalResponse)
}
// Make sure the user belongs to the created group
assert.True(strings.Contains(string(finalResponse), groupName))
assert.True(strings.Contains(finalResponse, groupName))
}
}
func Test_GetUserPolicyAPI(t *testing.T) {
assert := assert.New(t)
// 1. Create an active user with valid policy
groups := []string{}
policies := []string{"readwrite"}
addUserResponse, addUserError := AddUser(
"getpolicyuser", "secretKey", groups, policies)
if addUserError != nil {
log.Println(addUserError)
return
}
if addUserResponse != nil {
fmt.Println("StatusCode:", addUserResponse.StatusCode)
assert.Equal(
201, addUserResponse.StatusCode, "Status Code is incorrect")
}
type args struct {
api string
}
tests := []struct {
name string
args args
expectedStatus int
expectedError error
}{
{
name: "Get User Policies",
args: args{
api: "/user/policy",
},
expectedStatus: 200,
expectedError: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &http.Client{
Timeout: 3 * time.Second,
}
request, err := http.NewRequest(
"GET", fmt.Sprintf("http://localhost:9090/api/v1%s", tt.args.api), nil)
if err != nil {
log.Println(err)
return
}
request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
request.Header.Add("Content-Type", "application/json")
response, err := client.Do(request)
if err != nil {
log.Println(err)
return
}
if response != nil {
assert.Equal(tt.expectedStatus, response.StatusCode, tt.name+" Failed")
}
})
}
}

View File

@@ -68,8 +68,6 @@ func Test_VersionAPI(t *testing.T) {
if response != nil {
assert.Equal(tt.expectedStatus, response.StatusCode, "Status Code is incorrect")
}
})
}
}

View File

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

View File

@@ -32,7 +32,7 @@ spec:
spec:
containers:
- name: console
image: 'minio/console:v0.16.0'
image: 'minio/console:v0.17.0'
imagePullPolicy: "IfNotPresent"
env:
- name: CONSOLE_MINIO_SERVER

70
models/condition.go Normal file
View File

@@ -0,0 +1,70 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// Condition condition
//
// swagger:model condition
type Condition struct {
// status
Status string `json:"status,omitempty"`
// type
Type string `json:"type,omitempty"`
}
// Validate validates this condition
func (m *Condition) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this condition based on context it is used
func (m *Condition) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *Condition) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *Condition) UnmarshalBinary(b []byte) error {
var res Condition
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

70
models/config_map.go Normal file
View File

@@ -0,0 +1,70 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// ConfigMap config map
//
// swagger:model configMap
type ConfigMap struct {
// name
Name string `json:"name,omitempty"`
// optional
Optional bool `json:"optional,omitempty"`
}
// Validate validates this config map
func (m *ConfigMap) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this config map based on context it is used
func (m *ConfigMap) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *ConfigMap) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *ConfigMap) UnmarshalBinary(b []byte) error {
var res ConfigMap
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

309
models/container.go Normal file
View File

@@ -0,0 +1,309 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 (
"context"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// Container container
//
// swagger:model container
type Container struct {
// args
Args []string `json:"args"`
// container ID
ContainerID string `json:"containerID,omitempty"`
// environment variables
EnvironmentVariables []*EnvironmentVariable `json:"environmentVariables"`
// host ports
HostPorts []string `json:"hostPorts"`
// image
Image string `json:"image,omitempty"`
// image ID
ImageID string `json:"imageID,omitempty"`
// last state
LastState *State `json:"lastState,omitempty"`
// mounts
Mounts []*Mount `json:"mounts"`
// name
Name string `json:"name,omitempty"`
// ports
Ports []string `json:"ports"`
// ready
Ready bool `json:"ready,omitempty"`
// restart count
RestartCount int64 `json:"restartCount,omitempty"`
// state
State *State `json:"state,omitempty"`
}
// Validate validates this container
func (m *Container) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateEnvironmentVariables(formats); err != nil {
res = append(res, err)
}
if err := m.validateLastState(formats); err != nil {
res = append(res, err)
}
if err := m.validateMounts(formats); err != nil {
res = append(res, err)
}
if err := m.validateState(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *Container) validateEnvironmentVariables(formats strfmt.Registry) error {
if swag.IsZero(m.EnvironmentVariables) { // not required
return nil
}
for i := 0; i < len(m.EnvironmentVariables); i++ {
if swag.IsZero(m.EnvironmentVariables[i]) { // not required
continue
}
if m.EnvironmentVariables[i] != nil {
if err := m.EnvironmentVariables[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("environmentVariables" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("environmentVariables" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *Container) validateLastState(formats strfmt.Registry) error {
if swag.IsZero(m.LastState) { // not required
return nil
}
if m.LastState != nil {
if err := m.LastState.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("lastState")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("lastState")
}
return err
}
}
return nil
}
func (m *Container) validateMounts(formats strfmt.Registry) error {
if swag.IsZero(m.Mounts) { // not required
return nil
}
for i := 0; i < len(m.Mounts); i++ {
if swag.IsZero(m.Mounts[i]) { // not required
continue
}
if m.Mounts[i] != nil {
if err := m.Mounts[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("mounts" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("mounts" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *Container) validateState(formats strfmt.Registry) error {
if swag.IsZero(m.State) { // not required
return nil
}
if m.State != nil {
if err := m.State.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("state")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("state")
}
return err
}
}
return nil
}
// ContextValidate validate this container based on the context it is used
func (m *Container) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateEnvironmentVariables(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateLastState(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateMounts(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateState(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *Container) contextValidateEnvironmentVariables(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.EnvironmentVariables); i++ {
if m.EnvironmentVariables[i] != nil {
if err := m.EnvironmentVariables[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("environmentVariables" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("environmentVariables" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *Container) contextValidateLastState(ctx context.Context, formats strfmt.Registry) error {
if m.LastState != nil {
if err := m.LastState.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("lastState")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("lastState")
}
return err
}
}
return nil
}
func (m *Container) contextValidateMounts(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Mounts); i++ {
if m.Mounts[i] != nil {
if err := m.Mounts[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("mounts" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("mounts" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *Container) contextValidateState(ctx context.Context, formats strfmt.Registry) error {
if m.State != nil {
if err := m.State.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("state")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("state")
}
return err
}
}
return nil
}
// MarshalBinary interface implementation
func (m *Container) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *Container) UnmarshalBinary(b []byte) error {
var res Container
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

154
models/csr_element.go Normal file
View File

@@ -0,0 +1,154 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 (
"context"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// CsrElement csr element
//
// swagger:model csrElement
type CsrElement struct {
// annotations
Annotations []*Annotation `json:"annotations"`
// deletion grace period seconds
DeletionGracePeriodSeconds int64 `json:"deletion_grace_period_seconds,omitempty"`
// generate name
GenerateName string `json:"generate_name,omitempty"`
// generation
Generation int64 `json:"generation,omitempty"`
// name
Name string `json:"name,omitempty"`
// namespace
Namespace string `json:"namespace,omitempty"`
// resource version
ResourceVersion string `json:"resource_version,omitempty"`
// status
Status string `json:"status,omitempty"`
}
// Validate validates this csr element
func (m *CsrElement) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateAnnotations(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *CsrElement) validateAnnotations(formats strfmt.Registry) error {
if swag.IsZero(m.Annotations) { // not required
return nil
}
for i := 0; i < len(m.Annotations); i++ {
if swag.IsZero(m.Annotations[i]) { // not required
continue
}
if m.Annotations[i] != nil {
if err := m.Annotations[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("annotations" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("annotations" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// ContextValidate validate this csr element based on the context it is used
func (m *CsrElement) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateAnnotations(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *CsrElement) contextValidateAnnotations(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Annotations); i++ {
if m.Annotations[i] != nil {
if err := m.Annotations[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("annotations" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("annotations" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// MarshalBinary interface implementation
func (m *CsrElement) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *CsrElement) UnmarshalBinary(b []byte) error {
var res CsrElement
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -0,0 +1,217 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 (
"context"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// DescribePVCWrapper describe p v c wrapper
//
// swagger:model describePVCWrapper
type DescribePVCWrapper struct {
// access modes
AccessModes []string `json:"accessModes"`
// annotations
Annotations []*Annotation `json:"annotations"`
// capacity
Capacity string `json:"capacity,omitempty"`
// finalizers
Finalizers []string `json:"finalizers"`
// labels
Labels []*Label `json:"labels"`
// name
Name string `json:"name,omitempty"`
// namespace
Namespace string `json:"namespace,omitempty"`
// status
Status string `json:"status,omitempty"`
// storage class
StorageClass string `json:"storageClass,omitempty"`
// volume
Volume string `json:"volume,omitempty"`
// volume mode
VolumeMode string `json:"volumeMode,omitempty"`
}
// Validate validates this describe p v c wrapper
func (m *DescribePVCWrapper) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateAnnotations(formats); err != nil {
res = append(res, err)
}
if err := m.validateLabels(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *DescribePVCWrapper) validateAnnotations(formats strfmt.Registry) error {
if swag.IsZero(m.Annotations) { // not required
return nil
}
for i := 0; i < len(m.Annotations); i++ {
if swag.IsZero(m.Annotations[i]) { // not required
continue
}
if m.Annotations[i] != nil {
if err := m.Annotations[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("annotations" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("annotations" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *DescribePVCWrapper) validateLabels(formats strfmt.Registry) error {
if swag.IsZero(m.Labels) { // not required
return nil
}
for i := 0; i < len(m.Labels); i++ {
if swag.IsZero(m.Labels[i]) { // not required
continue
}
if m.Labels[i] != nil {
if err := m.Labels[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("labels" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("labels" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// ContextValidate validate this describe p v c wrapper based on the context it is used
func (m *DescribePVCWrapper) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateAnnotations(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateLabels(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *DescribePVCWrapper) contextValidateAnnotations(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Annotations); i++ {
if m.Annotations[i] != nil {
if err := m.Annotations[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("annotations" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("annotations" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *DescribePVCWrapper) contextValidateLabels(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Labels); i++ {
if m.Labels[i] != nil {
if err := m.Labels[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("labels" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("labels" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// MarshalBinary interface implementation
func (m *DescribePVCWrapper) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *DescribePVCWrapper) UnmarshalBinary(b []byte) error {
var res DescribePVCWrapper
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -0,0 +1,517 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 (
"context"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// DescribePodWrapper describe pod wrapper
//
// swagger:model describePodWrapper
type DescribePodWrapper struct {
// annotations
Annotations []*Annotation `json:"annotations"`
// conditions
Conditions []*Condition `json:"conditions"`
// containers
Containers []*Container `json:"containers"`
// controller ref
ControllerRef string `json:"controllerRef,omitempty"`
// deletion grace period seconds
DeletionGracePeriodSeconds int64 `json:"deletionGracePeriodSeconds,omitempty"`
// deletion timestamp
DeletionTimestamp string `json:"deletionTimestamp,omitempty"`
// labels
Labels []*Label `json:"labels"`
// message
Message string `json:"message,omitempty"`
// name
Name string `json:"name,omitempty"`
// namespace
Namespace string `json:"namespace,omitempty"`
// node name
NodeName string `json:"nodeName,omitempty"`
// node selector
NodeSelector []*NodeSelector `json:"nodeSelector"`
// phase
Phase string `json:"phase,omitempty"`
// pod IP
PodIP string `json:"podIP,omitempty"`
// priority
Priority int64 `json:"priority,omitempty"`
// priority class name
PriorityClassName string `json:"priorityClassName,omitempty"`
// qos class
QosClass string `json:"qosClass,omitempty"`
// reason
Reason string `json:"reason,omitempty"`
// start time
StartTime string `json:"startTime,omitempty"`
// tolerations
Tolerations []*Toleration `json:"tolerations"`
// volumes
Volumes []*Volume `json:"volumes"`
}
// Validate validates this describe pod wrapper
func (m *DescribePodWrapper) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateAnnotations(formats); err != nil {
res = append(res, err)
}
if err := m.validateConditions(formats); err != nil {
res = append(res, err)
}
if err := m.validateContainers(formats); err != nil {
res = append(res, err)
}
if err := m.validateLabels(formats); err != nil {
res = append(res, err)
}
if err := m.validateNodeSelector(formats); err != nil {
res = append(res, err)
}
if err := m.validateTolerations(formats); err != nil {
res = append(res, err)
}
if err := m.validateVolumes(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *DescribePodWrapper) validateAnnotations(formats strfmt.Registry) error {
if swag.IsZero(m.Annotations) { // not required
return nil
}
for i := 0; i < len(m.Annotations); i++ {
if swag.IsZero(m.Annotations[i]) { // not required
continue
}
if m.Annotations[i] != nil {
if err := m.Annotations[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("annotations" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("annotations" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *DescribePodWrapper) validateConditions(formats strfmt.Registry) error {
if swag.IsZero(m.Conditions) { // not required
return nil
}
for i := 0; i < len(m.Conditions); i++ {
if swag.IsZero(m.Conditions[i]) { // not required
continue
}
if m.Conditions[i] != nil {
if err := m.Conditions[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("conditions" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("conditions" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *DescribePodWrapper) validateContainers(formats strfmt.Registry) error {
if swag.IsZero(m.Containers) { // not required
return nil
}
for i := 0; i < len(m.Containers); i++ {
if swag.IsZero(m.Containers[i]) { // not required
continue
}
if m.Containers[i] != nil {
if err := m.Containers[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("containers" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("containers" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *DescribePodWrapper) validateLabels(formats strfmt.Registry) error {
if swag.IsZero(m.Labels) { // not required
return nil
}
for i := 0; i < len(m.Labels); i++ {
if swag.IsZero(m.Labels[i]) { // not required
continue
}
if m.Labels[i] != nil {
if err := m.Labels[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("labels" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("labels" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *DescribePodWrapper) validateNodeSelector(formats strfmt.Registry) error {
if swag.IsZero(m.NodeSelector) { // not required
return nil
}
for i := 0; i < len(m.NodeSelector); i++ {
if swag.IsZero(m.NodeSelector[i]) { // not required
continue
}
if m.NodeSelector[i] != nil {
if err := m.NodeSelector[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("nodeSelector" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("nodeSelector" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *DescribePodWrapper) validateTolerations(formats strfmt.Registry) error {
if swag.IsZero(m.Tolerations) { // not required
return nil
}
for i := 0; i < len(m.Tolerations); i++ {
if swag.IsZero(m.Tolerations[i]) { // not required
continue
}
if m.Tolerations[i] != nil {
if err := m.Tolerations[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("tolerations" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("tolerations" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *DescribePodWrapper) validateVolumes(formats strfmt.Registry) error {
if swag.IsZero(m.Volumes) { // not required
return nil
}
for i := 0; i < len(m.Volumes); i++ {
if swag.IsZero(m.Volumes[i]) { // not required
continue
}
if m.Volumes[i] != nil {
if err := m.Volumes[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("volumes" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("volumes" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// ContextValidate validate this describe pod wrapper based on the context it is used
func (m *DescribePodWrapper) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateAnnotations(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateConditions(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateContainers(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateLabels(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateNodeSelector(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateTolerations(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateVolumes(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *DescribePodWrapper) contextValidateAnnotations(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Annotations); i++ {
if m.Annotations[i] != nil {
if err := m.Annotations[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("annotations" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("annotations" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *DescribePodWrapper) contextValidateConditions(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Conditions); i++ {
if m.Conditions[i] != nil {
if err := m.Conditions[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("conditions" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("conditions" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *DescribePodWrapper) contextValidateContainers(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Containers); i++ {
if m.Containers[i] != nil {
if err := m.Containers[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("containers" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("containers" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *DescribePodWrapper) contextValidateLabels(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Labels); i++ {
if m.Labels[i] != nil {
if err := m.Labels[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("labels" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("labels" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *DescribePodWrapper) contextValidateNodeSelector(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.NodeSelector); i++ {
if m.NodeSelector[i] != nil {
if err := m.NodeSelector[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("nodeSelector" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("nodeSelector" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *DescribePodWrapper) contextValidateTolerations(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Tolerations); i++ {
if m.Tolerations[i] != nil {
if err := m.Tolerations[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("tolerations" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("tolerations" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *DescribePodWrapper) contextValidateVolumes(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Volumes); i++ {
if m.Volumes[i] != nil {
if err := m.Volumes[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("volumes" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("volumes" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// MarshalBinary interface implementation
func (m *DescribePodWrapper) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *DescribePodWrapper) UnmarshalBinary(b []byte) error {
var res DescribePodWrapper
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -0,0 +1,70 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// EnvironmentVariable environment variable
//
// swagger:model environmentVariable
type EnvironmentVariable struct {
// key
Key string `json:"key,omitempty"`
// value
Value string `json:"value,omitempty"`
}
// Validate validates this environment variable
func (m *EnvironmentVariable) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this environment variable based on context it is used
func (m *EnvironmentVariable) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *EnvironmentVariable) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *EnvironmentVariable) UnmarshalBinary(b []byte) error {
var res EnvironmentVariable
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

76
models/mount.go Normal file
View File

@@ -0,0 +1,76 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// Mount mount
//
// swagger:model mount
type Mount struct {
// mount path
MountPath string `json:"mountPath,omitempty"`
// name
Name string `json:"name,omitempty"`
// read only
ReadOnly bool `json:"readOnly,omitempty"`
// sub path
SubPath string `json:"subPath,omitempty"`
}
// Validate validates this mount
func (m *Mount) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this mount based on context it is used
func (m *Mount) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *Mount) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *Mount) UnmarshalBinary(b []byte) error {
var res Mount
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -0,0 +1,73 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// PermissionResource permission resource
//
// swagger:model permissionResource
type PermissionResource struct {
// condition operator
ConditionOperator string `json:"conditionOperator,omitempty"`
// prefixes
Prefixes []string `json:"prefixes"`
// resource
Resource string `json:"resource,omitempty"`
}
// Validate validates this permission resource
func (m *PermissionResource) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this permission resource based on context it is used
func (m *PermissionResource) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *PermissionResource) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *PermissionResource) UnmarshalBinary(b []byte) error {
var res PermissionResource
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

133
models/projected_volume.go Normal file
View File

@@ -0,0 +1,133 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 (
"context"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// ProjectedVolume projected volume
//
// swagger:model projectedVolume
type ProjectedVolume struct {
// sources
Sources []*ProjectedVolumeSource `json:"sources"`
}
// Validate validates this projected volume
func (m *ProjectedVolume) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateSources(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *ProjectedVolume) validateSources(formats strfmt.Registry) error {
if swag.IsZero(m.Sources) { // not required
return nil
}
for i := 0; i < len(m.Sources); i++ {
if swag.IsZero(m.Sources[i]) { // not required
continue
}
if m.Sources[i] != nil {
if err := m.Sources[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("sources" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("sources" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// ContextValidate validate this projected volume based on the context it is used
func (m *ProjectedVolume) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateSources(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *ProjectedVolume) contextValidateSources(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Sources); i++ {
if m.Sources[i] != nil {
if err := m.Sources[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("sources" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("sources" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// MarshalBinary interface implementation
func (m *ProjectedVolume) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *ProjectedVolume) UnmarshalBinary(b []byte) error {
var res ProjectedVolume
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -0,0 +1,216 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// ProjectedVolumeSource projected volume source
//
// swagger:model projectedVolumeSource
type ProjectedVolumeSource struct {
// config map
ConfigMap *ConfigMap `json:"configMap,omitempty"`
// downward Api
DownwardAPI bool `json:"downwardApi,omitempty"`
// secret
Secret *Secret `json:"secret,omitempty"`
// service account token
ServiceAccountToken *ServiceAccountToken `json:"serviceAccountToken,omitempty"`
}
// Validate validates this projected volume source
func (m *ProjectedVolumeSource) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateConfigMap(formats); err != nil {
res = append(res, err)
}
if err := m.validateSecret(formats); err != nil {
res = append(res, err)
}
if err := m.validateServiceAccountToken(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *ProjectedVolumeSource) validateConfigMap(formats strfmt.Registry) error {
if swag.IsZero(m.ConfigMap) { // not required
return nil
}
if m.ConfigMap != nil {
if err := m.ConfigMap.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("configMap")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("configMap")
}
return err
}
}
return nil
}
func (m *ProjectedVolumeSource) validateSecret(formats strfmt.Registry) error {
if swag.IsZero(m.Secret) { // not required
return nil
}
if m.Secret != nil {
if err := m.Secret.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("secret")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("secret")
}
return err
}
}
return nil
}
func (m *ProjectedVolumeSource) validateServiceAccountToken(formats strfmt.Registry) error {
if swag.IsZero(m.ServiceAccountToken) { // not required
return nil
}
if m.ServiceAccountToken != nil {
if err := m.ServiceAccountToken.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("serviceAccountToken")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("serviceAccountToken")
}
return err
}
}
return nil
}
// ContextValidate validate this projected volume source based on the context it is used
func (m *ProjectedVolumeSource) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateConfigMap(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateSecret(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateServiceAccountToken(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *ProjectedVolumeSource) contextValidateConfigMap(ctx context.Context, formats strfmt.Registry) error {
if m.ConfigMap != nil {
if err := m.ConfigMap.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("configMap")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("configMap")
}
return err
}
}
return nil
}
func (m *ProjectedVolumeSource) contextValidateSecret(ctx context.Context, formats strfmt.Registry) error {
if m.Secret != nil {
if err := m.Secret.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("secret")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("secret")
}
return err
}
}
return nil
}
func (m *ProjectedVolumeSource) contextValidateServiceAccountToken(ctx context.Context, formats strfmt.Registry) error {
if m.ServiceAccountToken != nil {
if err := m.ServiceAccountToken.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("serviceAccountToken")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("serviceAccountToken")
}
return err
}
}
return nil
}
// MarshalBinary interface implementation
func (m *ProjectedVolumeSource) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *ProjectedVolumeSource) UnmarshalBinary(b []byte) error {
var res ProjectedVolumeSource
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

70
models/pvc.go Normal file
View File

@@ -0,0 +1,70 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// Pvc pvc
//
// swagger:model pvc
type Pvc struct {
// claim name
ClaimName string `json:"claimName,omitempty"`
// read only
ReadOnly bool `json:"readOnly,omitempty"`
}
// Validate validates this pvc
func (m *Pvc) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this pvc based on context it is used
func (m *Pvc) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *Pvc) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *Pvc) UnmarshalBinary(b []byte) error {
var res Pvc
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

70
models/secret.go Normal file
View File

@@ -0,0 +1,70 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// Secret secret
//
// swagger:model secret
type Secret struct {
// name
Name string `json:"name,omitempty"`
// optional
Optional bool `json:"optional,omitempty"`
}
// Validate validates this secret
func (m *Secret) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this secret based on context it is used
func (m *Secret) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *Secret) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *Secret) UnmarshalBinary(b []byte) error {
var res Secret
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -0,0 +1,67 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// ServiceAccountToken service account token
//
// swagger:model serviceAccountToken
type ServiceAccountToken struct {
// expiration seconds
ExpirationSeconds int64 `json:"expirationSeconds,omitempty"`
}
// Validate validates this service account token
func (m *ServiceAccountToken) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this service account token based on context it is used
func (m *ServiceAccountToken) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *ServiceAccountToken) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *ServiceAccountToken) UnmarshalBinary(b []byte) error {
var res ServiceAccountToken
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -25,6 +25,7 @@ package models
import (
"context"
"encoding/json"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
@@ -37,6 +38,9 @@ import (
// swagger:model sessionResponse
type SessionResponse struct {
// allow resources
AllowResources []*PermissionResource `json:"allowResources"`
// distributed mode
DistributedMode bool `json:"distributedMode,omitempty"`
@@ -58,6 +62,10 @@ type SessionResponse struct {
func (m *SessionResponse) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateAllowResources(formats); err != nil {
res = append(res, err)
}
if err := m.validateStatus(formats); err != nil {
res = append(res, err)
}
@@ -68,6 +76,32 @@ func (m *SessionResponse) Validate(formats strfmt.Registry) error {
return nil
}
func (m *SessionResponse) validateAllowResources(formats strfmt.Registry) error {
if swag.IsZero(m.AllowResources) { // not required
return nil
}
for i := 0; i < len(m.AllowResources); i++ {
if swag.IsZero(m.AllowResources[i]) { // not required
continue
}
if m.AllowResources[i] != nil {
if err := m.AllowResources[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("allowResources" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("allowResources" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
var sessionResponseTypeStatusPropEnum []interface{}
func init() {
@@ -107,8 +141,37 @@ func (m *SessionResponse) validateStatus(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this session response based on context it is used
// ContextValidate validate this session response based on the context it is used
func (m *SessionResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateAllowResources(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *SessionResponse) contextValidateAllowResources(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.AllowResources); i++ {
if m.AllowResources[i] != nil {
if err := m.AllowResources[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("allowResources" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("allowResources" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}

85
models/state.go Normal file
View File

@@ -0,0 +1,85 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// State state
//
// swagger:model state
type State struct {
// exit code
ExitCode int64 `json:"exitCode,omitempty"`
// finished
Finished string `json:"finished,omitempty"`
// message
Message string `json:"message,omitempty"`
// reason
Reason string `json:"reason,omitempty"`
// signal
Signal int64 `json:"signal,omitempty"`
// started
Started string `json:"started,omitempty"`
// state
State string `json:"state,omitempty"`
}
// Validate validates this state
func (m *State) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this state based on context it is used
func (m *State) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *State) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *State) UnmarshalBinary(b []byte) error {
var res State
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

79
models/toleration.go Normal file
View File

@@ -0,0 +1,79 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// Toleration toleration
//
// swagger:model toleration
type Toleration struct {
// effect
Effect string `json:"effect,omitempty"`
// key
Key string `json:"key,omitempty"`
// operator
Operator string `json:"operator,omitempty"`
// toleration seconds
TolerationSeconds int64 `json:"tolerationSeconds,omitempty"`
// value
Value string `json:"value,omitempty"`
}
// Validate validates this toleration
func (m *Toleration) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this toleration based on context it is used
func (m *Toleration) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *Toleration) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *Toleration) UnmarshalBinary(b []byte) error {
var res Toleration
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

170
models/volume.go Normal file
View File

@@ -0,0 +1,170 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// Volume volume
//
// swagger:model volume
type Volume struct {
// name
Name string `json:"name,omitempty"`
// projected
Projected *ProjectedVolume `json:"projected,omitempty"`
// pvc
Pvc *Pvc `json:"pvc,omitempty"`
}
// Validate validates this volume
func (m *Volume) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateProjected(formats); err != nil {
res = append(res, err)
}
if err := m.validatePvc(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *Volume) validateProjected(formats strfmt.Registry) error {
if swag.IsZero(m.Projected) { // not required
return nil
}
if m.Projected != nil {
if err := m.Projected.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("projected")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("projected")
}
return err
}
}
return nil
}
func (m *Volume) validatePvc(formats strfmt.Registry) error {
if swag.IsZero(m.Pvc) { // not required
return nil
}
if m.Pvc != nil {
if err := m.Pvc.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("pvc")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("pvc")
}
return err
}
}
return nil
}
// ContextValidate validate this volume based on the context it is used
func (m *Volume) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateProjected(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidatePvc(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *Volume) contextValidateProjected(ctx context.Context, formats strfmt.Registry) error {
if m.Projected != nil {
if err := m.Projected.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("projected")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("projected")
}
return err
}
}
return nil
}
func (m *Volume) contextValidatePvc(ctx context.Context, formats strfmt.Registry) error {
if m.Pvc != nil {
if err := m.Pvc.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("pvc")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("pvc")
}
return err
}
}
return nil
}
// MarshalBinary interface implementation
func (m *Volume) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *Volume) UnmarshalBinary(b []byte) error {
var res Volume
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -88,8 +88,7 @@ func printEndFunc(functionName string) {
}
func initConsoleServer() (*operatorapi.Server, error) {
//os.Setenv("CONSOLE_MINIO_SERVER", "localhost:9000")
// os.Setenv("CONSOLE_MINIO_SERVER", "localhost:9000")
swaggerSpec, err := loads.Embedded(operatorapi.SwaggerJSON, operatorapi.FlatSwaggerJSON)
if err != nil {
@@ -133,7 +132,6 @@ func TestMain(m *testing.M) {
return
}
srv.Serve()
}()
fmt.Println("sleeping")
@@ -200,7 +198,6 @@ func TestMain(m *testing.M) {
request.Header.Add("Content-Type", "application/json")
response, err := client.Do(request)
if err != nil {
log.Println(err)
return
@@ -564,3 +561,86 @@ func TestGetPodEvents(t *testing.T) {
200, resp.StatusCode, "Status Code is incorrect")
}
}
func GetPodDescribe(nameSpace string, tenant string, podName string) (*http.Response, error) {
/*
Helper function to get events for pod
URL: /namespaces/{namespace}/tenants/{tenant}/pods/{podName}/events
HTTP Verb: GET
*/
fmt.Println(nameSpace)
fmt.Println(tenant)
fmt.Println(podName)
request, err := http.NewRequest(
"GET", "http://localhost:9090/api/v1/namespaces/"+nameSpace+"/tenants/"+tenant+"/pods/"+podName+"/describe", nil)
if err != nil {
log.Println(err)
}
request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
request.Header.Add("Content-Type", "application/json")
client := &http.Client{
Timeout: 2 * time.Second,
}
response, err := client.Do(request)
return response, err
}
func TestGetPodDescribe(t *testing.T) {
assert := assert.New(t)
namespace := "tenant-lite"
tenant := "storage-lite"
podName := "storage-lite-pool-0-0"
resp, err := GetPodDescribe(namespace, tenant, podName)
assert.Nil(err)
if err != nil {
log.Println(err)
return
}
finalResponse := inspectHTTPResponse(resp)
if resp != nil {
assert.Equal(
200, resp.StatusCode, finalResponse)
}
/*if resp != nil {
assert.Equal(
200, resp.StatusCode, "Status Code is incorrect")
}*/
}
func GetCSR(nameSpace string, tenant string) (*http.Response, error) {
/*
Helper function to get events for pod
URL: /namespaces/{namespace}/tenants/{tenant}/csr
HTTP Verb: GET
*/
request, err := http.NewRequest(
"GET", "http://localhost:9090/api/v1/namespaces/"+nameSpace+"/tenants/"+tenant+"/csr/", nil)
if err != nil {
log.Println(err)
}
request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
request.Header.Add("Content-Type", "application/json")
client := &http.Client{
Timeout: 2 * time.Second,
}
response, err := client.Do(request)
return response, err
}
func TestGetCSR(t *testing.T) {
assert := assert.New(t)
namespace := "tenant-lite"
tenant := "storage-lite"
resp, err := GetCSR(namespace, tenant)
assert.Nil(err)
if err != nil {
log.Println(err)
return
}
finalResponse := inspectHTTPResponse(resp)
if resp != nil {
assert.Equal(
200, resp.StatusCode, finalResponse)
}
assert.Equal(strings.Contains(finalResponse, "Automatically approved by MinIO Operator"), true)
}

View File

@@ -0,0 +1,88 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 operatorapi
import (
"os"
"testing"
)
func Test_getK8sSAToken(t *testing.T) {
tests := []struct {
name string
want string
envs map[string]string
}{
{
name: "Missing file, empty",
want: "",
envs: nil,
},
{
name: "Missing file, return env",
want: "x",
envs: map[string]string{
ConsoleOperatorSAToken: "x",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.envs != nil {
for k, v := range tt.envs {
os.Setenv(k, v)
}
}
if got := getK8sSAToken(); got != tt.want {
t.Errorf("getK8sSAToken() = %v, want %v", got, tt.want)
}
if tt.envs != nil {
for k := range tt.envs {
os.Unsetenv(k)
}
}
})
}
}
func Test_getMarketplace(t *testing.T) {
tests := []struct {
name string
want string
envs map[string]string
}{
{
name: "Nothing set",
want: "",
envs: nil,
},
{
name: "Value set",
want: "x",
envs: map[string]string{
ConsoleMarketplace: "x",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := getMarketplace(); got != tt.want {
t.Errorf("getMarketplace() = %v, want %v", got, tt.want)
}
})
}
}

View File

@@ -52,7 +52,6 @@ func configureFlags(api *operations.OperatorAPI) {
}
func configureAPI(api *operations.OperatorAPI) http.Handler {
// Applies when the "x-token" header is set
api.KeyAuth = func(token string, scopes []string) (*models.Principal, error) {
// we are validating the session token by decrypting the claims inside, if the operation succeed that means the jwt

File diff suppressed because it is too large Load Diff

View File

@@ -112,7 +112,6 @@ func gkeIntegration(clientset *kubernetes.Clientset, tenantName string, namespac
Name: tenantNpSvc,
},
Spec: corev1.ServiceSpec{
Selector: map[string]string{
"v1.min.io/instance": tenantName,
},
@@ -132,7 +131,7 @@ func gkeIntegration(clientset *kubernetes.Clientset, tenantName string, namespac
return err
}
//NOW FOR Console
// NOW FOR Console
// create consoleManagedCertificate
// get a nodeport port for this tenant and create a nodeport for it

View File

@@ -25,8 +25,10 @@ import (
"github.com/minio/cli"
)
var infoLog = log.New(os.Stdout, "I: ", log.LstdFlags)
var errorLog = log.New(os.Stdout, "E: ", log.LstdFlags)
var (
infoLog = log.New(os.Stdout, "I: ", log.LstdFlags)
errorLog = log.New(os.Stdout, "E: ", log.LstdFlags)
)
func logInfo(msg string, data ...interface{}) {
infoLog.Printf(msg+"\n", data...)

View File

@@ -16,5 +16,7 @@
package operatorapi
type opClientMock struct{}
type httpClientMock struct{}
type (
opClientMock struct{}
httpClientMock struct{}
)

View File

@@ -34,7 +34,7 @@ import (
func registerNamespaceHandlers(api *operations.OperatorAPI) {
// Add Namespace
//api.OperatorAPICreateNamespaceHandler = operator_api.CreateNamespaceHandlerFunc(func(params operator_api.CreateNamespaceParams, session *models.Principal) middleware.Responder {
// api.OperatorAPICreateNamespaceHandler = operator_api.CreateNamespaceHandlerFunc(func(params operator_api.CreateNamespaceParams, session *models.Principal) middleware.Responder {
api.OperatorAPICreateNamespaceHandler = operator_api.CreateNamespaceHandlerFunc(func(params operator_api.CreateNamespaceParams, session *models.Principal) middleware.Responder {
err := getNamespaceCreatedResponse(session, params)
if err != nil {
@@ -48,7 +48,6 @@ func getNamespaceCreatedResponse(session *models.Principal, params operator_api.
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
clientset, err := cluster.K8sClient(session.STSSessionToken)
if err != nil {
return xerrors.ErrorWithContext(ctx, err)
}

View File

@@ -230,7 +230,6 @@ func getNodeLabelsResponse(ctx context.Context, session *models.Principal) (*mod
}
func getClusterResourcesInfo(numNodes int32, inNodesResources []NodeResourceInfo) *models.AllocatableResourcesResponse {
// purge any nodes with 0 cpu
var nodesResources []NodeResourceInfo
for _, n := range inNodesResources {

View File

@@ -82,6 +82,9 @@ func NewOperatorAPI(spec *loads.Document) *OperatorAPI {
OperatorAPIDeleteTenantHandler: operator_api.DeleteTenantHandlerFunc(func(params operator_api.DeleteTenantParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation operator_api.DeleteTenant has not yet been implemented")
}),
OperatorAPIDescribePodHandler: operator_api.DescribePodHandlerFunc(func(params operator_api.DescribePodParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation operator_api.DescribePod has not yet been implemented")
}),
OperatorAPIDisableTenantLoggingHandler: operator_api.DisableTenantLoggingHandlerFunc(func(params operator_api.DisableTenantLoggingParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation operator_api.DisableTenantLogging has not yet been implemented")
}),
@@ -94,6 +97,9 @@ func NewOperatorAPI(spec *loads.Document) *OperatorAPI {
OperatorAPIGetMaxAllocatableMemHandler: operator_api.GetMaxAllocatableMemHandlerFunc(func(params operator_api.GetMaxAllocatableMemParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation operator_api.GetMaxAllocatableMem has not yet been implemented")
}),
OperatorAPIGetPVCDescribeHandler: operator_api.GetPVCDescribeHandlerFunc(func(params operator_api.GetPVCDescribeParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation operator_api.GetPVCDescribe has not yet been implemented")
}),
OperatorAPIGetPVCEventsHandler: operator_api.GetPVCEventsHandlerFunc(func(params operator_api.GetPVCEventsParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation operator_api.GetPVCEvents has not yet been implemented")
}),
@@ -139,6 +145,9 @@ func NewOperatorAPI(spec *loads.Document) *OperatorAPI {
OperatorAPIListPVCsForTenantHandler: operator_api.ListPVCsForTenantHandlerFunc(func(params operator_api.ListPVCsForTenantParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation operator_api.ListPVCsForTenant has not yet been implemented")
}),
OperatorAPIListTenantCertificateSigningRequestHandler: operator_api.ListTenantCertificateSigningRequestHandlerFunc(func(params operator_api.ListTenantCertificateSigningRequestParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation operator_api.ListTenantCertificateSigningRequest has not yet been implemented")
}),
OperatorAPIListTenantsHandler: operator_api.ListTenantsHandlerFunc(func(params operator_api.ListTenantsParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation operator_api.ListTenants has not yet been implemented")
}),
@@ -278,6 +287,8 @@ type OperatorAPI struct {
OperatorAPIDeletePodHandler operator_api.DeletePodHandler
// OperatorAPIDeleteTenantHandler sets the operation handler for the delete tenant operation
OperatorAPIDeleteTenantHandler operator_api.DeleteTenantHandler
// OperatorAPIDescribePodHandler sets the operation handler for the describe pod operation
OperatorAPIDescribePodHandler operator_api.DescribePodHandler
// OperatorAPIDisableTenantLoggingHandler sets the operation handler for the disable tenant logging operation
OperatorAPIDisableTenantLoggingHandler operator_api.DisableTenantLoggingHandler
// OperatorAPIEnableTenantLoggingHandler sets the operation handler for the enable tenant logging operation
@@ -286,6 +297,8 @@ type OperatorAPI struct {
OperatorAPIGetAllocatableResourcesHandler operator_api.GetAllocatableResourcesHandler
// OperatorAPIGetMaxAllocatableMemHandler sets the operation handler for the get max allocatable mem operation
OperatorAPIGetMaxAllocatableMemHandler operator_api.GetMaxAllocatableMemHandler
// OperatorAPIGetPVCDescribeHandler sets the operation handler for the get p v c describe operation
OperatorAPIGetPVCDescribeHandler operator_api.GetPVCDescribeHandler
// OperatorAPIGetPVCEventsHandler sets the operation handler for the get p v c events operation
OperatorAPIGetPVCEventsHandler operator_api.GetPVCEventsHandler
// OperatorAPIGetParityHandler sets the operation handler for the get parity operation
@@ -316,6 +329,8 @@ type OperatorAPI struct {
OperatorAPIListPVCsHandler operator_api.ListPVCsHandler
// OperatorAPIListPVCsForTenantHandler sets the operation handler for the list p v cs for tenant operation
OperatorAPIListPVCsForTenantHandler operator_api.ListPVCsForTenantHandler
// OperatorAPIListTenantCertificateSigningRequestHandler sets the operation handler for the list tenant certificate signing request operation
OperatorAPIListTenantCertificateSigningRequestHandler operator_api.ListTenantCertificateSigningRequestHandler
// OperatorAPIListTenantsHandler sets the operation handler for the list tenants operation
OperatorAPIListTenantsHandler operator_api.ListTenantsHandler
// AuthLoginDetailHandler sets the operation handler for the login detail operation
@@ -467,6 +482,9 @@ func (o *OperatorAPI) Validate() error {
if o.OperatorAPIDeleteTenantHandler == nil {
unregistered = append(unregistered, "operator_api.DeleteTenantHandler")
}
if o.OperatorAPIDescribePodHandler == nil {
unregistered = append(unregistered, "operator_api.DescribePodHandler")
}
if o.OperatorAPIDisableTenantLoggingHandler == nil {
unregistered = append(unregistered, "operator_api.DisableTenantLoggingHandler")
}
@@ -479,6 +497,9 @@ func (o *OperatorAPI) Validate() error {
if o.OperatorAPIGetMaxAllocatableMemHandler == nil {
unregistered = append(unregistered, "operator_api.GetMaxAllocatableMemHandler")
}
if o.OperatorAPIGetPVCDescribeHandler == nil {
unregistered = append(unregistered, "operator_api.GetPVCDescribeHandler")
}
if o.OperatorAPIGetPVCEventsHandler == nil {
unregistered = append(unregistered, "operator_api.GetPVCEventsHandler")
}
@@ -524,6 +545,9 @@ func (o *OperatorAPI) Validate() error {
if o.OperatorAPIListPVCsForTenantHandler == nil {
unregistered = append(unregistered, "operator_api.ListPVCsForTenantHandler")
}
if o.OperatorAPIListTenantCertificateSigningRequestHandler == nil {
unregistered = append(unregistered, "operator_api.ListTenantCertificateSigningRequestHandler")
}
if o.OperatorAPIListTenantsHandler == nil {
unregistered = append(unregistered, "operator_api.ListTenantsHandler")
}
@@ -724,6 +748,10 @@ func (o *OperatorAPI) initHandlerCache() {
o.handlers["DELETE"] = make(map[string]http.Handler)
}
o.handlers["DELETE"]["/namespaces/{namespace}/tenants/{tenant}"] = operator_api.NewDeleteTenant(o.context, o.OperatorAPIDeleteTenantHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/namespaces/{namespace}/tenants/{tenant}/pods/{podName}/describe"] = operator_api.NewDescribePod(o.context, o.OperatorAPIDescribePodHandler)
if o.handlers["POST"] == nil {
o.handlers["POST"] = make(map[string]http.Handler)
}
@@ -743,6 +771,10 @@ func (o *OperatorAPI) initHandlerCache() {
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/namespaces/{namespace}/tenants/{tenant}/pvcs/{PVCName}/describe"] = operator_api.NewGetPVCDescribe(o.context, o.OperatorAPIGetPVCDescribeHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/namespaces/{namespace}/tenants/{tenant}/pvcs/{PVCName}/events"] = operator_api.NewGetPVCEvents(o.context, o.OperatorAPIGetPVCEventsHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
@@ -803,6 +835,10 @@ func (o *OperatorAPI) initHandlerCache() {
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/namespaces/{namespace}/tenants/{tenant}/csr"] = operator_api.NewListTenantCertificateSigningRequest(o.context, o.OperatorAPIListTenantCertificateSigningRequestHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/namespaces/{namespace}/tenants"] = operator_api.NewListTenants(o.context, o.OperatorAPIListTenantsHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)

View File

@@ -0,0 +1,88 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 operator_api
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"net/http"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models"
)
// DescribePodHandlerFunc turns a function with the right signature into a describe pod handler
type DescribePodHandlerFunc func(DescribePodParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn DescribePodHandlerFunc) Handle(params DescribePodParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// DescribePodHandler interface for that can handle valid describe pod params
type DescribePodHandler interface {
Handle(DescribePodParams, *models.Principal) middleware.Responder
}
// NewDescribePod creates a new http.Handler for the describe pod operation
func NewDescribePod(ctx *middleware.Context, handler DescribePodHandler) *DescribePod {
return &DescribePod{Context: ctx, Handler: handler}
}
/* DescribePod swagger:route GET /namespaces/{namespace}/tenants/{tenant}/pods/{podName}/describe OperatorAPI describePod
Describe Pod
*/
type DescribePod struct {
Context *middleware.Context
Handler DescribePodHandler
}
func (o *DescribePod) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewDescribePodParams()
uprinc, aCtx, err := o.Context.Authorize(r, route)
if err != nil {
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
if aCtx != nil {
*r = *aCtx
}
var principal *models.Principal
if uprinc != nil {
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
}
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params, principal) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -0,0 +1,136 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 operator_api
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/strfmt"
)
// NewDescribePodParams creates a new DescribePodParams object
//
// There are no default values defined in the spec.
func NewDescribePodParams() DescribePodParams {
return DescribePodParams{}
}
// DescribePodParams contains all the bound params for the describe pod operation
// typically these are obtained from a http.Request
//
// swagger:parameters DescribePod
type DescribePodParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
/*
Required: true
In: path
*/
Namespace string
/*
Required: true
In: path
*/
PodName string
/*
Required: true
In: path
*/
Tenant string
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
// for simple values it will use straight method calls.
//
// To ensure default values, the struct must have been initialized with NewDescribePodParams() beforehand.
func (o *DescribePodParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
rNamespace, rhkNamespace, _ := route.Params.GetOK("namespace")
if err := o.bindNamespace(rNamespace, rhkNamespace, route.Formats); err != nil {
res = append(res, err)
}
rPodName, rhkPodName, _ := route.Params.GetOK("podName")
if err := o.bindPodName(rPodName, rhkPodName, route.Formats); err != nil {
res = append(res, err)
}
rTenant, rhkTenant, _ := route.Params.GetOK("tenant")
if err := o.bindTenant(rTenant, rhkTenant, route.Formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// bindNamespace binds and validates parameter Namespace from path.
func (o *DescribePodParams) bindNamespace(rawData []string, hasKey bool, formats strfmt.Registry) error {
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: true
// Parameter is provided by construction from the route
o.Namespace = raw
return nil
}
// bindPodName binds and validates parameter PodName from path.
func (o *DescribePodParams) bindPodName(rawData []string, hasKey bool, formats strfmt.Registry) error {
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: true
// Parameter is provided by construction from the route
o.PodName = raw
return nil
}
// bindTenant binds and validates parameter Tenant from path.
func (o *DescribePodParams) bindTenant(rawData []string, hasKey bool, formats strfmt.Registry) error {
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: true
// Parameter is provided by construction from the route
o.Tenant = raw
return nil
}

View File

@@ -0,0 +1,133 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 operator_api
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/runtime"
"github.com/minio/console/models"
)
// DescribePodOKCode is the HTTP code returned for type DescribePodOK
const DescribePodOKCode int = 200
/*DescribePodOK A successful response.
swagger:response describePodOK
*/
type DescribePodOK struct {
/*
In: Body
*/
Payload *models.DescribePodWrapper `json:"body,omitempty"`
}
// NewDescribePodOK creates DescribePodOK with default headers values
func NewDescribePodOK() *DescribePodOK {
return &DescribePodOK{}
}
// WithPayload adds the payload to the describe pod o k response
func (o *DescribePodOK) WithPayload(payload *models.DescribePodWrapper) *DescribePodOK {
o.Payload = payload
return o
}
// SetPayload sets the payload to the describe pod o k response
func (o *DescribePodOK) SetPayload(payload *models.DescribePodWrapper) {
o.Payload = payload
}
// WriteResponse to the client
func (o *DescribePodOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(200)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}
/*DescribePodDefault Generic error response.
swagger:response describePodDefault
*/
type DescribePodDefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.Error `json:"body,omitempty"`
}
// NewDescribePodDefault creates DescribePodDefault with default headers values
func NewDescribePodDefault(code int) *DescribePodDefault {
if code <= 0 {
code = 500
}
return &DescribePodDefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the describe pod default response
func (o *DescribePodDefault) WithStatusCode(code int) *DescribePodDefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the describe pod default response
func (o *DescribePodDefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the describe pod default response
func (o *DescribePodDefault) WithPayload(payload *models.Error) *DescribePodDefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the describe pod default response
func (o *DescribePodDefault) SetPayload(payload *models.Error) {
o.Payload = payload
}
// WriteResponse to the client
func (o *DescribePodDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(o._statusCode)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}

View File

@@ -0,0 +1,132 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 operator_api
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"errors"
"net/url"
golangswaggerpaths "path"
"strings"
)
// DescribePodURL generates an URL for the describe pod operation
type DescribePodURL struct {
Namespace string
PodName string
Tenant string
_basePath string
// avoid unkeyed usage
_ struct{}
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *DescribePodURL) WithBasePath(bp string) *DescribePodURL {
o.SetBasePath(bp)
return o
}
// SetBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *DescribePodURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *DescribePodURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/namespaces/{namespace}/tenants/{tenant}/pods/{podName}/describe"
namespace := o.Namespace
if namespace != "" {
_path = strings.Replace(_path, "{namespace}", namespace, -1)
} else {
return nil, errors.New("namespace is required on DescribePodURL")
}
podName := o.PodName
if podName != "" {
_path = strings.Replace(_path, "{podName}", podName, -1)
} else {
return nil, errors.New("podName is required on DescribePodURL")
}
tenant := o.Tenant
if tenant != "" {
_path = strings.Replace(_path, "{tenant}", tenant, -1)
} else {
return nil, errors.New("tenant is required on DescribePodURL")
}
_basePath := o._basePath
if _basePath == "" {
_basePath = "/api/v1"
}
_result.Path = golangswaggerpaths.Join(_basePath, _path)
return &_result, nil
}
// Must is a helper function to panic when the url builder returns an error
func (o *DescribePodURL) Must(u *url.URL, err error) *url.URL {
if err != nil {
panic(err)
}
if u == nil {
panic("url can't be nil")
}
return u
}
// String returns the string representation of the path with query string
func (o *DescribePodURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *DescribePodURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on DescribePodURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on DescribePodURL")
}
base, err := o.Build()
if err != nil {
return nil, err
}
base.Scheme = scheme
base.Host = host
return base, nil
}
// StringFull returns the string representation of a complete url
func (o *DescribePodURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -0,0 +1,88 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 operator_api
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"net/http"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models"
)
// GetPVCDescribeHandlerFunc turns a function with the right signature into a get p v c describe handler
type GetPVCDescribeHandlerFunc func(GetPVCDescribeParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn GetPVCDescribeHandlerFunc) Handle(params GetPVCDescribeParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// GetPVCDescribeHandler interface for that can handle valid get p v c describe params
type GetPVCDescribeHandler interface {
Handle(GetPVCDescribeParams, *models.Principal) middleware.Responder
}
// NewGetPVCDescribe creates a new http.Handler for the get p v c describe operation
func NewGetPVCDescribe(ctx *middleware.Context, handler GetPVCDescribeHandler) *GetPVCDescribe {
return &GetPVCDescribe{Context: ctx, Handler: handler}
}
/* GetPVCDescribe swagger:route GET /namespaces/{namespace}/tenants/{tenant}/pvcs/{PVCName}/describe OperatorAPI getPVCDescribe
Get Describe output for PVC
*/
type GetPVCDescribe struct {
Context *middleware.Context
Handler GetPVCDescribeHandler
}
func (o *GetPVCDescribe) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewGetPVCDescribeParams()
uprinc, aCtx, err := o.Context.Authorize(r, route)
if err != nil {
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
if aCtx != nil {
*r = *aCtx
}
var principal *models.Principal
if uprinc != nil {
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
}
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params, principal) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -0,0 +1,136 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 operator_api
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/strfmt"
)
// NewGetPVCDescribeParams creates a new GetPVCDescribeParams object
//
// There are no default values defined in the spec.
func NewGetPVCDescribeParams() GetPVCDescribeParams {
return GetPVCDescribeParams{}
}
// GetPVCDescribeParams contains all the bound params for the get p v c describe operation
// typically these are obtained from a http.Request
//
// swagger:parameters GetPVCDescribe
type GetPVCDescribeParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
/*
Required: true
In: path
*/
PVCName string
/*
Required: true
In: path
*/
Namespace string
/*
Required: true
In: path
*/
Tenant string
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
// for simple values it will use straight method calls.
//
// To ensure default values, the struct must have been initialized with NewGetPVCDescribeParams() beforehand.
func (o *GetPVCDescribeParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
rPVCName, rhkPVCName, _ := route.Params.GetOK("PVCName")
if err := o.bindPVCName(rPVCName, rhkPVCName, route.Formats); err != nil {
res = append(res, err)
}
rNamespace, rhkNamespace, _ := route.Params.GetOK("namespace")
if err := o.bindNamespace(rNamespace, rhkNamespace, route.Formats); err != nil {
res = append(res, err)
}
rTenant, rhkTenant, _ := route.Params.GetOK("tenant")
if err := o.bindTenant(rTenant, rhkTenant, route.Formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// bindPVCName binds and validates parameter PVCName from path.
func (o *GetPVCDescribeParams) bindPVCName(rawData []string, hasKey bool, formats strfmt.Registry) error {
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: true
// Parameter is provided by construction from the route
o.PVCName = raw
return nil
}
// bindNamespace binds and validates parameter Namespace from path.
func (o *GetPVCDescribeParams) bindNamespace(rawData []string, hasKey bool, formats strfmt.Registry) error {
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: true
// Parameter is provided by construction from the route
o.Namespace = raw
return nil
}
// bindTenant binds and validates parameter Tenant from path.
func (o *GetPVCDescribeParams) bindTenant(rawData []string, hasKey bool, formats strfmt.Registry) error {
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: true
// Parameter is provided by construction from the route
o.Tenant = raw
return nil
}

View File

@@ -0,0 +1,133 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 operator_api
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/runtime"
"github.com/minio/console/models"
)
// GetPVCDescribeOKCode is the HTTP code returned for type GetPVCDescribeOK
const GetPVCDescribeOKCode int = 200
/*GetPVCDescribeOK A successful response.
swagger:response getPVCDescribeOK
*/
type GetPVCDescribeOK struct {
/*
In: Body
*/
Payload *models.DescribePVCWrapper `json:"body,omitempty"`
}
// NewGetPVCDescribeOK creates GetPVCDescribeOK with default headers values
func NewGetPVCDescribeOK() *GetPVCDescribeOK {
return &GetPVCDescribeOK{}
}
// WithPayload adds the payload to the get p v c describe o k response
func (o *GetPVCDescribeOK) WithPayload(payload *models.DescribePVCWrapper) *GetPVCDescribeOK {
o.Payload = payload
return o
}
// SetPayload sets the payload to the get p v c describe o k response
func (o *GetPVCDescribeOK) SetPayload(payload *models.DescribePVCWrapper) {
o.Payload = payload
}
// WriteResponse to the client
func (o *GetPVCDescribeOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(200)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}
/*GetPVCDescribeDefault Generic error response.
swagger:response getPVCDescribeDefault
*/
type GetPVCDescribeDefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.Error `json:"body,omitempty"`
}
// NewGetPVCDescribeDefault creates GetPVCDescribeDefault with default headers values
func NewGetPVCDescribeDefault(code int) *GetPVCDescribeDefault {
if code <= 0 {
code = 500
}
return &GetPVCDescribeDefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the get p v c describe default response
func (o *GetPVCDescribeDefault) WithStatusCode(code int) *GetPVCDescribeDefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the get p v c describe default response
func (o *GetPVCDescribeDefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the get p v c describe default response
func (o *GetPVCDescribeDefault) WithPayload(payload *models.Error) *GetPVCDescribeDefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the get p v c describe default response
func (o *GetPVCDescribeDefault) SetPayload(payload *models.Error) {
o.Payload = payload
}
// WriteResponse to the client
func (o *GetPVCDescribeDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(o._statusCode)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}

View File

@@ -0,0 +1,132 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 operator_api
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"errors"
"net/url"
golangswaggerpaths "path"
"strings"
)
// GetPVCDescribeURL generates an URL for the get p v c describe operation
type GetPVCDescribeURL struct {
PVCName string
Namespace string
Tenant string
_basePath string
// avoid unkeyed usage
_ struct{}
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *GetPVCDescribeURL) WithBasePath(bp string) *GetPVCDescribeURL {
o.SetBasePath(bp)
return o
}
// SetBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *GetPVCDescribeURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *GetPVCDescribeURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/namespaces/{namespace}/tenants/{tenant}/pvcs/{PVCName}/describe"
pVCName := o.PVCName
if pVCName != "" {
_path = strings.Replace(_path, "{PVCName}", pVCName, -1)
} else {
return nil, errors.New("pVCName is required on GetPVCDescribeURL")
}
namespace := o.Namespace
if namespace != "" {
_path = strings.Replace(_path, "{namespace}", namespace, -1)
} else {
return nil, errors.New("namespace is required on GetPVCDescribeURL")
}
tenant := o.Tenant
if tenant != "" {
_path = strings.Replace(_path, "{tenant}", tenant, -1)
} else {
return nil, errors.New("tenant is required on GetPVCDescribeURL")
}
_basePath := o._basePath
if _basePath == "" {
_basePath = "/api/v1"
}
_result.Path = golangswaggerpaths.Join(_basePath, _path)
return &_result, nil
}
// Must is a helper function to panic when the url builder returns an error
func (o *GetPVCDescribeURL) Must(u *url.URL, err error) *url.URL {
if err != nil {
panic(err)
}
if u == nil {
panic("url can't be nil")
}
return u
}
// String returns the string representation of the path with query string
func (o *GetPVCDescribeURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *GetPVCDescribeURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on GetPVCDescribeURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on GetPVCDescribeURL")
}
base, err := o.Build()
if err != nil {
return nil, err
}
base.Scheme = scheme
base.Host = host
return base, nil
}
// StringFull returns the string representation of a complete url
func (o *GetPVCDescribeURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -0,0 +1,88 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 operator_api
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"net/http"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models"
)
// ListTenantCertificateSigningRequestHandlerFunc turns a function with the right signature into a list tenant certificate signing request handler
type ListTenantCertificateSigningRequestHandlerFunc func(ListTenantCertificateSigningRequestParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn ListTenantCertificateSigningRequestHandlerFunc) Handle(params ListTenantCertificateSigningRequestParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// ListTenantCertificateSigningRequestHandler interface for that can handle valid list tenant certificate signing request params
type ListTenantCertificateSigningRequestHandler interface {
Handle(ListTenantCertificateSigningRequestParams, *models.Principal) middleware.Responder
}
// NewListTenantCertificateSigningRequest creates a new http.Handler for the list tenant certificate signing request operation
func NewListTenantCertificateSigningRequest(ctx *middleware.Context, handler ListTenantCertificateSigningRequestHandler) *ListTenantCertificateSigningRequest {
return &ListTenantCertificateSigningRequest{Context: ctx, Handler: handler}
}
/* ListTenantCertificateSigningRequest swagger:route GET /namespaces/{namespace}/tenants/{tenant}/csr OperatorAPI listTenantCertificateSigningRequest
List Tenant Certificate Signing Request
*/
type ListTenantCertificateSigningRequest struct {
Context *middleware.Context
Handler ListTenantCertificateSigningRequestHandler
}
func (o *ListTenantCertificateSigningRequest) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewListTenantCertificateSigningRequestParams()
uprinc, aCtx, err := o.Context.Authorize(r, route)
if err != nil {
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
if aCtx != nil {
*r = *aCtx
}
var principal *models.Principal
if uprinc != nil {
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
}
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params, principal) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -0,0 +1,112 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 operator_api
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/strfmt"
)
// NewListTenantCertificateSigningRequestParams creates a new ListTenantCertificateSigningRequestParams object
//
// There are no default values defined in the spec.
func NewListTenantCertificateSigningRequestParams() ListTenantCertificateSigningRequestParams {
return ListTenantCertificateSigningRequestParams{}
}
// ListTenantCertificateSigningRequestParams contains all the bound params for the list tenant certificate signing request operation
// typically these are obtained from a http.Request
//
// swagger:parameters ListTenantCertificateSigningRequest
type ListTenantCertificateSigningRequestParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
/*
Required: true
In: path
*/
Namespace string
/*
Required: true
In: path
*/
Tenant string
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
// for simple values it will use straight method calls.
//
// To ensure default values, the struct must have been initialized with NewListTenantCertificateSigningRequestParams() beforehand.
func (o *ListTenantCertificateSigningRequestParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
rNamespace, rhkNamespace, _ := route.Params.GetOK("namespace")
if err := o.bindNamespace(rNamespace, rhkNamespace, route.Formats); err != nil {
res = append(res, err)
}
rTenant, rhkTenant, _ := route.Params.GetOK("tenant")
if err := o.bindTenant(rTenant, rhkTenant, route.Formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// bindNamespace binds and validates parameter Namespace from path.
func (o *ListTenantCertificateSigningRequestParams) bindNamespace(rawData []string, hasKey bool, formats strfmt.Registry) error {
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: true
// Parameter is provided by construction from the route
o.Namespace = raw
return nil
}
// bindTenant binds and validates parameter Tenant from path.
func (o *ListTenantCertificateSigningRequestParams) bindTenant(rawData []string, hasKey bool, formats strfmt.Registry) error {
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: true
// Parameter is provided by construction from the route
o.Tenant = raw
return nil
}

View File

@@ -0,0 +1,133 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 operator_api
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/runtime"
"github.com/minio/console/models"
)
// ListTenantCertificateSigningRequestOKCode is the HTTP code returned for type ListTenantCertificateSigningRequestOK
const ListTenantCertificateSigningRequestOKCode int = 200
/*ListTenantCertificateSigningRequestOK A successful response.
swagger:response listTenantCertificateSigningRequestOK
*/
type ListTenantCertificateSigningRequestOK struct {
/*
In: Body
*/
Payload *models.CsrElement `json:"body,omitempty"`
}
// NewListTenantCertificateSigningRequestOK creates ListTenantCertificateSigningRequestOK with default headers values
func NewListTenantCertificateSigningRequestOK() *ListTenantCertificateSigningRequestOK {
return &ListTenantCertificateSigningRequestOK{}
}
// WithPayload adds the payload to the list tenant certificate signing request o k response
func (o *ListTenantCertificateSigningRequestOK) WithPayload(payload *models.CsrElement) *ListTenantCertificateSigningRequestOK {
o.Payload = payload
return o
}
// SetPayload sets the payload to the list tenant certificate signing request o k response
func (o *ListTenantCertificateSigningRequestOK) SetPayload(payload *models.CsrElement) {
o.Payload = payload
}
// WriteResponse to the client
func (o *ListTenantCertificateSigningRequestOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(200)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}
/*ListTenantCertificateSigningRequestDefault Generic error response.
swagger:response listTenantCertificateSigningRequestDefault
*/
type ListTenantCertificateSigningRequestDefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.Error `json:"body,omitempty"`
}
// NewListTenantCertificateSigningRequestDefault creates ListTenantCertificateSigningRequestDefault with default headers values
func NewListTenantCertificateSigningRequestDefault(code int) *ListTenantCertificateSigningRequestDefault {
if code <= 0 {
code = 500
}
return &ListTenantCertificateSigningRequestDefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the list tenant certificate signing request default response
func (o *ListTenantCertificateSigningRequestDefault) WithStatusCode(code int) *ListTenantCertificateSigningRequestDefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the list tenant certificate signing request default response
func (o *ListTenantCertificateSigningRequestDefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the list tenant certificate signing request default response
func (o *ListTenantCertificateSigningRequestDefault) WithPayload(payload *models.Error) *ListTenantCertificateSigningRequestDefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the list tenant certificate signing request default response
func (o *ListTenantCertificateSigningRequestDefault) SetPayload(payload *models.Error) {
o.Payload = payload
}
// WriteResponse to the client
func (o *ListTenantCertificateSigningRequestDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(o._statusCode)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}

View File

@@ -0,0 +1,124 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 operator_api
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"errors"
"net/url"
golangswaggerpaths "path"
"strings"
)
// ListTenantCertificateSigningRequestURL generates an URL for the list tenant certificate signing request operation
type ListTenantCertificateSigningRequestURL struct {
Namespace string
Tenant string
_basePath string
// avoid unkeyed usage
_ struct{}
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *ListTenantCertificateSigningRequestURL) WithBasePath(bp string) *ListTenantCertificateSigningRequestURL {
o.SetBasePath(bp)
return o
}
// SetBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *ListTenantCertificateSigningRequestURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *ListTenantCertificateSigningRequestURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/namespaces/{namespace}/tenants/{tenant}/csr"
namespace := o.Namespace
if namespace != "" {
_path = strings.Replace(_path, "{namespace}", namespace, -1)
} else {
return nil, errors.New("namespace is required on ListTenantCertificateSigningRequestURL")
}
tenant := o.Tenant
if tenant != "" {
_path = strings.Replace(_path, "{tenant}", tenant, -1)
} else {
return nil, errors.New("tenant is required on ListTenantCertificateSigningRequestURL")
}
_basePath := o._basePath
if _basePath == "" {
_basePath = "/api/v1"
}
_result.Path = golangswaggerpaths.Join(_basePath, _path)
return &_result, nil
}
// Must is a helper function to panic when the url builder returns an error
func (o *ListTenantCertificateSigningRequestURL) Must(u *url.URL, err error) *url.URL {
if err != nil {
panic(err)
}
if u == nil {
panic("url can't be nil")
}
return u
}
// String returns the string representation of the path with query string
func (o *ListTenantCertificateSigningRequestURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *ListTenantCertificateSigningRequestURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on ListTenantCertificateSigningRequestURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on ListTenantCertificateSigningRequestURL")
}
base, err := o.Build()
if err != nil {
return nil, err
}
base.Scheme = scheme
base.Host = host
return base, nil
}
// StringFull returns the string representation of a complete url
func (o *ListTenantCertificateSigningRequestURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -42,7 +42,6 @@ func registerParityHandlers(api *operations.OperatorAPI) {
func GetParityInfo(nodes int64, disksPerNode int64) (models.ParityResponse, error) {
parityVals, err := utils.PossibleParityValues(fmt.Sprintf(`http://minio{1...%d}/export/set{1...%d}`, nodes, disksPerNode))
if err != nil {
return nil, err
}

View File

@@ -99,8 +99,8 @@ func serveProxy(responseWriter http.ResponseWriter, req *http.Request) {
tenantURL := fmt.Sprintf("%s://%s.%s.svc.%s%s", tenantSchema, tenant.ConsoleCIServiceName(), tenant.Namespace, v2.GetClusterDomain(), tenantPort)
// for development
//tenantURL = "http://localhost:9091"
//tenantURL = "https://localhost:9443"
// tenantURL = "http://localhost:9091"
// tenantURL = "https://localhost:9443"
h := sha1.New()
h.Write([]byte(nsTenant))
@@ -201,7 +201,7 @@ func serveProxy(responseWriter http.ResponseWriter, req *http.Request) {
return
}
tenantBase := fmt.Sprintf("/api/%s/%s/%s", proxyMethod, tenant.Namespace, tenant.Name)
targetURL.Path = strings.Replace(req.URL.Path, tenantBase, "", -1)
targetURL.Path = strings.ReplaceAll(req.URL.Path, tenantBase, "")
proxiedCookie := &http.Cookie{
Name: "token",
@@ -219,7 +219,6 @@ func serveProxy(responseWriter http.ResponseWriter, req *http.Request) {
default:
handleHTTPRequest(responseWriter, req, proxyCookieJar, tenantBase, targetURL)
}
}
func handleHTTPRequest(responseWriter http.ResponseWriter, req *http.Request, proxyCookieJar *cookiejar.Jar, tenantBase string, targetURL *url2.URL) {
@@ -227,11 +226,13 @@ func handleHTTPRequest(responseWriter http.ResponseWriter, req *http.Request, pr
// FIXME: use restapi.GetConsoleHTTPClient()
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr,
Jar: proxyCookieJar,
client := &http.Client{
Transport: tr,
Jar: proxyCookieJar,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
}}
},
}
// are we proxying something with cp=y? (console proxy) then add cpb (console proxy base) so the console
// on the other side updates the <base href="" /> to this value overriding sub path or root

View File

@@ -41,7 +41,6 @@ func registerResourceQuotaHandlers(api *operations.OperatorAPI) {
return operator_api.NewGetResourceQuotaDefault(int(err.Code)).WithPayload(err)
}
return operator_api.NewGetResourceQuotaOK().WithPayload(resp)
})
}

View File

@@ -18,13 +18,12 @@ package operatorapi
import (
"context"
"errors"
"reflect"
"testing"
storagev1 "k8s.io/api/storage/v1"
"errors"
"github.com/minio/console/models"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
@@ -33,9 +32,11 @@ import (
type k8sClientMock struct{}
var k8sclientGetResourceQuotaMock func(ctx context.Context, namespace, resource string, opts metav1.GetOptions) (*v1.ResourceQuota, error)
var k8sclientGetNameSpaceMock func(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Namespace, error)
var k8sclientStorageClassesMock func(ctx context.Context, opts metav1.ListOptions) (*storagev1.StorageClassList, error)
var (
k8sclientGetResourceQuotaMock func(ctx context.Context, namespace, resource string, opts metav1.GetOptions) (*v1.ResourceQuota, error)
k8sclientGetNameSpaceMock func(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Namespace, error)
k8sclientStorageClassesMock func(ctx context.Context, opts metav1.ListOptions) (*storagev1.StorageClassList, error)
)
// mock functions
func (c k8sClientMock) getResourceQuota(ctx context.Context, namespace, resource string, opts metav1.GetOptions) (*v1.ResourceQuota, error) {

View File

@@ -132,7 +132,7 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
tenantConfigurationENV["MINIO_STORAGE_CLASS_STANDARD"] = fmt.Sprintf("EC:%d", tenantReq.ErasureCodingParity)
}
//Construct a MinIO Instance with everything we are getting from parameters
// Construct a MinIO Instance with everything we are getting from parameters
minInst := miniov2.Tenant{
ObjectMeta: metav1.ObjectMeta{
Name: tenantName,
@@ -149,7 +149,8 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
var tenantExternalIDPConfigured bool
if tenantReq.Idp != nil {
// Enable IDP (Active Directory) for MinIO
if tenantReq.Idp.ActiveDirectory != nil {
switch {
case tenantReq.Idp.ActiveDirectory != nil:
tenantExternalIDPConfigured = true
serverAddress := *tenantReq.Idp.ActiveDirectory.URL
tlsSkipVerify := tenantReq.Idp.ActiveDirectory.SkipTLSVerification
@@ -209,8 +210,7 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
}
// attach the users to the tenant
minInst.Spec.Users = users
} else if tenantReq.Idp.Oidc != nil {
case tenantReq.Idp.Oidc != nil:
tenantExternalIDPConfigured = true
// Enable IDP (OIDC) for MinIO
configurationURL := *tenantReq.Idp.Oidc.ConfigurationURL
@@ -228,7 +228,7 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
scopes = "openid,profile,email"
}
tenantConfigurationENV["MINIO_IDENTITY_OPENID_SCOPES"] = scopes
} else if len(tenantReq.Idp.Keys) > 0 {
case len(tenantReq.Idp.Keys) > 0:
// Create the secret any built-in user passed if no external IDP was configured
for i := 0; i < len(tenantReq.Idp.Keys); i++ {
userSecretName := fmt.Sprintf("%s-user-%d", tenantName, i)
@@ -382,7 +382,7 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
// Is Log Search enabled? (present in the parameters) if so configure
if tenantReq.LogSearchConfiguration != nil {
//Default class name for Log search
// Default class name for Log search
diskSpaceFromAPI := int64(5) * humanize.GiByte // Default is 5Gi
logSearchImage := ""
logSearchPgImage := ""

View File

@@ -64,22 +64,13 @@ func getTenantDetailsResponse(session *models.Principal, params operator_api.Ten
}
// detect if AD/LDAP is enabled
ldapEnabled := false
if string(tenantConfiguration["MINIO_IDENTITY_LDAP_SERVER_ADDR"]) != "" {
ldapEnabled = true
}
ldapEnabled := tenantConfiguration["MINIO_IDENTITY_LDAP_SERVER_ADDR"] != ""
// detect if OpenID is enabled
oidcEnabled := false
if string(tenantConfiguration["MINIO_IDENTITY_OPENID_CONFIG_URL"]) != "" {
oidcEnabled = true
}
oidcEnabled := tenantConfiguration["MINIO_IDENTITY_OPENID_CONFIG_URL"] != ""
// detect if encryption is enabled
if minTenant.HasKESEnabled() || string(tenantConfiguration["MINIO_KMS_SECRET_KEY"]) != "" {
info.EncryptionEnabled = true
}
info.EncryptionEnabled = minTenant.HasKESEnabled() || tenantConfiguration["MINIO_KMS_SECRET_KEY"] != ""
info.LogEnabled = minTenant.HasLogEnabled()
info.MonitoringEnabled = minTenant.HasPrometheusEnabled()
info.IdpAdEnabled = ldapEnabled
@@ -103,13 +94,13 @@ func getTenantDetailsResponse(session *models.Principal, params operator_api.Ten
// get tenant service
minTenant.EnsureDefaults()
//minio service
// minio service
minSvc, err := k8sClient.getService(ctx, minTenant.Namespace, minTenant.MinIOCIServiceName(), metav1.GetOptions{})
if err != nil {
// we can tolerate this errors
errors.LogError("Unable to get MinIO service name: %v, continuing", err)
}
//console service
// console service
conSvc, err := k8sClient.getService(ctx, minTenant.Namespace, minTenant.ConsoleCIServiceName(), metav1.GetOptions{})
if err != nil {
// we can tolerate this errors
@@ -117,13 +108,14 @@ func getTenantDetailsResponse(session *models.Principal, params operator_api.Ten
}
schema := "http"
consoleSchema := "http"
consoleSchema := schema
consolePort := fmt.Sprintf(":%d", miniov2.ConsolePort)
if minTenant.TLS() {
schema = "https"
consoleSchema = "https"
consoleSchema = schema
consolePort = fmt.Sprintf(":%d", miniov2.ConsoleTLSPort)
}
var minioEndpoint string
var consoleEndpoint string
if minSvc != nil && len(minSvc.Status.LoadBalancer.Ingress) > 0 {
@@ -136,6 +128,7 @@ func getTenantDetailsResponse(session *models.Principal, params operator_api.Ten
}
}
if conSvc != nil && len(conSvc.Status.LoadBalancer.Ingress) > 0 {
if conSvc.Status.LoadBalancer.Ingress[0].IP != "" {
consoleEndpoint = fmt.Sprintf("%s://%s%s", consoleSchema, conSvc.Status.LoadBalancer.Ingress[0].IP, consolePort)
@@ -144,11 +137,10 @@ func getTenantDetailsResponse(session *models.Principal, params operator_api.Ten
consoleEndpoint = fmt.Sprintf("%s://%s%s", consoleSchema, conSvc.Status.LoadBalancer.Ingress[0].Hostname, consolePort)
}
}
if minioEndpoint != "" || consoleEndpoint != "" {
info.Endpoints = &models.TenantEndpoints{
Console: consoleEndpoint,
Minio: minioEndpoint,
}
info.Endpoints = &models.TenantEndpoints{
Console: consoleEndpoint,
Minio: minioEndpoint,
}
var domains models.DomainsConfiguration

View File

@@ -44,11 +44,13 @@ import (
"github.com/minio/console/pkg/auth/utils"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/duration"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/utils/strings/slices"
corev1 "k8s.io/api/core/v1"
@@ -90,7 +92,6 @@ func registerTenantHandlers(api *operations.OperatorAPI) {
return operator_api.NewListTenantsDefault(int(err.Code)).WithPayload(err)
}
return operator_api.NewListTenantsOK().WithPayload(resp)
})
// List Tenants by namespace
api.OperatorAPIListTenantsHandler = operator_api.ListTenantsHandlerFunc(func(params operator_api.ListTenantsParams, session *models.Principal) middleware.Responder {
@@ -99,7 +100,6 @@ func registerTenantHandlers(api *operations.OperatorAPI) {
return operator_api.NewListTenantsDefault(int(err.Code)).WithPayload(err)
}
return operator_api.NewListTenantsOK().WithPayload(resp)
})
// Detail Tenant
api.OperatorAPITenantDetailsHandler = operator_api.TenantDetailsHandlerFunc(func(params operator_api.TenantDetailsParams, session *models.Principal) middleware.Responder {
@@ -108,7 +108,6 @@ func registerTenantHandlers(api *operations.OperatorAPI) {
return operator_api.NewTenantDetailsDefault(int(err.Code)).WithPayload(err)
}
return operator_api.NewTenantDetailsOK().WithPayload(resp)
})
// Tenant Security details
@@ -118,7 +117,6 @@ func registerTenantHandlers(api *operations.OperatorAPI) {
return operator_api.NewTenantSecurityDefault(int(err.Code)).WithPayload(err)
}
return operator_api.NewTenantSecurityOK().WithPayload(resp)
})
// Update Tenant Security configuration
@@ -128,7 +126,6 @@ func registerTenantHandlers(api *operations.OperatorAPI) {
return operator_api.NewUpdateTenantSecurityDefault(int(err.Code)).WithPayload(err)
}
return operator_api.NewUpdateTenantSecurityNoContent()
})
// Tenant identity provider details
@@ -138,7 +135,6 @@ func registerTenantHandlers(api *operations.OperatorAPI) {
return operator_api.NewTenantIdentityProviderDefault(int(err.Code)).WithPayload(err)
}
return operator_api.NewTenantIdentityProviderOK().WithPayload(resp)
})
// Update Tenant identity provider configuration
@@ -148,7 +144,6 @@ func registerTenantHandlers(api *operations.OperatorAPI) {
return operator_api.NewUpdateTenantIdentityProviderDefault(int(err.Code)).WithPayload(err)
}
return operator_api.NewUpdateTenantIdentityProviderNoContent()
})
// Delete Tenant
@@ -158,7 +153,6 @@ func registerTenantHandlers(api *operations.OperatorAPI) {
return operator_api.NewDeleteTenantDefault(int(err.Code)).WithPayload(err)
}
return operator_api.NewDeleteTenantNoContent()
})
// Delete Pod
@@ -168,7 +162,6 @@ func registerTenantHandlers(api *operations.OperatorAPI) {
return operator_api.NewDeletePodDefault(int(err.Code)).WithPayload(err)
}
return operator_api.NewDeletePodNoContent()
})
// Update Tenant
@@ -256,7 +249,15 @@ func registerTenantHandlers(api *operations.OperatorAPI) {
return operator_api.NewGetPodEventsOK().WithPayload(payload)
})
//Get tenant monitoring info
api.OperatorAPIDescribePodHandler = operator_api.DescribePodHandlerFunc(func(params operator_api.DescribePodParams, session *models.Principal) middleware.Responder {
payload, err := getDescribePodResponse(session, params)
if err != nil {
return operator_api.NewDescribePodDefault(int(err.Code)).WithPayload(err)
}
return operator_api.NewDescribePodOK().WithPayload(payload)
})
// Get tenant monitoring info
api.OperatorAPIGetTenantMonitoringHandler = operator_api.GetTenantMonitoringHandlerFunc(func(params operator_api.GetTenantMonitoringParams, session *models.Principal) middleware.Responder {
payload, err := getTenantMonitoringResponse(session, params)
if err != nil {
@@ -264,7 +265,7 @@ func registerTenantHandlers(api *operations.OperatorAPI) {
}
return operator_api.NewGetTenantMonitoringOK().WithPayload(payload)
})
//Set configuration fields for Prometheus monitoring on a tenant
// Set configuration fields for Prometheus monitoring on a tenant
api.OperatorAPISetTenantMonitoringHandler = operator_api.SetTenantMonitoringHandlerFunc(func(params operator_api.SetTenantMonitoringParams, session *models.Principal) middleware.Responder {
_, err := setTenantMonitoringResponse(session, params)
if err != nil {
@@ -393,8 +394,8 @@ func deleteTenantAction(
operatorClient OperatorClientI,
clientset v1.CoreV1Interface,
tenant *miniov2.Tenant,
deletePvcs bool) error {
deletePvcs bool,
) error {
err := operatorClient.TenantDelete(ctx, tenant.Namespace, tenant.Name, metav1.DeleteOptions{})
if err != nil {
// try to delete pvc even if the tenant doesn't exist anymore but only if deletePvcs is set to true,
@@ -538,7 +539,7 @@ func getTenantInfo(tenant *miniov2.Tenant) *models.Tenant {
for _, p := range tenant.Spec.Pools {
pools = append(pools, parseTenantPool(&p))
poolSize := int64(p.Servers) * int64(p.VolumesPerServer) * p.VolumeClaimTemplate.Spec.Resources.Requests.Storage().Value()
totalSize = totalSize + poolSize
totalSize += poolSize
}
var deletion string
if tenant.ObjectMeta.DeletionTimestamp != nil {
@@ -586,6 +587,13 @@ func parseCertificate(name string, rawCert []byte) (*models.CertificateInfo, err
}, nil
}
var secretTypePublicKeyNameMap = map[string]string{
"kubernetes.io/tls": "tls.crt",
"cert-manager.io/v1": "tls.crt",
"cert-manager.io/v1alpha2": "tls.crt",
// Add newer secretTypes and their corresponding values in future
}
// parseTenantCertificates convert public key pem certificates stored in k8s secrets for a given Tenant into x509 certificates
func parseTenantCertificates(ctx context.Context, clientSet K8sClientI, namespace string, secrets []*miniov2.LocalCertificateReference) ([]*models.CertificateInfo, error) {
var certificates []*models.CertificateInfo
@@ -597,9 +605,11 @@ func parseTenantCertificates(ctx context.Context, clientSet K8sClientI, namespac
if err != nil {
return nil, err
}
if secret.Type == "kubernetes.io/tls" || secret.Type == "cert-manager.io/v1alpha2" {
publicKey = "tls.crt"
if v, ok := secretTypePublicKeyNameMap[secret.Type]; ok {
publicKey = v
}
// Extract public key from certificate TLS secret
if rawCert, ok := keyPair.Data[publicKey]; ok {
var blocks []byte
@@ -843,7 +853,6 @@ func updateTenantIdentityProvider(ctx context.Context, operatorClient OperatorCl
}
func getTenantIdentityProviderResponse(session *models.Principal, params operator_api.TenantIdentityProviderParams) (*models.IdpConfiguration, *models.Error) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
@@ -874,7 +883,6 @@ func getTenantIdentityProviderResponse(session *models.Principal, params operato
}
func getUpdateTenantIdentityProviderResponse(session *models.Principal, params operator_api.UpdateTenantIdentityProviderParams) *models.Error {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
opClientClientSet, err := cluster.OperatorClient(session.STSSessionToken)
@@ -899,7 +907,6 @@ func getUpdateTenantIdentityProviderResponse(session *models.Principal, params o
}
func getTenantSecurityResponse(session *models.Principal, params operator_api.TenantSecurityParams) (*models.TenantSecurityResponse, *models.Error) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
opClientClientSet, err := cluster.OperatorClient(session.STSSessionToken)
@@ -929,7 +936,6 @@ func getTenantSecurityResponse(session *models.Principal, params operator_api.Te
}
func getUpdateTenantSecurityResponse(session *models.Principal, params operator_api.UpdateTenantSecurityParams) *models.Error {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
opClientClientSet, err := cluster.OperatorClient(session.STSSessionToken)
@@ -991,7 +997,7 @@ func updateTenantSecurity(ctx context.Context, operatorClient OperatorClientI, c
}
newMinIOExternalCaCertSecret = append(newMinIOExternalCaCertSecret, certificate)
}
//Create new Certificate Secrets for MinIO
// Create new Certificate Secrets for MinIO
secretName := fmt.Sprintf("%s-%s", minInst.Name, strings.ToLower(utils.RandomCharString(5)))
externalCertSecretName := fmt.Sprintf("%s-external-certificates", secretName)
externalCertSecrets, err := createOrReplaceExternalCertSecrets(ctx, client, minInst.Namespace, params.Body.CustomCertificates.Minio, externalCertSecretName, minInst.Name)
@@ -1058,11 +1064,11 @@ func listTenants(ctx context.Context, operatorClient OperatorClientI, namespace
var instanceCount int64
var volumeCount int64
for _, pool := range tenant.Spec.Pools {
instanceCount = instanceCount + int64(pool.Servers)
volumeCount = volumeCount + int64(pool.Servers*pool.VolumesPerServer)
instanceCount += int64(pool.Servers)
volumeCount += int64(pool.Servers * pool.VolumesPerServer)
if pool.VolumeClaimTemplate != nil {
poolSize := int64(pool.VolumesPerServer) * int64(pool.Servers) * pool.VolumeClaimTemplate.Spec.Resources.Requests.Storage().Value()
totalSize = totalSize + poolSize
totalSize += poolSize
}
}
@@ -1303,7 +1309,6 @@ func getTenantAddPoolResponse(session *models.Principal, params operator_api.Ten
// getTenantUsageResponse returns the usage of a tenant
func getTenantUsageResponse(session *models.Principal, params operator_api.GetTenantUsageParams) (*models.TenantUsage, *models.Error) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
@@ -1354,7 +1359,6 @@ func getTenantUsageResponse(session *models.Principal, params operator_api.GetTe
// getTenantLogsResponse returns the logs of a tenant
func getTenantLogsResponse(session *models.Principal, params operator_api.GetTenantLogsParams) (*models.TenantLogs, *models.Error) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
@@ -1451,7 +1455,6 @@ func getTenantLogsResponse(session *models.Principal, params operator_api.GetTen
// setTenantLogsResponse returns the logs of a tenant
func setTenantLogsResponse(session *models.Principal, params operator_api.SetTenantLogsParams) (bool, *models.Error) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
@@ -1469,21 +1472,21 @@ func setTenantLogsResponse(session *models.Principal, params operator_api.SetTen
return false, restapi.ErrorWithContext(ctx, err, restapi.ErrUnableToGetTenantUsage)
}
var labels = make(map[string]string)
labels := make(map[string]string)
for i := 0; i < len(params.Data.Labels); i++ {
if params.Data.Labels[i] != nil {
labels[params.Data.Labels[i].Key] = params.Data.Labels[i].Value
}
}
minTenant.Spec.Log.Labels = labels
var annotations = make(map[string]string)
annotations := make(map[string]string)
for i := 0; i < len(params.Data.Annotations); i++ {
if params.Data.Annotations[i] != nil {
annotations[params.Data.Annotations[i].Key] = params.Data.Annotations[i].Value
}
}
minTenant.Spec.Log.Annotations = annotations
var nodeSelector = make(map[string]string)
nodeSelector := make(map[string]string)
for i := 0; i < len(params.Data.NodeSelector); i++ {
if params.Data.NodeSelector[i] != nil {
nodeSelector[params.Data.NodeSelector[i].Key] = params.Data.NodeSelector[i].Value
@@ -1514,21 +1517,21 @@ func setTenantLogsResponse(session *models.Principal, params operator_api.SetTen
if minTenant.Spec.Log.Db != nil {
modified = true
}
var dbLabels = make(map[string]string)
dbLabels := make(map[string]string)
for i := 0; i < len(params.Data.DbLabels); i++ {
if params.Data.DbLabels[i] != nil {
dbLabels[params.Data.DbLabels[i].Key] = params.Data.DbLabels[i].Value
}
modified = true
}
var dbAnnotations = make(map[string]string)
dbAnnotations := make(map[string]string)
for i := 0; i < len(params.Data.DbAnnotations); i++ {
if params.Data.DbAnnotations[i] != nil {
dbAnnotations[params.Data.DbAnnotations[i].Key] = params.Data.DbAnnotations[i].Value
}
modified = true
}
var dbNodeSelector = make(map[string]string)
dbNodeSelector := make(map[string]string)
for i := 0; i < len(params.Data.DbNodeSelector); i++ {
if params.Data.DbNodeSelector[i] != nil {
dbNodeSelector[params.Data.DbNodeSelector[i].Key] = params.Data.DbNodeSelector[i].Value
@@ -1568,7 +1571,7 @@ func setTenantLogsResponse(session *models.Principal, params operator_api.SetTen
}
if modified {
if minTenant.Spec.Log.Db == nil {
//Default class name for Log search
// Default class name for Log search
diskSpaceFromAPI := int64(5) * humanize.GiByte // Default is 5Gi
logSearchStorageClass := "standard"
@@ -1618,7 +1621,6 @@ func setTenantLogsResponse(session *models.Principal, params operator_api.SetTen
// enableTenantLoggingResponse enables Tenant Logging
func enableTenantLoggingResponse(session *models.Principal, params operator_api.EnableTenantLoggingParams) (bool, *models.Error) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
@@ -1637,7 +1639,7 @@ func enableTenantLoggingResponse(session *models.Principal, params operator_api.
}
minTenant.EnsureDefaults()
//Default class name for Log search
// Default class name for Log search
diskSpaceFromAPI := int64(5) * humanize.GiByte // Default is 5Gi
logSearchStorageClass := "standard"
@@ -1679,7 +1681,6 @@ func enableTenantLoggingResponse(session *models.Principal, params operator_api.
// disableTenantLoggingResponse disables Tenant Logging
func disableTenantLoggingResponse(session *models.Principal, params operator_api.DisableTenantLoggingParams) (bool, *models.Error) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
@@ -1739,7 +1740,8 @@ func getTenantPodsResponse(session *models.Principal, params operator_api.GetTen
TimeCreated: pod.CreationTimestamp.Unix(),
PodIP: pod.Status.PodIP,
Restarts: restarts,
Node: pod.Spec.NodeName})
Node: pod.Spec.NodeName,
})
}
return retval, nil
}
@@ -1791,7 +1793,293 @@ func getPodEventsResponse(session *models.Principal, params operator_api.GetPodE
return retval, nil
}
//get values for prometheus metrics
func getDescribePodResponse(session *models.Principal, params operator_api.DescribePodParams) (*models.DescribePodWrapper, *models.Error) {
ctx := context.Background()
clientset, err := cluster.K8sClient(session.STSSessionToken)
if err != nil {
return nil, restapi.ErrorWithContext(ctx, err)
}
pod, err := clientset.CoreV1().Pods(params.Namespace).Get(ctx, params.PodName, metav1.GetOptions{})
if err != nil {
return nil, restapi.ErrorWithContext(ctx, err)
}
retval := &models.DescribePodWrapper{
Name: pod.Name,
Namespace: pod.Namespace,
PriorityClassName: pod.Spec.PriorityClassName,
NodeName: pod.Spec.NodeName,
}
if pod.Spec.Priority != nil {
retval.Priority = int64(*pod.Spec.Priority)
}
if pod.Status.StartTime != nil {
retval.StartTime = pod.Status.StartTime.Time.String()
}
labelArray := make([]*models.Label, len(pod.Labels))
i := 0
for key := range pod.Labels {
labelArray[i] = &models.Label{Key: key, Value: pod.Labels[key]}
i++
}
retval.Labels = labelArray
annotationArray := make([]*models.Annotation, len(pod.Annotations))
i = 0
for key := range pod.Annotations {
annotationArray[i] = &models.Annotation{Key: key, Value: pod.Annotations[key]}
i++
}
retval.Annotations = annotationArray
if pod.DeletionTimestamp != nil {
retval.DeletionTimestamp = translateTimestampSince(*pod.DeletionTimestamp)
retval.DeletionGracePeriodSeconds = *pod.DeletionGracePeriodSeconds
}
retval.Phase = string(pod.Status.Phase)
retval.Reason = pod.Status.Reason
retval.Message = pod.Status.Message
retval.PodIP = pod.Status.PodIP
retval.ControllerRef = metav1.GetControllerOf(pod).String()
retval.Containers = make([]*models.Container, len(pod.Spec.Containers))
statusMap := map[string]corev1.ContainerStatus{}
statusKeys := make([]string, len(pod.Status.ContainerStatuses))
for i, status := range pod.Status.ContainerStatuses {
statusMap[status.Name] = status
statusKeys[i] = status.Name
}
for i := range pod.Spec.Containers {
retval.Containers[i] = &models.Container{
Name: pod.Spec.Containers[i].Name,
Image: pod.Spec.Containers[i].Image,
Ports: describeContainerPorts(pod.Spec.Containers[i].Ports),
HostPorts: describeContainerHostPorts(pod.Spec.Containers[i].Ports),
Args: pod.Spec.Containers[i].Args,
}
if slices.Contains(statusKeys, pod.Spec.Containers[i].Name) {
retval.Containers[i].ContainerID = statusMap[pod.Spec.Containers[i].Name].ContainerID
retval.Containers[i].ImageID = statusMap[pod.Spec.Containers[i].Name].ImageID
retval.Containers[i].Ready = statusMap[pod.Spec.Containers[i].Name].Ready
retval.Containers[i].RestartCount = int64(statusMap[pod.Spec.Containers[i].Name].RestartCount)
retval.Containers[i].State, retval.Containers[i].LastState = describeStatus(statusMap[pod.Spec.Containers[i].Name])
}
retval.Containers[i].EnvironmentVariables = make([]*models.EnvironmentVariable, len(pod.Spec.Containers[0].Env))
for j := range pod.Spec.Containers[i].Env {
retval.Containers[i].EnvironmentVariables[j] = &models.EnvironmentVariable{
Key: pod.Spec.Containers[i].Env[j].Name,
Value: pod.Spec.Containers[i].Env[j].Value,
}
}
retval.Containers[i].Mounts = make([]*models.Mount, len(pod.Spec.Containers[i].VolumeMounts))
for j := range pod.Spec.Containers[i].VolumeMounts {
retval.Containers[i].Mounts[j] = &models.Mount{
Name: pod.Spec.Containers[i].VolumeMounts[j].Name,
MountPath: pod.Spec.Containers[i].VolumeMounts[j].MountPath,
SubPath: pod.Spec.Containers[i].VolumeMounts[j].SubPath,
ReadOnly: pod.Spec.Containers[i].VolumeMounts[j].ReadOnly,
}
}
}
retval.Conditions = make([]*models.Condition, len(pod.Status.Conditions))
for i := range pod.Status.Conditions {
retval.Conditions[i] = &models.Condition{
Type: string(pod.Status.Conditions[i].Type),
Status: string(pod.Status.Conditions[i].Status),
}
}
retval.Volumes = make([]*models.Volume, len(pod.Spec.Volumes))
for i := range pod.Spec.Volumes {
retval.Volumes[i] = &models.Volume{
Name: pod.Spec.Volumes[i].Name,
}
if pod.Spec.Volumes[i].PersistentVolumeClaim != nil {
retval.Volumes[i].Pvc = &models.Pvc{
ReadOnly: pod.Spec.Volumes[i].PersistentVolumeClaim.ReadOnly,
ClaimName: pod.Spec.Volumes[i].PersistentVolumeClaim.ClaimName,
}
} else if pod.Spec.Volumes[i].Projected != nil {
retval.Volumes[i].Projected = &models.ProjectedVolume{}
retval.Volumes[i].Projected.Sources = make([]*models.ProjectedVolumeSource, len(pod.Spec.Volumes[i].Projected.Sources))
for j := range pod.Spec.Volumes[i].Projected.Sources {
retval.Volumes[i].Projected.Sources[j] = &models.ProjectedVolumeSource{}
if pod.Spec.Volumes[i].Projected.Sources[j].Secret != nil {
retval.Volumes[i].Projected.Sources[j].Secret = &models.Secret{
Name: pod.Spec.Volumes[i].Projected.Sources[j].Secret.Name,
Optional: pod.Spec.Volumes[i].Projected.Sources[j].Secret.Optional != nil,
}
}
if pod.Spec.Volumes[i].Projected.Sources[j].DownwardAPI != nil {
retval.Volumes[i].Projected.Sources[j].DownwardAPI = true
}
if pod.Spec.Volumes[i].Projected.Sources[j].ConfigMap != nil {
retval.Volumes[i].Projected.Sources[j].ConfigMap = &models.ConfigMap{
Name: pod.Spec.Volumes[i].Projected.Sources[j].ConfigMap.Name,
Optional: pod.Spec.Volumes[i].Projected.Sources[j].ConfigMap.Optional != nil,
}
}
if pod.Spec.Volumes[i].Projected.Sources[j].ServiceAccountToken != nil {
retval.Volumes[i].Projected.Sources[j].ServiceAccountToken = &models.ServiceAccountToken{ExpirationSeconds: *pod.Spec.Volumes[i].Projected.Sources[j].ServiceAccountToken.ExpirationSeconds}
}
}
}
}
retval.QosClass = string(getPodQOS(pod))
nodeSelectorArray := make([]*models.NodeSelector, len(pod.Spec.NodeSelector))
i = 0
for key := range pod.Spec.NodeSelector {
nodeSelectorArray[i] = &models.NodeSelector{Key: key, Value: pod.Spec.NodeSelector[key]}
i++
}
retval.NodeSelector = nodeSelectorArray
retval.Tolerations = make([]*models.Toleration, len(pod.Spec.Tolerations))
for i := range pod.Spec.Tolerations {
retval.Tolerations[i] = &models.Toleration{
Effect: string(pod.Spec.Tolerations[i].Effect),
Key: pod.Spec.Tolerations[i].Key,
Value: pod.Spec.Tolerations[i].Value,
Operator: string(pod.Spec.Tolerations[i].Operator),
TolerationSeconds: *pod.Spec.Tolerations[i].TolerationSeconds,
}
}
return retval, nil
}
func describeStatus(status corev1.ContainerStatus) (*models.State, *models.State) {
retval := &models.State{}
last := &models.State{}
state := status.State
lastState := status.LastTerminationState
switch {
case state.Running != nil:
retval.State = "Running"
retval.Started = state.Running.StartedAt.Time.Format(time.RFC1123Z)
case state.Waiting != nil:
retval.State = "Waiting"
retval.Reason = state.Waiting.Reason
case state.Terminated != nil:
retval.State = "Terminated"
retval.Message = state.Terminated.Message
retval.ExitCode = int64(state.Terminated.ExitCode)
retval.Signal = int64(state.Terminated.Signal)
retval.Started = state.Terminated.StartedAt.Time.Format(time.RFC1123Z)
retval.Finished = state.Terminated.FinishedAt.Time.Format(time.RFC1123Z)
switch {
case lastState.Running != nil:
last.State = "Running"
last.Started = lastState.Running.StartedAt.Time.Format(time.RFC1123Z)
case lastState.Waiting != nil:
last.State = "Waiting"
last.Reason = lastState.Waiting.Reason
case lastState.Terminated != nil:
last.State = "Terminated"
last.Message = lastState.Terminated.Message
last.ExitCode = int64(lastState.Terminated.ExitCode)
last.Signal = int64(lastState.Terminated.Signal)
last.Started = lastState.Terminated.StartedAt.Time.Format(time.RFC1123Z)
last.Finished = lastState.Terminated.FinishedAt.Time.Format(time.RFC1123Z)
default:
last.State = "Waiting"
}
default:
retval.State = "Waiting"
}
return retval, last
}
func describeContainerPorts(cPorts []corev1.ContainerPort) []string {
ports := make([]string, 0, len(cPorts))
for _, cPort := range cPorts {
ports = append(ports, fmt.Sprintf("%d/%s", cPort.ContainerPort, cPort.Protocol))
}
return ports
}
func describeContainerHostPorts(cPorts []corev1.ContainerPort) []string {
ports := make([]string, 0, len(cPorts))
for _, cPort := range cPorts {
ports = append(ports, fmt.Sprintf("%d/%s", cPort.HostPort, cPort.Protocol))
}
return ports
}
func getPodQOS(pod *corev1.Pod) corev1.PodQOSClass {
requests := corev1.ResourceList{}
limits := corev1.ResourceList{}
zeroQuantity := resource.MustParse("0")
isGuaranteed := true
allContainers := []corev1.Container{}
allContainers = append(allContainers, pod.Spec.Containers...)
allContainers = append(allContainers, pod.Spec.InitContainers...)
for _, container := range allContainers {
// process requests
for name, quantity := range container.Resources.Requests {
if !isSupportedQoSComputeResource(name) {
continue
}
if quantity.Cmp(zeroQuantity) == 1 {
delta := quantity.DeepCopy()
if _, exists := requests[name]; !exists {
requests[name] = delta
} else {
delta.Add(requests[name])
requests[name] = delta
}
}
}
// process limits
qosLimitsFound := sets.NewString()
for name, quantity := range container.Resources.Limits {
if !isSupportedQoSComputeResource(name) {
continue
}
if quantity.Cmp(zeroQuantity) == 1 {
qosLimitsFound.Insert(string(name))
delta := quantity.DeepCopy()
if _, exists := limits[name]; !exists {
limits[name] = delta
} else {
delta.Add(limits[name])
limits[name] = delta
}
}
}
if !qosLimitsFound.HasAll(string(corev1.ResourceMemory), string(corev1.ResourceCPU)) {
isGuaranteed = false
}
}
if len(requests) == 0 && len(limits) == 0 {
return corev1.PodQOSBestEffort
}
// Check is requests match limits for all resources.
if isGuaranteed {
for name, req := range requests {
if lim, exists := limits[name]; !exists || lim.Cmp(req) != 0 {
isGuaranteed = false
break
}
}
}
if isGuaranteed &&
len(requests) == len(limits) {
return corev1.PodQOSGuaranteed
}
return corev1.PodQOSBurstable
}
var supportedQoSComputeResources = sets.NewString(string(corev1.ResourceCPU), string(corev1.ResourceMemory))
func isSupportedQoSComputeResource(name corev1.ResourceName) bool {
return supportedQoSComputeResources.Has(string(name))
}
func translateTimestampSince(timestamp metav1.Time) string {
if timestamp.IsZero() {
return "<unknown>"
}
return duration.HumanDuration(time.Since(timestamp.Time))
}
// get values for prometheus metrics
func getTenantMonitoringResponse(session *models.Principal, params operator_api.GetTenantMonitoringParams) (*models.TenantMonitoringInfo, *models.Error) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
@@ -1882,12 +2170,10 @@ func getTenantMonitoringResponse(session *models.Principal, params operator_api.
}
return monitoringInfo, nil
}
//sets tenant Prometheus monitoring cofiguration fields to values provided
// sets tenant Prometheus monitoring cofiguration fields to values provided
func setTenantMonitoringResponse(session *models.Principal, params operator_api.SetTenantMonitoringParams) (bool, *models.Error) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
@@ -1923,19 +2209,19 @@ func setTenantMonitoringResponse(session *models.Principal, params operator_api.
return true, nil
}
var labels = make(map[string]string)
labels := make(map[string]string)
for i := 0; i < len(params.Data.Labels); i++ {
if params.Data.Labels[i] != nil {
labels[params.Data.Labels[i].Key] = params.Data.Labels[i].Value
}
}
var annotations = make(map[string]string)
annotations := make(map[string]string)
for i := 0; i < len(params.Data.Annotations); i++ {
if params.Data.Annotations[i] != nil {
annotations[params.Data.Annotations[i].Key] = params.Data.Annotations[i].Value
}
}
var nodeSelector = make(map[string]string)
nodeSelector := make(map[string]string)
for i := 0; i < len(params.Data.NodeSelector); i++ {
if params.Data.NodeSelector[i] != nil {
nodeSelector[params.Data.NodeSelector[i].Key] = params.Data.NodeSelector[i].Value
@@ -1983,7 +2269,6 @@ func setTenantMonitoringResponse(session *models.Principal, params operator_api.
}
return true, nil
}
// parseTenantPoolRequest parse pool request and returns the equivalent
@@ -2454,8 +2739,8 @@ func updateTenantPools(
operatorClient OperatorClientI,
namespace string,
tenantName string,
poolsReq []*models.Pool) (*miniov2.Tenant, error) {
poolsReq []*models.Pool,
) (*miniov2.Tenant, error) {
minInst, err := operatorClient.TenantGet(ctx, namespace, tenantName, metav1.GetOptions{})
if err != nil {
return nil, err
@@ -2502,7 +2787,7 @@ func getTenantYAML(session *models.Principal, params operator_api.GetTenantYAMLP
}
// remove managed fields
tenant.ManagedFields = []metav1.ManagedFieldsEntry{}
//yb, err := yaml.Marshal(tenant)
// yb, err := yaml.Marshal(tenant)
j8sJSONSerializer := k8sJson.NewSerializerWithOptions(
k8sJson.DefaultMetaFactory, nil, nil,
k8sJson.SerializerOptions{
@@ -2623,7 +2908,6 @@ func getUpdateDomainsResponse(session *models.Principal, params operator_api.Upd
}
func updateTenantDomains(ctx context.Context, operatorClient OperatorClientI, namespace string, tenantName string, domainConfig *models.DomainsConfiguration) error {
minTenant, err := getTenant(ctx, operatorClient, namespace, tenantName)
if err != nil {
return err

View File

@@ -23,6 +23,7 @@ import (
"encoding/base64"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"strconv"
"time"
@@ -31,8 +32,6 @@ import (
"github.com/minio/console/operatorapi/operations/operator_api"
"errors"
"github.com/minio/console/cluster"
"github.com/minio/console/models"
"github.com/minio/console/pkg/kes"
@@ -429,7 +428,6 @@ func tenantEncryptionInfo(ctx context.Context, operatorClient OperatorClientI, c
}
}
}
}
}
encryptConfig.Gemalto = gemaltoConfig
@@ -688,13 +686,14 @@ func createOrReplaceKesConfigurationSecrets(ctx context.Context, clientSet K8sCl
}
// miniov2 will mount the mTLSCertificates in the following paths
// therefore we set these values in the KES yaml kesConfiguration
var mTLSClientCrtPath = "/tmp/kes/client.crt"
var mTLSClientKeyPath = "/tmp/kes/client.key"
var mTLSClientCaPath = "/tmp/kes/ca.crt"
mTLSClientCrtPath := "/tmp/kes/client.crt"
mTLSClientKeyPath := "/tmp/kes/client.key"
mTLSClientCaPath := "/tmp/kes/ca.crt"
// map to hold mTLSCertificates for KES mTLS against Vault
mTLSCertificates := map[string][]byte{}
// if encryption is enabled and encryption is configured to use Vault
if encryptionCfg.Vault != nil {
switch {
case encryptionCfg.Vault != nil:
ping := 10 // default ping
if encryptionCfg.Vault.Status != nil {
ping = int(encryptionCfg.Vault.Status.Ping)
@@ -750,7 +749,7 @@ func createOrReplaceKesConfigurationSecrets(ctx context.Context, clientSet K8sCl
kesConfig.Keys.Vault.TLS.CAPath = mTLSClientCaPath
}
}
} else if encryptionCfg.Aws != nil {
case encryptionCfg.Aws != nil:
// Initialize AWS
kesConfig.Keys.Aws = &kes.Aws{
SecretsManager: &kes.AwsSecretManager{},
@@ -769,7 +768,7 @@ func createOrReplaceKesConfigurationSecrets(ctx context.Context, clientSet K8sCl
}
}
}
} else if encryptionCfg.Gemalto != nil {
case encryptionCfg.Gemalto != nil:
// Initialize Gemalto
kesConfig.Keys.Gemalto = &kes.Gemalto{
KeySecure: &kes.GemaltoKeySecure{},
@@ -799,7 +798,7 @@ func createOrReplaceKesConfigurationSecrets(ctx context.Context, clientSet K8sCl
}
}
}
} else if encryptionCfg.Gcp != nil {
case encryptionCfg.Gcp != nil:
// Initialize GCP
kesConfig.Keys.Gcp = &kes.Gcp{
SecretManager: &kes.GcpSecretManager{},
@@ -818,7 +817,7 @@ func createOrReplaceKesConfigurationSecrets(ctx context.Context, clientSet K8sCl
}
}
}
} else if encryptionCfg.Azure != nil {
case encryptionCfg.Azure != nil:
// Initialize Azure
kesConfig.Keys.Azure = &kes.Azure{
KeyVault: &kes.AzureKeyVault{},

View File

@@ -30,10 +30,12 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
var DeletePodCollectionMock func(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error
var DeleteSecretMock func(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error
var CreateSecretMock func(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.CreateOptions) (*v1.Secret, error)
var UpdateSecretMock func(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.UpdateOptions) (*v1.Secret, error)
var (
DeletePodCollectionMock func(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error
DeleteSecretMock func(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error
CreateSecretMock func(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.CreateOptions) (*v1.Secret, error)
UpdateSecretMock func(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.UpdateOptions) (*v1.Secret, error)
)
func (c k8sClientMock) deletePodCollection(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
return DeletePodCollectionMock(ctx, namespace, opts, listOpts)

View File

@@ -45,17 +45,21 @@ import (
"k8s.io/client-go/kubernetes/fake"
)
var opClientTenantDeleteMock func(ctx context.Context, namespace string, tenantName string, options metav1.DeleteOptions) error
var opClientTenantGetMock func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*miniov2.Tenant, error)
var opClientTenantPatchMock func(ctx context.Context, namespace string, tenantName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*miniov2.Tenant, error)
var opClientTenantUpdateMock func(ctx context.Context, tenant *miniov2.Tenant, opts metav1.UpdateOptions) (*miniov2.Tenant, error)
var (
opClientTenantDeleteMock func(ctx context.Context, namespace string, tenantName string, options metav1.DeleteOptions) error
opClientTenantGetMock func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*miniov2.Tenant, error)
opClientTenantPatchMock func(ctx context.Context, namespace string, tenantName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*miniov2.Tenant, error)
opClientTenantUpdateMock func(ctx context.Context, tenant *miniov2.Tenant, opts metav1.UpdateOptions) (*miniov2.Tenant, error)
)
var opClientTenantListMock func(ctx context.Context, namespace string, opts metav1.ListOptions) (*miniov2.TenantList, error)
var httpClientGetMock func(url string) (resp *http.Response, err error)
var httpClientPostMock func(url, contentType string, body io.Reader) (resp *http.Response, err error)
var httpClientDoMock func(req *http.Request) (*http.Response, error)
var k8sclientGetSecretMock func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error)
var k8sclientGetServiceMock func(ctx context.Context, namespace, serviceName string, opts metav1.GetOptions) (*corev1.Service, error)
var (
opClientTenantListMock func(ctx context.Context, namespace string, opts metav1.ListOptions) (*miniov2.TenantList, error)
httpClientGetMock func(url string) (resp *http.Response, err error)
httpClientPostMock func(url, contentType string, body io.Reader) (resp *http.Response, err error)
httpClientDoMock func(req *http.Request) (*http.Response, error)
k8sclientGetSecretMock func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error)
k8sclientGetServiceMock func(ctx context.Context, namespace, serviceName string, opts metav1.GetOptions) (*corev1.Service, error)
)
// mock function of TenantDelete()
func (ac opClientMock) TenantDelete(ctx context.Context, namespace string, tenantName string, options metav1.DeleteOptions) error {
@@ -758,7 +762,8 @@ func Test_TenantAddPool(t *testing.T) {
},
},
wantErr: false,
}, {
},
{
name: "Add pool, error size",
args: args{
ctx: context.Background(),

View File

@@ -49,7 +49,8 @@ func getVersionResponse(params user_api.CheckMinIOVersionParams) (*models.CheckO
ver, err := utils.GetLatestMinIOImage(&xhttp.Client{
Client: &http.Client{
Timeout: 15 * time.Second,
}})
},
})
if err != nil {
return nil, errors.ErrorWithContext(ctx, err)
}

View File

@@ -36,7 +36,6 @@ import (
func registerVolumesHandlers(api *operations.OperatorAPI) {
api.OperatorAPIListPVCsHandler = operator_api.ListPVCsHandlerFunc(func(params operator_api.ListPVCsParams, session *models.Principal) middleware.Responder {
payload, err := getPVCsResponse(session, params)
if err != nil {
return operator_api.NewListPVCsDefault(int(err.Code)).WithPayload(err)
}
@@ -46,7 +45,6 @@ func registerVolumesHandlers(api *operations.OperatorAPI) {
api.OperatorAPIListPVCsForTenantHandler = operator_api.ListPVCsForTenantHandlerFunc(func(params operator_api.ListPVCsForTenantParams, session *models.Principal) middleware.Responder {
payload, err := getPVCsForTenantResponse(session, params)
if err != nil {
return operator_api.NewListPVCsForTenantDefault(int(err.Code)).WithPayload(err)
}
@@ -54,6 +52,15 @@ func registerVolumesHandlers(api *operations.OperatorAPI) {
return operator_api.NewListPVCsForTenantOK().WithPayload(payload)
})
api.OperatorAPIListTenantCertificateSigningRequestHandler = operator_api.ListTenantCertificateSigningRequestHandlerFunc(func(params operator_api.ListTenantCertificateSigningRequestParams, session *models.Principal) middleware.Responder {
payload, err := getTenantCSResponse(session, params)
if err != nil {
return operator_api.NewListTenantCertificateSigningRequestDefault(int(err.Code)).WithPayload(err)
}
return operator_api.NewListTenantCertificateSigningRequestOK().WithPayload(payload)
})
api.OperatorAPIDeletePVCHandler = operator_api.DeletePVCHandlerFunc(func(params operator_api.DeletePVCParams, session *models.Principal) middleware.Responder {
err := getDeletePVCResponse(session, params)
if err != nil {
@@ -64,7 +71,6 @@ func registerVolumesHandlers(api *operations.OperatorAPI) {
api.OperatorAPIGetPVCEventsHandler = operator_api.GetPVCEventsHandlerFunc(func(params operator_api.GetPVCEventsParams, session *models.Principal) middleware.Responder {
payload, err := getPVCEventsResponse(session, params)
if err != nil {
return operator_api.NewGetPVCEventsDefault(int(err.Code)).WithPayload(err)
}
@@ -72,13 +78,19 @@ func registerVolumesHandlers(api *operations.OperatorAPI) {
return operator_api.NewGetPVCEventsOK().WithPayload(payload)
})
api.OperatorAPIGetPVCDescribeHandler = operator_api.GetPVCDescribeHandlerFunc(func(params operator_api.GetPVCDescribeParams, session *models.Principal) middleware.Responder {
payload, err := getPVCDescribeResponse(session, params)
if err != nil {
return operator_api.NewGetPVCDescribeDefault(int(err.Code)).WithPayload(err)
}
return operator_api.NewGetPVCDescribeOK().WithPayload(payload)
})
}
func getPVCsResponse(session *models.Principal, params operator_api.ListPVCsParams) (*models.ListPVCsResponse, *models.Error) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
clientset, err := cluster.K8sClient(session.STSSessionToken)
if err != nil {
return nil, errors.ErrorWithContext(ctx, err)
}
@@ -126,7 +138,6 @@ func getPVCsForTenantResponse(session *models.Principal, params operator_api.Lis
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
clientset, err := cluster.K8sClient(session.STSSessionToken)
if err != nil {
return nil, errors.ErrorWithContext(ctx, err)
}
@@ -218,3 +229,86 @@ func getPVCEventsResponse(session *models.Principal, params operator_api.GetPVCE
})
return retval, nil
}
func getTenantCSResponse(session *models.Principal, params operator_api.ListTenantCertificateSigningRequestParams) (*models.CsrElement, *models.Error) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
clientset, err := cluster.K8sClient(session.STSSessionToken)
if err != nil {
return nil, errors.ErrorWithContext(ctx, err)
}
csrName := params.Tenant + "-" + params.Namespace + "-csr"
csrResult, csrError := clientset.CertificatesV1().CertificateSigningRequests().Get(ctx, csrName, metav1.GetOptions{})
if csrError != nil {
return nil, errors.ErrorWithContext(ctx, err)
}
annotations := []*models.Annotation{}
for k, v := range csrResult.ObjectMeta.Annotations {
annotations = append(annotations, &models.Annotation{Key: k, Value: v})
}
var DeletionGracePeriodSeconds int64
DeletionGracePeriodSeconds = 0
if csrResult.ObjectMeta.DeletionGracePeriodSeconds != nil {
DeletionGracePeriodSeconds = *csrResult.ObjectMeta.DeletionGracePeriodSeconds
}
messages := ""
// A CSR.Status can contain multiple Conditions
for i := 0; i < len(csrResult.Status.Conditions); i++ {
messages = messages + " " + csrResult.Status.Conditions[i].Message
}
retval := &models.CsrElement{
Name: csrResult.ObjectMeta.Name,
Annotations: annotations,
DeletionGracePeriodSeconds: DeletionGracePeriodSeconds,
GenerateName: csrResult.ObjectMeta.GenerateName,
Generation: csrResult.ObjectMeta.Generation,
Namespace: csrResult.ObjectMeta.Namespace,
ResourceVersion: csrResult.ObjectMeta.ResourceVersion,
Status: messages,
}
return retval, nil
}
func getPVCDescribeResponse(session *models.Principal, params operator_api.GetPVCDescribeParams) (*models.DescribePVCWrapper, *models.Error) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
clientset, err := cluster.K8sClient(session.STSSessionToken)
if err != nil {
return nil, errors.ErrorWithContext(ctx, err)
}
pvc, err := clientset.CoreV1().PersistentVolumeClaims(params.Namespace).Get(ctx, params.PVCName, metav1.GetOptions{})
if err != nil {
return nil, errors.ErrorWithContext(ctx, err)
}
accessModes := []string{}
for _, a := range pvc.Status.AccessModes {
accessModes = append(accessModes, string(a))
}
return &models.DescribePVCWrapper{
Name: pvc.Name,
Namespace: pvc.Namespace,
StorageClass: *pvc.Spec.StorageClassName,
Status: string(pvc.Status.Phase),
Volume: pvc.Spec.VolumeName,
Labels: castLabels(pvc.Labels),
Annotations: castAnnotations(pvc.Annotations),
Finalizers: pvc.Finalizers,
Capacity: pvc.Status.Capacity.Storage().String(),
AccessModes: accessModes,
VolumeMode: string(*pvc.Spec.VolumeMode),
}, nil
}
func castLabels(labelsToCast map[string]string) (labels []*models.Label) {
for k, v := range labelsToCast {
labels = append(labels, &models.Label{Key: k, Value: v})
}
return labels
}
func castAnnotations(annotationsToCast map[string]string) (annotations []*models.Annotation) {
for k, v := range annotationsToCast {
annotations = append(annotations, &models.Annotation{Key: k, Value: v})
}
return annotations
}

View File

@@ -41,7 +41,7 @@ import (
type Configuration interface {
Exchange(ctx context.Context, code string, opts ...xoauth2.AuthCodeOption) (*xoauth2.Token, error)
AuthCodeURL(state string, opts ...xoauth2.AuthCodeOption) string
PasswordCredentialsToken(ctx context.Context, username string, password string) (*xoauth2.Token, error)
PasswordCredentialsToken(ctx context.Context, username, password string) (*xoauth2.Token, error)
Client(ctx context.Context, t *xoauth2.Token) *http.Client
TokenSource(ctx context.Context, t *xoauth2.Token) xoauth2.TokenSource
}
@@ -76,7 +76,7 @@ func (ac Config) AuthCodeURL(state string, opts ...xoauth2.AuthCodeOption) strin
return ac.AuthCodeURL(state, opts...)
}
func (ac Config) PasswordCredentialsToken(ctx context.Context, username string, password string) (*xoauth2.Token, error) {
func (ac Config) PasswordCredentialsToken(ctx context.Context, username, password string) (*xoauth2.Token, error) {
return ac.PasswordCredentialsToken(ctx, username, password)
}

View File

@@ -27,11 +27,13 @@ import (
type Oauth2configMock struct{}
var oauth2ConfigExchangeMock func(ctx context.Context, code string, opts ...oauth2.AuthCodeOption) (*oauth2.Token, error)
var oauth2ConfigAuthCodeURLMock func(state string, opts ...oauth2.AuthCodeOption) string
var oauth2ConfigPasswordCredentialsTokenMock func(ctx context.Context, username string, password string) (*oauth2.Token, error)
var oauth2ConfigClientMock func(ctx context.Context, t *oauth2.Token) *http.Client
var oauth2ConfigokenSourceMock func(ctx context.Context, t *oauth2.Token) oauth2.TokenSource
var (
oauth2ConfigExchangeMock func(ctx context.Context, code string, opts ...oauth2.AuthCodeOption) (*oauth2.Token, error)
oauth2ConfigAuthCodeURLMock func(state string, opts ...oauth2.AuthCodeOption) string
oauth2ConfigPasswordCredentialsTokenMock func(ctx context.Context, username, password string) (*oauth2.Token, error)
oauth2ConfigClientMock func(ctx context.Context, t *oauth2.Token) *http.Client
oauth2ConfigokenSourceMock func(ctx context.Context, t *oauth2.Token) oauth2.TokenSource
)
func (ac Oauth2configMock) Exchange(ctx context.Context, code string, opts ...oauth2.AuthCodeOption) (*oauth2.Token, error) {
return oauth2ConfigExchangeMock(ctx, code, opts...)
@@ -41,7 +43,7 @@ func (ac Oauth2configMock) AuthCodeURL(state string, opts ...oauth2.AuthCodeOpti
return oauth2ConfigAuthCodeURLMock(state, opts...)
}
func (ac Oauth2configMock) PasswordCredentialsToken(ctx context.Context, username string, password string) (*oauth2.Token, error) {
func (ac Oauth2configMock) PasswordCredentialsToken(ctx context.Context, username, password string) (*oauth2.Token, error) {
return oauth2ConfigPasswordCredentialsTokenMock(ctx, username, password)
}

View File

@@ -233,7 +233,7 @@ func encrypt(plaintext, associatedData []byte) ([]byte, error) {
// Decrypts a blob of data using AEAD scheme AES-GCM if the executing CPU
// provides AES hardware support, otherwise will use ChaCha20-Poly1305with
// and a pbkdf2 derived key
func decrypt(ciphertext []byte, associatedData []byte) ([]byte, error) {
func decrypt(ciphertext, associatedData []byte) ([]byte, error) {
var (
algorithm [1]byte
iv [16]byte
@@ -257,7 +257,7 @@ func decrypt(ciphertext []byte, associatedData []byte) ([]byte, error) {
mac := hmac.New(sha256.New, derivedKey())
mac.Write(iv[:])
sealingKey := mac.Sum(nil)
block, err := aes.NewCipher(sealingKey[:])
block, err := aes.NewCipher(sealingKey)
if err != nil {
return nil, err
}

View File

@@ -29,8 +29,11 @@ var creds = &credentials.Value{
SessionToken: "fakeSessionToken",
SignerType: 0,
}
var goodToken = ""
var badToken = "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoiRDMwYWE0ekQ1bWtFaFRyWm5yOWM3NWh0Yko0MkROOWNDZVQ5RHVHUkg1U25SR3RyTXZNOXBMdnlFSVJAAAE5eWxxekhYMXllck8xUXpzMlZzRVFKeUF2ZmpOaDkrTVdoUURWZ2FhK2R5emxzSjNpK0k1dUdoeW5DNWswUW83WEY0UWszY0RtUTdUQUVROVFEbWRKdjBkdVB5L25hQk5vM3dIdlRDZHFNRDJZN3kycktJbmVUbUlFNmVveW9EWmprcW5tckVoYmMrTlhTRU81WjZqa1kwZ1E2eXZLaWhUZGxBRS9zS1lBNlc4Q1R1cm1MU0E0b0dIcGtldFZWU0VXMHEzNU9TU1VaczRXNkxHdGMxSTFWVFZLWUo3ZTlHR2REQ3hMWGtiZHQwcjl0RDNMWUhWRndra0dSZit5ZHBzS1Y3L1Jtbkp3SHNqNVVGV0w5WGVHUkZVUjJQclJTN2plVzFXeGZuYitVeXoxNVpOMzZsZ01GNnBlWFd1LzJGcEtrb2Z2QzNpY2x5Rmp0SE45ZkxYTVpVSFhnV2lsQWVSa3oiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjkwMDAiLCJleHAiOjE1ODc1MTY1NzEsInN1YiI6ImZmYmY4YzljLTJlMjYtNGMwYS1iMmI0LTYyMmVhM2I1YjZhYiJ9.P392RUwzsrBeJOO3fS1xMZcF-lWiDvWZ5hM7LZOyFMmoG5QLccDU5eAPSm8obzPoznX1b7eCFLeEmKK-vKgjiQ"
var (
goodToken = ""
badToken = "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoiRDMwYWE0ekQ1bWtFaFRyWm5yOWM3NWh0Yko0MkROOWNDZVQ5RHVHUkg1U25SR3RyTXZNOXBMdnlFSVJAAAE5eWxxekhYMXllck8xUXpzMlZzRVFKeUF2ZmpOaDkrTVdoUURWZ2FhK2R5emxzSjNpK0k1dUdoeW5DNWswUW83WEY0UWszY0RtUTdUQUVROVFEbWRKdjBkdVB5L25hQk5vM3dIdlRDZHFNRDJZN3kycktJbmVUbUlFNmVveW9EWmprcW5tckVoYmMrTlhTRU81WjZqa1kwZ1E2eXZLaWhUZGxBRS9zS1lBNlc4Q1R1cm1MU0E0b0dIcGtldFZWU0VXMHEzNU9TU1VaczRXNkxHdGMxSTFWVFZLWUo3ZTlHR2REQ3hMWGtiZHQwcjl0RDNMWUhWRndra0dSZit5ZHBzS1Y3L1Jtbkp3SHNqNVVGV0w5WGVHUkZVUjJQclJTN2plVzFXeGZuYitVeXoxNVpOMzZsZ01GNnBlWFd1LzJGcEtrb2Z2QzNpY2x5Rmp0SE45ZkxYTVpVSFhnV2lsQWVSa3oiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjkwMDAiLCJleHAiOjE1ODc1MTY1NzEsInN1YiI6ImZmYmY4YzljLTJlMjYtNGMwYS1iMmI0LTYyMmVhM2I1YjZhYiJ9.P392RUwzsrBeJOO3fS1xMZcF-lWiDvWZ5hM7LZOyFMmoG5QLccDU5eAPSm8obzPoznX1b7eCFLeEmKK-vKgjiQ"
)
func TestNewJWTWithClaimsForClient(t *testing.T) {
funcAssert := assert.New(t)

View File

@@ -38,9 +38,9 @@ func TestRandomCharString(t *testing.T) {
func TestComputeHmac256(t *testing.T) {
funcAssert := assert.New(t)
// Test-1 : ComputeHmac256() should return the right Hmac256 string based on a derived key
var derivedKey = pbkdf2.Key([]byte("secret"), []byte("salt"), 4096, 32, sha1.New)
var message = "hello world"
var expectedHmac = "5r32q7W+0hcBnqzQwJJUDzVGoVivXGSodTcHSqG/9Q8="
derivedKey := pbkdf2.Key([]byte("secret"), []byte("salt"), 4096, 32, sha1.New)
message := "hello world"
expectedHmac := "5r32q7W+0hcBnqzQwJJUDzVGoVivXGSodTcHSqG/9Q8="
hmac := ComputeHmac256(message, derivedKey)
funcAssert.Equal(hmac, expectedHmac)
}

View File

@@ -119,7 +119,7 @@ func ParsePublicCertFile(certFile string) (x509Certs []*x509.Certificate, err er
// MkdirAllIgnorePerm attempts to create all directories, ignores any permission denied errors.
func MkdirAllIgnorePerm(path string) error {
err := os.MkdirAll(path, 0700)
err := os.MkdirAll(path, 0o700)
if err != nil {
// It is possible in kubernetes like deployments this directory
// is already mounted and is not writable, ignore any write errors.
@@ -250,7 +250,7 @@ func GetTLSConfig() (x509Certs []*x509.Certificate, manager *xcerts.Manager, err
return nil, nil, err
}
//Console has support for multiple certificates. It expects the following structure:
// Console has support for multiple certificates. It expects the following structure:
// certs/
// │
// ├─ public.crt
@@ -266,8 +266,8 @@ func GetTLSConfig() (x509Certs []*x509.Certificate, manager *xcerts.Manager, err
// └─ 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.
// 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 {

View File

@@ -144,7 +144,7 @@ func GetAuditEntry(ctx context.Context) *audit.Entry {
}
r = &audit.Entry{
Version: audit.Version,
//DeploymentID: globalDeploymentID,
// DeploymentID: globalDeploymentID,
Time: time.Now().UTC(),
}
SetAuditEntry(ctx, r)

View File

@@ -144,7 +144,7 @@ func uniqueEntries(paths []string) []string {
// and GOROOT directories. Also append github.com/minio/minio
// This is done to clean up the filename, when stack trace is
// displayed when an errors happens.
func Init(goPath string, goRoot string) {
func Init(goPath, goRoot string) {
var goPathList []string
var goRootList []string
var defaultgoPathList []string

View File

@@ -59,7 +59,6 @@ func TestNewEntry(t *testing.T) {
}
func TestToEntry(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/api/v1/tenants?test=xyz", nil)
req.Header.Set("Authorization", "xyz")
req.Header.Set("ETag", "\"ABCDE\"")
@@ -91,7 +90,6 @@ func TestToEntry(t *testing.T) {
},
postFunc: func() {
os.Unsetenv("CONSOLE_OPERATOR_MODE")
},
name: "constructs an audit entry from a http request",
args: args{

View File

@@ -105,8 +105,7 @@ func (h *Target) Init() error {
xhttp.DrainBody(resp.Body)
if !acceptedResponseStatusCode(resp.StatusCode) {
switch resp.StatusCode {
case http.StatusForbidden:
if resp.StatusCode == http.StatusForbidden {
return fmt.Errorf("%s returned '%s', please check if your auth token is correctly set",
h.config.Endpoint, resp.Status)
}

View File

@@ -34,7 +34,6 @@ mr/cKCUyBL7rcAvg0zNq1vcSrUSGlAmY3SEDCu3GOKnjG/U4E7+p957ocWSV+mQU
)
func TestGetLicenseInfoFromJWT(t *testing.T) {
mockLicense, _ := GetLicenseInfoFromJWT(license, publicKeys)
type args struct {

View File

@@ -16,15 +16,13 @@
package subnet
var (
OfflinePublicKeys = []string{
`-----BEGIN PUBLIC KEY-----
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

View File

@@ -56,7 +56,7 @@ var isValidSetSize = func(count uint64) bool {
// input argument patterns, the symmetry calculation is to ensure that
// we also use uniform number of drives common across all ellipses patterns.
func possibleSetCountsWithSymmetry(setCounts []uint64, argPatterns []ellipses.ArgPattern) []uint64 {
var newSetCounts = make(map[uint64]struct{})
newSetCounts := make(map[uint64]struct{})
for _, ss := range setCounts {
var symmetry bool
for _, argPattern := range argPatterns {
@@ -177,7 +177,7 @@ func getTotalSizes(argPatterns []ellipses.ArgPattern) []uint64 {
for _, argPattern := range argPatterns {
var totalSize uint64 = 1
for _, p := range argPattern {
totalSize = totalSize * uint64(len(p.Seq))
totalSize *= uint64(len(p.Seq))
}
totalSizes = append(totalSizes, totalSize)
}
@@ -206,7 +206,7 @@ func PossibleParityValues(args ...string) ([]string, error) {
// of endpoints following the ellipses pattern, this is what is used
// by the object layer for initializing itself.
func parseEndpointSet(args ...string) (setIndexes [][]uint64, err error) {
var argPatterns = make([]ellipses.ArgPattern, len(args))
argPatterns := make([]ellipses.ArgPattern, len(args))
for i, arg := range args {
patterns, err := ellipses.FindEllipsesPatterns(arg)
if err != nil {

View File

@@ -27,7 +27,8 @@ func TestGetDivisibleSize(t *testing.T) {
testCases := []struct {
totalSizes []uint64
result uint64
}{{[]uint64{24, 32, 16}, 8},
}{
{[]uint64{24, 32, 16}, 8},
{[]uint64{32, 8, 4}, 4},
{[]uint64{8, 8, 8}, 8},
{[]uint64{24}, 24},
@@ -143,7 +144,7 @@ func TestGetSetIndexes(t *testing.T) {
for _, testCase := range testCases {
testCase := testCase
t.Run("", func(t *testing.T) {
var argPatterns = make([]ellipses.ArgPattern, len(testCase.args))
argPatterns := make([]ellipses.ArgPattern, len(testCase.args))
for i, arg := range testCase.args {
patterns, err := ellipses.FindEllipsesPatterns(arg)
if err != nil {

View File

@@ -16,7 +16,11 @@
package utils
import "github.com/google/uuid"
import (
"encoding/base64"
"github.com/google/uuid"
)
// NewUUID - get a random UUID.
func NewUUID() (string, error) {
@@ -27,13 +31,24 @@ func NewUUID() (string, error) {
return u.String(), nil
}
// DecodeBase64 : decoded base64 input into utf-8 text
func DecodeBase64(s string) (string, error) {
decodedInput, err := base64.StdEncoding.DecodeString(s)
if err != nil {
return "", err
}
return string(decodedInput), nil
}
// Key used for Get/SetReqInfo
type key string
const ContextLogKey = key("console-log")
const ContextRequestID = key("request-id")
const ContextRequestUserID = key("request-user-id")
const ContextRequestUserAgent = key("request-user-agent")
const ContextRequestHost = key("request-host")
const ContextRequestRemoteAddr = key("request-remote-addr")
const ContextAuditKey = key("request-audit-entry")
const (
ContextLogKey = key("console-log")
ContextRequestID = key("request-id")
ContextRequestUserID = key("request-user-id")
ContextRequestUserAgent = key("request-user-agent")
ContextRequestHost = key("request-host")
ContextRequestRemoteAddr = key("request-remote-addr")
ContextAuditKey = key("request-audit-entry")
)

92
pkg/utils/utils_test.go Normal file
View File

@@ -0,0 +1,92 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 utils
import "testing"
func TestDecodeInput(t *testing.T) {
type args struct {
s string
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{
name: "chinese characters",
args: args{
s: "5bCP6aO85by+5bCP6aO85by+5bCP6aO85by+L+Wwj+mjvOW8vuWwj+mjvOW8vuWwj+mjvOW8vg==",
},
want: "小飼弾小飼弾小飼弾/小飼弾小飼弾小飼弾",
wantErr: false,
},
{
name: "spaces and & symbol",
args: args{
s: "YSBhIC0gYSBhICYgYSBhIC0gYSBhIGE=",
},
want: "a a - a a & a a - a a a",
wantErr: false,
},
{
name: "the infamous fly me to the moon",
args: args{
s: "MDIlMjAtJTIwRkxZJTIwTUUlMjBUTyUyMFRIRSUyME1PT04lMjA=",
},
want: "02%20-%20FLY%20ME%20TO%20THE%20MOON%20",
wantErr: false,
},
{
name: "random symbols",
args: args{
s: "IUAjJCVeJiooKV8r",
},
want: "!@#$%^&*()_+",
wantErr: false,
},
{
name: "name with / symbols",
args: args{
s: "dGVzdC90ZXN0Mi/lsI/po7zlvL7lsI/po7zlvL7lsI/po7zlvL4uanBn",
},
want: "test/test2/小飼弾小飼弾小飼弾.jpg",
wantErr: false,
},
{
name: "decoding fails",
args: args{
s: "this should fail",
},
want: "",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := DecodeBase64(tt.args.s)
if (err != nil) != tt.wantErr {
t.Errorf("DecodeBase64() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("DecodeBase64() got = %v, want %v", got, tt.want)
}
})
}
}

View File

@@ -25,9 +25,7 @@ import (
"github.com/minio/console/pkg/http"
)
var (
ErrCantDetermineMinIOImage = errors.New("can't determine MinIO Image")
)
var ErrCantDetermineMinIOImage = errors.New("can't determine MinIO Image")
// getLatestMinIOImage returns the latest docker image for MinIO if found on the internet
func GetLatestMinIOImage(client http.ClientI) (*string, error) {
@@ -41,7 +39,7 @@ func GetLatestMinIOImage(client http.ClientI) (*string, error) {
if err != nil {
return nil, err
}
var re = regexp.MustCompile(`minio\.(RELEASE.*?Z)"`)
re := regexp.MustCompile(`minio\.(RELEASE.*?Z)"`)
// look for a single match
matches := re.FindAllStringSubmatch(string(body), 1)
for i := range matches {

View File

@@ -1,303 +1,301 @@
{
"files": {
"main.css": "./static/css/main.90d417ae.css",
"main.js": "./static/js/main.eec275cb.js",
"static/js/2483.48dd183a.chunk.js": "./static/js/2483.48dd183a.chunk.js",
"main.js": "./static/js/main.55e03c75.js",
"static/js/2483.64c94bc6.chunk.js": "./static/js/2483.64c94bc6.chunk.js",
"static/js/6914.c9671304.chunk.js": "./static/js/6914.c9671304.chunk.js",
"static/js/4209.b2656735.chunk.js": "./static/js/4209.b2656735.chunk.js",
"static/js/1829.3a638c7d.chunk.js": "./static/js/1829.3a638c7d.chunk.js",
"static/js/4455.4ba90afa.chunk.js": "./static/js/4455.4ba90afa.chunk.js",
"static/js/5088.dae21c0f.chunk.js": "./static/js/5088.dae21c0f.chunk.js",
"static/js/4209.2b6438a1.chunk.js": "./static/js/4209.2b6438a1.chunk.js",
"static/js/1829.187799ba.chunk.js": "./static/js/1829.187799ba.chunk.js",
"static/js/4455.0849ed40.chunk.js": "./static/js/4455.0849ed40.chunk.js",
"static/js/5088.60f151ba.chunk.js": "./static/js/5088.60f151ba.chunk.js",
"static/js/5140.e9043b63.chunk.js": "./static/js/5140.e9043b63.chunk.js",
"static/js/5646.e4b3b3e9.chunk.js": "./static/js/5646.e4b3b3e9.chunk.js",
"static/js/5646.e760211f.chunk.js": "./static/js/5646.e760211f.chunk.js",
"static/js/3176.43953acc.chunk.js": "./static/js/3176.43953acc.chunk.js",
"static/js/6137.c0b24aaa.chunk.js": "./static/js/6137.c0b24aaa.chunk.js",
"static/js/6137.7c3483b1.chunk.js": "./static/js/6137.7c3483b1.chunk.js",
"static/js/7045.ca5a5aae.chunk.js": "./static/js/7045.ca5a5aae.chunk.js",
"static/js/9251.be8506b4.chunk.js": "./static/js/9251.be8506b4.chunk.js",
"static/js/2338.8d87570c.chunk.js": "./static/js/2338.8d87570c.chunk.js",
"static/js/4335.44360980.chunk.js": "./static/js/4335.44360980.chunk.js",
"static/js/3061.c71568b9.chunk.js": "./static/js/3061.c71568b9.chunk.js",
"static/js/6763.f0f3ae01.chunk.js": "./static/js/6763.f0f3ae01.chunk.js",
"static/js/3543.2a18a6b9.chunk.js": "./static/js/3543.2a18a6b9.chunk.js",
"static/js/4061.44b5ee07.chunk.js": "./static/js/4061.44b5ee07.chunk.js",
"static/js/2249.eff0718f.chunk.js": "./static/js/2249.eff0718f.chunk.js",
"static/js/9251.43d5879d.chunk.js": "./static/js/9251.43d5879d.chunk.js",
"static/js/2338.8430dcc6.chunk.js": "./static/js/2338.8430dcc6.chunk.js",
"static/js/4335.efdb7b8f.chunk.js": "./static/js/4335.efdb7b8f.chunk.js",
"static/js/3061.6f255655.chunk.js": "./static/js/3061.6f255655.chunk.js",
"static/js/6763.8e2c073b.chunk.js": "./static/js/6763.8e2c073b.chunk.js",
"static/js/3543.448be99d.chunk.js": "./static/js/3543.448be99d.chunk.js",
"static/js/4061.f26c1196.chunk.js": "./static/js/4061.f26c1196.chunk.js",
"static/js/2249.69729722.chunk.js": "./static/js/2249.69729722.chunk.js",
"static/js/9611.c217768e.chunk.js": "./static/js/9611.c217768e.chunk.js",
"static/js/2637.6d2abbec.chunk.js": "./static/js/2637.6d2abbec.chunk.js",
"static/css/380.8313f811.chunk.css": "./static/css/380.8313f811.chunk.css",
"static/js/380.78d0d6a2.chunk.js": "./static/js/380.78d0d6a2.chunk.js",
"static/js/5926.4b729c3b.chunk.js": "./static/js/5926.4b729c3b.chunk.js",
"static/js/701.52180c55.chunk.js": "./static/js/701.52180c55.chunk.js",
"static/js/7821.a2c85c06.chunk.js": "./static/js/7821.a2c85c06.chunk.js",
"static/css/2080.8313f811.chunk.css": "./static/css/2080.8313f811.chunk.css",
"static/js/2080.5b870317.chunk.js": "./static/js/2080.5b870317.chunk.js",
"static/js/6747.a78bbd22.chunk.js": "./static/js/6747.a78bbd22.chunk.js",
"static/css/9033.8313f811.chunk.css": "./static/css/9033.8313f811.chunk.css",
"static/js/9033.b95c6d4a.chunk.js": "./static/js/9033.b95c6d4a.chunk.js",
"static/css/3368.8313f811.chunk.css": "./static/css/3368.8313f811.chunk.css",
"static/js/3368.27a61e61.chunk.js": "./static/js/3368.27a61e61.chunk.js",
"static/css/3688.8313f811.chunk.css": "./static/css/3688.8313f811.chunk.css",
"static/js/3688.fa756e3b.chunk.js": "./static/js/3688.fa756e3b.chunk.js",
"static/js/2555.cd5bfa20.chunk.js": "./static/js/2555.cd5bfa20.chunk.js",
"static/js/7585.78d525ce.chunk.js": "./static/js/7585.78d525ce.chunk.js",
"static/js/1836.86b53328.chunk.js": "./static/js/1836.86b53328.chunk.js",
"static/js/4653.89f5d861.chunk.js": "./static/js/4653.89f5d861.chunk.js",
"static/js/4219.c24a76ef.chunk.js": "./static/js/4219.c24a76ef.chunk.js",
"static/js/8626.896fa8ac.chunk.js": "./static/js/8626.896fa8ac.chunk.js",
"static/js/736.40b3a390.chunk.js": "./static/js/736.40b3a390.chunk.js",
"static/js/6577.d48f6fc0.chunk.js": "./static/js/6577.d48f6fc0.chunk.js",
"static/js/9561.46bb02ad.chunk.js": "./static/js/9561.46bb02ad.chunk.js",
"static/js/4394.05e77f06.chunk.js": "./static/js/4394.05e77f06.chunk.js",
"static/js/4781.785d14ba.chunk.js": "./static/js/4781.785d14ba.chunk.js",
"static/js/9478.7c40d91e.chunk.js": "./static/js/9478.7c40d91e.chunk.js",
"static/js/7164.5542a849.chunk.js": "./static/js/7164.5542a849.chunk.js",
"static/js/4414.d9f98702.chunk.js": "./static/js/4414.d9f98702.chunk.js",
"static/js/7798.07093714.chunk.js": "./static/js/7798.07093714.chunk.js",
"static/js/8833.60296031.chunk.js": "./static/js/8833.60296031.chunk.js",
"static/js/471.244e997d.chunk.js": "./static/js/471.244e997d.chunk.js",
"static/js/483.a8ef0ad5.chunk.js": "./static/js/483.a8ef0ad5.chunk.js",
"static/js/9467.5fb2ba42.chunk.js": "./static/js/9467.5fb2ba42.chunk.js",
"static/js/6895.10b5757c.chunk.js": "./static/js/6895.10b5757c.chunk.js",
"static/js/6233.c0a85e71.chunk.js": "./static/js/6233.c0a85e71.chunk.js",
"static/js/5588.fa4e23ec.chunk.js": "./static/js/5588.fa4e23ec.chunk.js",
"static/js/4133.1b71a3ec.chunk.js": "./static/js/4133.1b71a3ec.chunk.js",
"static/css/1955.8313f811.chunk.css": "./static/css/1955.8313f811.chunk.css",
"static/js/1955.fcaedc3e.chunk.js": "./static/js/1955.fcaedc3e.chunk.js",
"static/js/3956.0b36ab08.chunk.js": "./static/js/3956.0b36ab08.chunk.js",
"static/js/8771.475684ba.chunk.js": "./static/js/8771.475684ba.chunk.js",
"static/js/9076.a6606f2e.chunk.js": "./static/js/9076.a6606f2e.chunk.js",
"static/js/9221.ba80075c.chunk.js": "./static/js/9221.ba80075c.chunk.js",
"static/js/8896.09fd2a0c.chunk.js": "./static/js/8896.09fd2a0c.chunk.js",
"static/js/7413.73b72a2b.chunk.js": "./static/js/7413.73b72a2b.chunk.js",
"static/js/9134.b0935ef3.chunk.js": "./static/js/9134.b0935ef3.chunk.js",
"static/css/8138.8313f811.chunk.css": "./static/css/8138.8313f811.chunk.css",
"static/js/8138.e9fa48a9.chunk.js": "./static/js/8138.e9fa48a9.chunk.js",
"static/js/1030.4a654568.chunk.js": "./static/js/1030.4a654568.chunk.js",
"static/js/9145.363b2352.chunk.js": "./static/js/9145.363b2352.chunk.js",
"static/js/1379.0bfc0b60.chunk.js": "./static/js/1379.0bfc0b60.chunk.js",
"static/js/1501.c46671fd.chunk.js": "./static/js/1501.c46671fd.chunk.js",
"static/js/9605.c3d4a4cf.chunk.js": "./static/js/9605.c3d4a4cf.chunk.js",
"static/js/426.e738683c.chunk.js": "./static/js/426.e738683c.chunk.js",
"static/js/2878.fca6e2cf.chunk.js": "./static/js/2878.fca6e2cf.chunk.js",
"static/js/8495.bdd215dc.chunk.js": "./static/js/8495.bdd215dc.chunk.js",
"static/js/4934.4a573b0b.chunk.js": "./static/js/4934.4a573b0b.chunk.js",
"static/js/3518.e1923a22.chunk.js": "./static/js/3518.e1923a22.chunk.js",
"static/js/7021.ea551e6b.chunk.js": "./static/js/7021.ea551e6b.chunk.js",
"static/js/2684.569c8172.chunk.js": "./static/js/2684.569c8172.chunk.js",
"static/js/6683.53f69e13.chunk.js": "./static/js/6683.53f69e13.chunk.js",
"static/js/8350.031612d5.chunk.js": "./static/js/8350.031612d5.chunk.js",
"static/js/2676.bd3d9df3.chunk.js": "./static/js/2676.bd3d9df3.chunk.js",
"static/js/9449.83d73a19.chunk.js": "./static/js/9449.83d73a19.chunk.js",
"static/js/7659.5154337d.chunk.js": "./static/js/7659.5154337d.chunk.js",
"static/js/9968.a7a1674d.chunk.js": "./static/js/9968.a7a1674d.chunk.js",
"static/js/2180.c83301fc.chunk.js": "./static/js/2180.c83301fc.chunk.js",
"static/js/8253.964026c0.chunk.js": "./static/js/8253.964026c0.chunk.js",
"static/js/3328.da1cf1c8.chunk.js": "./static/js/3328.da1cf1c8.chunk.js",
"static/js/1440.74dce637.chunk.js": "./static/js/1440.74dce637.chunk.js",
"static/js/2512.acfc57ce.chunk.js": "./static/js/2512.acfc57ce.chunk.js",
"static/js/51.63259724.chunk.js": "./static/js/51.63259724.chunk.js",
"static/js/711.5cec9776.chunk.js": "./static/js/711.5cec9776.chunk.js",
"static/js/6901.53c6aef7.chunk.js": "./static/js/6901.53c6aef7.chunk.js",
"static/js/2185.95c76a1b.chunk.js": "./static/js/2185.95c76a1b.chunk.js",
"static/js/312.d183c8e0.chunk.js": "./static/js/312.d183c8e0.chunk.js",
"static/js/2112.48f0caa6.chunk.js": "./static/js/2112.48f0caa6.chunk.js",
"static/js/4619.f7970b8a.chunk.js": "./static/js/4619.f7970b8a.chunk.js",
"static/js/8990.18a36cac.chunk.js": "./static/js/8990.18a36cac.chunk.js",
"static/js/8455.0cd71acb.chunk.js": "./static/js/8455.0cd71acb.chunk.js",
"static/css/3631.8313f811.chunk.css": "./static/css/3631.8313f811.chunk.css",
"static/js/3631.64015ba0.chunk.js": "./static/js/3631.64015ba0.chunk.js",
"static/js/1604.a9d0b62b.chunk.js": "./static/js/1604.a9d0b62b.chunk.js",
"static/js/8391.7c39b52d.chunk.js": "./static/js/8391.7c39b52d.chunk.js",
"static/js/402.0fe11251.chunk.js": "./static/js/402.0fe11251.chunk.js",
"static/js/1705.5e57fd31.chunk.js": "./static/js/1705.5e57fd31.chunk.js",
"static/js/1581.e5ea40c0.chunk.js": "./static/js/1581.e5ea40c0.chunk.js",
"static/js/455.0218ce38.chunk.js": "./static/js/455.0218ce38.chunk.js",
"static/js/2661.2121f536.chunk.js": "./static/js/2661.2121f536.chunk.js",
"static/js/889.3d385602.chunk.js": "./static/js/889.3d385602.chunk.js",
"static/js/9088.e252c094.chunk.js": "./static/js/9088.e252c094.chunk.js",
"static/js/247.88de16aa.chunk.js": "./static/js/247.88de16aa.chunk.js",
"static/js/2763.44403c2a.chunk.js": "./static/js/2763.44403c2a.chunk.js",
"static/js/2637.2ba50a8f.chunk.js": "./static/js/2637.2ba50a8f.chunk.js",
"static/css/380.e60508f1.chunk.css": "./static/css/380.e60508f1.chunk.css",
"static/js/380.a147490c.chunk.js": "./static/js/380.a147490c.chunk.js",
"static/js/5926.e86016db.chunk.js": "./static/js/5926.e86016db.chunk.js",
"static/js/701.ffb1c26f.chunk.js": "./static/js/701.ffb1c26f.chunk.js",
"static/js/7821.88351a18.chunk.js": "./static/js/7821.88351a18.chunk.js",
"static/css/2080.e60508f1.chunk.css": "./static/css/2080.e60508f1.chunk.css",
"static/js/2080.2ddaba07.chunk.js": "./static/js/2080.2ddaba07.chunk.js",
"static/js/1182.5865af16.chunk.js": "./static/js/1182.5865af16.chunk.js",
"static/css/9033.e60508f1.chunk.css": "./static/css/9033.e60508f1.chunk.css",
"static/js/9033.ff414eaf.chunk.js": "./static/js/9033.ff414eaf.chunk.js",
"static/css/6633.e60508f1.chunk.css": "./static/css/6633.e60508f1.chunk.css",
"static/js/6633.b0272e64.chunk.js": "./static/js/6633.b0272e64.chunk.js",
"static/css/2731.e60508f1.chunk.css": "./static/css/2731.e60508f1.chunk.css",
"static/js/2731.2c59ed4f.chunk.js": "./static/js/2731.2c59ed4f.chunk.js",
"static/css/5316.e60508f1.chunk.css": "./static/css/5316.e60508f1.chunk.css",
"static/js/5316.558355d5.chunk.js": "./static/js/5316.558355d5.chunk.js",
"static/js/2555.190c0fbe.chunk.js": "./static/js/2555.190c0fbe.chunk.js",
"static/js/7585.dd261b31.chunk.js": "./static/js/7585.dd261b31.chunk.js",
"static/js/4847.b6087997.chunk.js": "./static/js/4847.b6087997.chunk.js",
"static/js/4653.de61acb4.chunk.js": "./static/js/4653.de61acb4.chunk.js",
"static/js/4219.c8ec9d39.chunk.js": "./static/js/4219.c8ec9d39.chunk.js",
"static/js/8626.5930d746.chunk.js": "./static/js/8626.5930d746.chunk.js",
"static/js/736.99255ac9.chunk.js": "./static/js/736.99255ac9.chunk.js",
"static/js/6577.3590592b.chunk.js": "./static/js/6577.3590592b.chunk.js",
"static/js/9561.57e6c274.chunk.js": "./static/js/9561.57e6c274.chunk.js",
"static/js/4394.b731122a.chunk.js": "./static/js/4394.b731122a.chunk.js",
"static/js/4781.f4794912.chunk.js": "./static/js/4781.f4794912.chunk.js",
"static/js/9478.dca1d314.chunk.js": "./static/js/9478.dca1d314.chunk.js",
"static/js/7164.3762a0c0.chunk.js": "./static/js/7164.3762a0c0.chunk.js",
"static/js/4414.4768f5bb.chunk.js": "./static/js/4414.4768f5bb.chunk.js",
"static/js/7798.f7fc00ff.chunk.js": "./static/js/7798.f7fc00ff.chunk.js",
"static/js/8833.d59bdcd8.chunk.js": "./static/js/8833.d59bdcd8.chunk.js",
"static/js/471.2305812b.chunk.js": "./static/js/471.2305812b.chunk.js",
"static/js/483.eb22af68.chunk.js": "./static/js/483.eb22af68.chunk.js",
"static/js/9467.fa37a011.chunk.js": "./static/js/9467.fa37a011.chunk.js",
"static/js/6895.e4e185e1.chunk.js": "./static/js/6895.e4e185e1.chunk.js",
"static/js/7925.565c799d.chunk.js": "./static/js/7925.565c799d.chunk.js",
"static/js/5588.5db89ec2.chunk.js": "./static/js/5588.5db89ec2.chunk.js",
"static/js/4133.1602db5d.chunk.js": "./static/js/4133.1602db5d.chunk.js",
"static/css/984.e60508f1.chunk.css": "./static/css/984.e60508f1.chunk.css",
"static/js/984.4ead34b2.chunk.js": "./static/js/984.4ead34b2.chunk.js",
"static/js/3956.9b6a6dff.chunk.js": "./static/js/3956.9b6a6dff.chunk.js",
"static/js/9076.46bf2c9e.chunk.js": "./static/js/9076.46bf2c9e.chunk.js",
"static/js/9221.064a4791.chunk.js": "./static/js/9221.064a4791.chunk.js",
"static/js/8896.3600ef1f.chunk.js": "./static/js/8896.3600ef1f.chunk.js",
"static/js/9134.11ed4367.chunk.js": "./static/js/9134.11ed4367.chunk.js",
"static/css/8138.e60508f1.chunk.css": "./static/css/8138.e60508f1.chunk.css",
"static/js/8138.41cc5427.chunk.js": "./static/js/8138.41cc5427.chunk.js",
"static/js/1030.9d4efe7b.chunk.js": "./static/js/1030.9d4efe7b.chunk.js",
"static/js/9145.e9982ac4.chunk.js": "./static/js/9145.e9982ac4.chunk.js",
"static/js/1379.1b932cb7.chunk.js": "./static/js/1379.1b932cb7.chunk.js",
"static/js/1501.e45e3e8d.chunk.js": "./static/js/1501.e45e3e8d.chunk.js",
"static/js/9605.9bcf6af3.chunk.js": "./static/js/9605.9bcf6af3.chunk.js",
"static/js/426.8e611cf9.chunk.js": "./static/js/426.8e611cf9.chunk.js",
"static/js/2878.a43d663c.chunk.js": "./static/js/2878.a43d663c.chunk.js",
"static/js/8495.71a61743.chunk.js": "./static/js/8495.71a61743.chunk.js",
"static/js/4934.064b787d.chunk.js": "./static/js/4934.064b787d.chunk.js",
"static/js/3518.0ed0b89a.chunk.js": "./static/js/3518.0ed0b89a.chunk.js",
"static/js/7021.ad5078e8.chunk.js": "./static/js/7021.ad5078e8.chunk.js",
"static/js/2684.b9fc03c6.chunk.js": "./static/js/2684.b9fc03c6.chunk.js",
"static/js/6683.fc3f5af3.chunk.js": "./static/js/6683.fc3f5af3.chunk.js",
"static/js/8350.a5a279cb.chunk.js": "./static/js/8350.a5a279cb.chunk.js",
"static/js/4873.ee12f6f7.chunk.js": "./static/js/4873.ee12f6f7.chunk.js",
"static/js/9449.d0d584ad.chunk.js": "./static/js/9449.d0d584ad.chunk.js",
"static/js/7659.2d03e3f6.chunk.js": "./static/js/7659.2d03e3f6.chunk.js",
"static/js/9968.aff741c4.chunk.js": "./static/js/9968.aff741c4.chunk.js",
"static/js/2180.50fad27b.chunk.js": "./static/js/2180.50fad27b.chunk.js",
"static/js/8253.18604e19.chunk.js": "./static/js/8253.18604e19.chunk.js",
"static/js/3328.cb6f26d0.chunk.js": "./static/js/3328.cb6f26d0.chunk.js",
"static/js/1440.427e7e65.chunk.js": "./static/js/1440.427e7e65.chunk.js",
"static/js/9179.4b036013.chunk.js": "./static/js/9179.4b036013.chunk.js",
"static/js/51.e2978f99.chunk.js": "./static/js/51.e2978f99.chunk.js",
"static/js/711.4afa02e3.chunk.js": "./static/js/711.4afa02e3.chunk.js",
"static/js/6901.d193e16b.chunk.js": "./static/js/6901.d193e16b.chunk.js",
"static/js/2185.2a906448.chunk.js": "./static/js/2185.2a906448.chunk.js",
"static/js/312.8294da96.chunk.js": "./static/js/312.8294da96.chunk.js",
"static/js/2112.dd0b4d48.chunk.js": "./static/js/2112.dd0b4d48.chunk.js",
"static/js/4619.aa018cb6.chunk.js": "./static/js/4619.aa018cb6.chunk.js",
"static/js/8990.ee4b3da7.chunk.js": "./static/js/8990.ee4b3da7.chunk.js",
"static/js/8455.6341f6aa.chunk.js": "./static/js/8455.6341f6aa.chunk.js",
"static/css/3631.e60508f1.chunk.css": "./static/css/3631.e60508f1.chunk.css",
"static/js/3631.93134db8.chunk.js": "./static/js/3631.93134db8.chunk.js",
"static/js/1604.c298cecf.chunk.js": "./static/js/1604.c298cecf.chunk.js",
"static/js/8391.6f343ba7.chunk.js": "./static/js/8391.6f343ba7.chunk.js",
"static/js/402.e7058288.chunk.js": "./static/js/402.e7058288.chunk.js",
"static/js/1705.58e59f26.chunk.js": "./static/js/1705.58e59f26.chunk.js",
"static/js/1581.c672f273.chunk.js": "./static/js/1581.c672f273.chunk.js",
"static/js/455.28c5aa40.chunk.js": "./static/js/455.28c5aa40.chunk.js",
"static/js/2661.1c28aeb7.chunk.js": "./static/js/2661.1c28aeb7.chunk.js",
"static/js/889.08464f2a.chunk.js": "./static/js/889.08464f2a.chunk.js",
"static/js/9088.022c4a1f.chunk.js": "./static/js/9088.022c4a1f.chunk.js",
"static/js/247.2d01bd01.chunk.js": "./static/js/247.2d01bd01.chunk.js",
"static/js/2763.2d19d316.chunk.js": "./static/js/2763.2d19d316.chunk.js",
"static/js/5171.2cf876b1.chunk.js": "./static/js/5171.2cf876b1.chunk.js",
"static/js/2426.172b5361.chunk.js": "./static/js/2426.172b5361.chunk.js",
"static/js/5561.c5000912.chunk.js": "./static/js/5561.c5000912.chunk.js",
"static/js/5609.0399a94c.chunk.js": "./static/js/5609.0399a94c.chunk.js",
"static/js/5561.c5000912.chunk.js": "./static/js/5561.c5000912.chunk.js",
"static/js/3801.a06455a2.chunk.js": "./static/js/3801.a06455a2.chunk.js",
"static/js/7757.3650a6cc.chunk.js": "./static/js/7757.3650a6cc.chunk.js",
"static/js/1918.ce3ab2e2.chunk.js": "./static/js/1918.ce3ab2e2.chunk.js",
"static/js/6523.f3c7724a.chunk.js": "./static/js/6523.f3c7724a.chunk.js",
"static/js/7757.3650a6cc.chunk.js": "./static/js/7757.3650a6cc.chunk.js",
"static/js/6523.fb65841b.chunk.js": "./static/js/6523.fb65841b.chunk.js",
"static/js/6431.5f2e5e6e.chunk.js": "./static/js/6431.5f2e5e6e.chunk.js",
"static/js/2011.53c6f61f.chunk.js": "./static/js/2011.53c6f61f.chunk.js",
"static/js/2011.9a9126b4.chunk.js": "./static/js/2011.9a9126b4.chunk.js",
"static/js/8810.b52e1e05.chunk.js": "./static/js/8810.b52e1e05.chunk.js",
"static/js/8152.83273cfb.chunk.js": "./static/js/8152.83273cfb.chunk.js",
"static/js/3909.cdbddaab.chunk.js": "./static/js/3909.cdbddaab.chunk.js",
"static/js/9437.1a158c7b.chunk.js": "./static/js/9437.1a158c7b.chunk.js",
"static/js/8152.83273cfb.chunk.js": "./static/js/8152.83273cfb.chunk.js",
"static/js/6172.098bf62e.chunk.js": "./static/js/6172.098bf62e.chunk.js",
"static/js/4509.0cb642e8.chunk.js": "./static/js/4509.0cb642e8.chunk.js",
"static/js/6852.94cb267a.chunk.js": "./static/js/6852.94cb267a.chunk.js",
"static/js/8396.49ac6668.chunk.js": "./static/js/8396.49ac6668.chunk.js",
"static/js/5085.49076139.chunk.js": "./static/js/5085.49076139.chunk.js",
"static/js/5749.d88c31a5.chunk.js": "./static/js/5749.d88c31a5.chunk.js",
"static/js/3402.e2a2d57b.chunk.js": "./static/js/3402.e2a2d57b.chunk.js",
"static/js/7002.c23dc7cf.chunk.js": "./static/js/7002.c23dc7cf.chunk.js",
"static/js/3461.f7b91f8d.chunk.js": "./static/js/3461.f7b91f8d.chunk.js",
"static/js/6484.be775902.chunk.js": "./static/js/6484.be775902.chunk.js",
"static/js/7142.957288ed.chunk.js": "./static/js/7142.957288ed.chunk.js",
"static/js/7923.552889f9.chunk.js": "./static/js/7923.552889f9.chunk.js",
"static/js/5586.a2da5401.chunk.js": "./static/js/5586.a2da5401.chunk.js",
"static/js/1788.280ca1f4.chunk.js": "./static/js/1788.280ca1f4.chunk.js",
"static/js/9785.7ccf0212.chunk.js": "./static/js/9785.7ccf0212.chunk.js",
"static/js/8735.52726eac.chunk.js": "./static/js/8735.52726eac.chunk.js",
"static/js/63.830fd6fc.chunk.js": "./static/js/63.830fd6fc.chunk.js",
"static/js/2983.66cf0ad4.chunk.js": "./static/js/2983.66cf0ad4.chunk.js",
"static/js/5289.8c388542.chunk.js": "./static/js/5289.8c388542.chunk.js",
"static/js/5026.0b30f6e2.chunk.js": "./static/js/5026.0b30f6e2.chunk.js",
"static/js/264.3c44e7e5.chunk.js": "./static/js/264.3c44e7e5.chunk.js",
"static/js/8959.b3179758.chunk.js": "./static/js/8959.b3179758.chunk.js",
"static/js/2983.fe24695f.chunk.js": "./static/js/2983.fe24695f.chunk.js",
"static/js/5289.d2bace8e.chunk.js": "./static/js/5289.d2bace8e.chunk.js",
"static/js/5026.cbf5a1ed.chunk.js": "./static/js/5026.cbf5a1ed.chunk.js",
"index.html": "./index.html",
"main.90d417ae.css.map": "./static/css/main.90d417ae.css.map",
"main.eec275cb.js.map": "./static/js/main.eec275cb.js.map",
"2483.48dd183a.chunk.js.map": "./static/js/2483.48dd183a.chunk.js.map",
"main.55e03c75.js.map": "./static/js/main.55e03c75.js.map",
"2483.64c94bc6.chunk.js.map": "./static/js/2483.64c94bc6.chunk.js.map",
"6914.c9671304.chunk.js.map": "./static/js/6914.c9671304.chunk.js.map",
"4209.b2656735.chunk.js.map": "./static/js/4209.b2656735.chunk.js.map",
"1829.3a638c7d.chunk.js.map": "./static/js/1829.3a638c7d.chunk.js.map",
"4455.4ba90afa.chunk.js.map": "./static/js/4455.4ba90afa.chunk.js.map",
"5088.dae21c0f.chunk.js.map": "./static/js/5088.dae21c0f.chunk.js.map",
"4209.2b6438a1.chunk.js.map": "./static/js/4209.2b6438a1.chunk.js.map",
"1829.187799ba.chunk.js.map": "./static/js/1829.187799ba.chunk.js.map",
"4455.0849ed40.chunk.js.map": "./static/js/4455.0849ed40.chunk.js.map",
"5088.60f151ba.chunk.js.map": "./static/js/5088.60f151ba.chunk.js.map",
"5140.e9043b63.chunk.js.map": "./static/js/5140.e9043b63.chunk.js.map",
"5646.e4b3b3e9.chunk.js.map": "./static/js/5646.e4b3b3e9.chunk.js.map",
"5646.e760211f.chunk.js.map": "./static/js/5646.e760211f.chunk.js.map",
"3176.43953acc.chunk.js.map": "./static/js/3176.43953acc.chunk.js.map",
"6137.c0b24aaa.chunk.js.map": "./static/js/6137.c0b24aaa.chunk.js.map",
"6137.7c3483b1.chunk.js.map": "./static/js/6137.7c3483b1.chunk.js.map",
"7045.ca5a5aae.chunk.js.map": "./static/js/7045.ca5a5aae.chunk.js.map",
"9251.be8506b4.chunk.js.map": "./static/js/9251.be8506b4.chunk.js.map",
"2338.8d87570c.chunk.js.map": "./static/js/2338.8d87570c.chunk.js.map",
"4335.44360980.chunk.js.map": "./static/js/4335.44360980.chunk.js.map",
"3061.c71568b9.chunk.js.map": "./static/js/3061.c71568b9.chunk.js.map",
"6763.f0f3ae01.chunk.js.map": "./static/js/6763.f0f3ae01.chunk.js.map",
"3543.2a18a6b9.chunk.js.map": "./static/js/3543.2a18a6b9.chunk.js.map",
"4061.44b5ee07.chunk.js.map": "./static/js/4061.44b5ee07.chunk.js.map",
"2249.eff0718f.chunk.js.map": "./static/js/2249.eff0718f.chunk.js.map",
"9251.43d5879d.chunk.js.map": "./static/js/9251.43d5879d.chunk.js.map",
"2338.8430dcc6.chunk.js.map": "./static/js/2338.8430dcc6.chunk.js.map",
"4335.efdb7b8f.chunk.js.map": "./static/js/4335.efdb7b8f.chunk.js.map",
"3061.6f255655.chunk.js.map": "./static/js/3061.6f255655.chunk.js.map",
"6763.8e2c073b.chunk.js.map": "./static/js/6763.8e2c073b.chunk.js.map",
"3543.448be99d.chunk.js.map": "./static/js/3543.448be99d.chunk.js.map",
"4061.f26c1196.chunk.js.map": "./static/js/4061.f26c1196.chunk.js.map",
"2249.69729722.chunk.js.map": "./static/js/2249.69729722.chunk.js.map",
"9611.c217768e.chunk.js.map": "./static/js/9611.c217768e.chunk.js.map",
"2637.6d2abbec.chunk.js.map": "./static/js/2637.6d2abbec.chunk.js.map",
"380.8313f811.chunk.css.map": "./static/css/380.8313f811.chunk.css.map",
"380.78d0d6a2.chunk.js.map": "./static/js/380.78d0d6a2.chunk.js.map",
"5926.4b729c3b.chunk.js.map": "./static/js/5926.4b729c3b.chunk.js.map",
"701.52180c55.chunk.js.map": "./static/js/701.52180c55.chunk.js.map",
"7821.a2c85c06.chunk.js.map": "./static/js/7821.a2c85c06.chunk.js.map",
"2080.8313f811.chunk.css.map": "./static/css/2080.8313f811.chunk.css.map",
"2080.5b870317.chunk.js.map": "./static/js/2080.5b870317.chunk.js.map",
"6747.a78bbd22.chunk.js.map": "./static/js/6747.a78bbd22.chunk.js.map",
"9033.8313f811.chunk.css.map": "./static/css/9033.8313f811.chunk.css.map",
"9033.b95c6d4a.chunk.js.map": "./static/js/9033.b95c6d4a.chunk.js.map",
"3368.8313f811.chunk.css.map": "./static/css/3368.8313f811.chunk.css.map",
"3368.27a61e61.chunk.js.map": "./static/js/3368.27a61e61.chunk.js.map",
"3688.8313f811.chunk.css.map": "./static/css/3688.8313f811.chunk.css.map",
"3688.fa756e3b.chunk.js.map": "./static/js/3688.fa756e3b.chunk.js.map",
"2555.cd5bfa20.chunk.js.map": "./static/js/2555.cd5bfa20.chunk.js.map",
"7585.78d525ce.chunk.js.map": "./static/js/7585.78d525ce.chunk.js.map",
"1836.86b53328.chunk.js.map": "./static/js/1836.86b53328.chunk.js.map",
"4653.89f5d861.chunk.js.map": "./static/js/4653.89f5d861.chunk.js.map",
"4219.c24a76ef.chunk.js.map": "./static/js/4219.c24a76ef.chunk.js.map",
"8626.896fa8ac.chunk.js.map": "./static/js/8626.896fa8ac.chunk.js.map",
"736.40b3a390.chunk.js.map": "./static/js/736.40b3a390.chunk.js.map",
"6577.d48f6fc0.chunk.js.map": "./static/js/6577.d48f6fc0.chunk.js.map",
"9561.46bb02ad.chunk.js.map": "./static/js/9561.46bb02ad.chunk.js.map",
"4394.05e77f06.chunk.js.map": "./static/js/4394.05e77f06.chunk.js.map",
"4781.785d14ba.chunk.js.map": "./static/js/4781.785d14ba.chunk.js.map",
"9478.7c40d91e.chunk.js.map": "./static/js/9478.7c40d91e.chunk.js.map",
"7164.5542a849.chunk.js.map": "./static/js/7164.5542a849.chunk.js.map",
"4414.d9f98702.chunk.js.map": "./static/js/4414.d9f98702.chunk.js.map",
"7798.07093714.chunk.js.map": "./static/js/7798.07093714.chunk.js.map",
"8833.60296031.chunk.js.map": "./static/js/8833.60296031.chunk.js.map",
"471.244e997d.chunk.js.map": "./static/js/471.244e997d.chunk.js.map",
"483.a8ef0ad5.chunk.js.map": "./static/js/483.a8ef0ad5.chunk.js.map",
"9467.5fb2ba42.chunk.js.map": "./static/js/9467.5fb2ba42.chunk.js.map",
"6895.10b5757c.chunk.js.map": "./static/js/6895.10b5757c.chunk.js.map",
"6233.c0a85e71.chunk.js.map": "./static/js/6233.c0a85e71.chunk.js.map",
"5588.fa4e23ec.chunk.js.map": "./static/js/5588.fa4e23ec.chunk.js.map",
"4133.1b71a3ec.chunk.js.map": "./static/js/4133.1b71a3ec.chunk.js.map",
"1955.8313f811.chunk.css.map": "./static/css/1955.8313f811.chunk.css.map",
"1955.fcaedc3e.chunk.js.map": "./static/js/1955.fcaedc3e.chunk.js.map",
"3956.0b36ab08.chunk.js.map": "./static/js/3956.0b36ab08.chunk.js.map",
"8771.475684ba.chunk.js.map": "./static/js/8771.475684ba.chunk.js.map",
"9076.a6606f2e.chunk.js.map": "./static/js/9076.a6606f2e.chunk.js.map",
"9221.ba80075c.chunk.js.map": "./static/js/9221.ba80075c.chunk.js.map",
"8896.09fd2a0c.chunk.js.map": "./static/js/8896.09fd2a0c.chunk.js.map",
"7413.73b72a2b.chunk.js.map": "./static/js/7413.73b72a2b.chunk.js.map",
"9134.b0935ef3.chunk.js.map": "./static/js/9134.b0935ef3.chunk.js.map",
"8138.8313f811.chunk.css.map": "./static/css/8138.8313f811.chunk.css.map",
"8138.e9fa48a9.chunk.js.map": "./static/js/8138.e9fa48a9.chunk.js.map",
"1030.4a654568.chunk.js.map": "./static/js/1030.4a654568.chunk.js.map",
"9145.363b2352.chunk.js.map": "./static/js/9145.363b2352.chunk.js.map",
"1379.0bfc0b60.chunk.js.map": "./static/js/1379.0bfc0b60.chunk.js.map",
"1501.c46671fd.chunk.js.map": "./static/js/1501.c46671fd.chunk.js.map",
"9605.c3d4a4cf.chunk.js.map": "./static/js/9605.c3d4a4cf.chunk.js.map",
"426.e738683c.chunk.js.map": "./static/js/426.e738683c.chunk.js.map",
"2878.fca6e2cf.chunk.js.map": "./static/js/2878.fca6e2cf.chunk.js.map",
"8495.bdd215dc.chunk.js.map": "./static/js/8495.bdd215dc.chunk.js.map",
"4934.4a573b0b.chunk.js.map": "./static/js/4934.4a573b0b.chunk.js.map",
"3518.e1923a22.chunk.js.map": "./static/js/3518.e1923a22.chunk.js.map",
"7021.ea551e6b.chunk.js.map": "./static/js/7021.ea551e6b.chunk.js.map",
"2684.569c8172.chunk.js.map": "./static/js/2684.569c8172.chunk.js.map",
"6683.53f69e13.chunk.js.map": "./static/js/6683.53f69e13.chunk.js.map",
"8350.031612d5.chunk.js.map": "./static/js/8350.031612d5.chunk.js.map",
"2676.bd3d9df3.chunk.js.map": "./static/js/2676.bd3d9df3.chunk.js.map",
"9449.83d73a19.chunk.js.map": "./static/js/9449.83d73a19.chunk.js.map",
"7659.5154337d.chunk.js.map": "./static/js/7659.5154337d.chunk.js.map",
"9968.a7a1674d.chunk.js.map": "./static/js/9968.a7a1674d.chunk.js.map",
"2180.c83301fc.chunk.js.map": "./static/js/2180.c83301fc.chunk.js.map",
"8253.964026c0.chunk.js.map": "./static/js/8253.964026c0.chunk.js.map",
"3328.da1cf1c8.chunk.js.map": "./static/js/3328.da1cf1c8.chunk.js.map",
"1440.74dce637.chunk.js.map": "./static/js/1440.74dce637.chunk.js.map",
"2512.acfc57ce.chunk.js.map": "./static/js/2512.acfc57ce.chunk.js.map",
"51.63259724.chunk.js.map": "./static/js/51.63259724.chunk.js.map",
"711.5cec9776.chunk.js.map": "./static/js/711.5cec9776.chunk.js.map",
"6901.53c6aef7.chunk.js.map": "./static/js/6901.53c6aef7.chunk.js.map",
"2185.95c76a1b.chunk.js.map": "./static/js/2185.95c76a1b.chunk.js.map",
"312.d183c8e0.chunk.js.map": "./static/js/312.d183c8e0.chunk.js.map",
"2112.48f0caa6.chunk.js.map": "./static/js/2112.48f0caa6.chunk.js.map",
"4619.f7970b8a.chunk.js.map": "./static/js/4619.f7970b8a.chunk.js.map",
"8990.18a36cac.chunk.js.map": "./static/js/8990.18a36cac.chunk.js.map",
"8455.0cd71acb.chunk.js.map": "./static/js/8455.0cd71acb.chunk.js.map",
"3631.8313f811.chunk.css.map": "./static/css/3631.8313f811.chunk.css.map",
"3631.64015ba0.chunk.js.map": "./static/js/3631.64015ba0.chunk.js.map",
"1604.a9d0b62b.chunk.js.map": "./static/js/1604.a9d0b62b.chunk.js.map",
"8391.7c39b52d.chunk.js.map": "./static/js/8391.7c39b52d.chunk.js.map",
"402.0fe11251.chunk.js.map": "./static/js/402.0fe11251.chunk.js.map",
"1705.5e57fd31.chunk.js.map": "./static/js/1705.5e57fd31.chunk.js.map",
"1581.e5ea40c0.chunk.js.map": "./static/js/1581.e5ea40c0.chunk.js.map",
"455.0218ce38.chunk.js.map": "./static/js/455.0218ce38.chunk.js.map",
"2661.2121f536.chunk.js.map": "./static/js/2661.2121f536.chunk.js.map",
"889.3d385602.chunk.js.map": "./static/js/889.3d385602.chunk.js.map",
"9088.e252c094.chunk.js.map": "./static/js/9088.e252c094.chunk.js.map",
"247.88de16aa.chunk.js.map": "./static/js/247.88de16aa.chunk.js.map",
"2763.44403c2a.chunk.js.map": "./static/js/2763.44403c2a.chunk.js.map",
"2637.2ba50a8f.chunk.js.map": "./static/js/2637.2ba50a8f.chunk.js.map",
"380.e60508f1.chunk.css.map": "./static/css/380.e60508f1.chunk.css.map",
"380.a147490c.chunk.js.map": "./static/js/380.a147490c.chunk.js.map",
"5926.e86016db.chunk.js.map": "./static/js/5926.e86016db.chunk.js.map",
"701.ffb1c26f.chunk.js.map": "./static/js/701.ffb1c26f.chunk.js.map",
"7821.88351a18.chunk.js.map": "./static/js/7821.88351a18.chunk.js.map",
"2080.e60508f1.chunk.css.map": "./static/css/2080.e60508f1.chunk.css.map",
"2080.2ddaba07.chunk.js.map": "./static/js/2080.2ddaba07.chunk.js.map",
"1182.5865af16.chunk.js.map": "./static/js/1182.5865af16.chunk.js.map",
"9033.e60508f1.chunk.css.map": "./static/css/9033.e60508f1.chunk.css.map",
"9033.ff414eaf.chunk.js.map": "./static/js/9033.ff414eaf.chunk.js.map",
"6633.e60508f1.chunk.css.map": "./static/css/6633.e60508f1.chunk.css.map",
"6633.b0272e64.chunk.js.map": "./static/js/6633.b0272e64.chunk.js.map",
"2731.e60508f1.chunk.css.map": "./static/css/2731.e60508f1.chunk.css.map",
"2731.2c59ed4f.chunk.js.map": "./static/js/2731.2c59ed4f.chunk.js.map",
"5316.e60508f1.chunk.css.map": "./static/css/5316.e60508f1.chunk.css.map",
"5316.558355d5.chunk.js.map": "./static/js/5316.558355d5.chunk.js.map",
"2555.190c0fbe.chunk.js.map": "./static/js/2555.190c0fbe.chunk.js.map",
"7585.dd261b31.chunk.js.map": "./static/js/7585.dd261b31.chunk.js.map",
"4847.b6087997.chunk.js.map": "./static/js/4847.b6087997.chunk.js.map",
"4653.de61acb4.chunk.js.map": "./static/js/4653.de61acb4.chunk.js.map",
"4219.c8ec9d39.chunk.js.map": "./static/js/4219.c8ec9d39.chunk.js.map",
"8626.5930d746.chunk.js.map": "./static/js/8626.5930d746.chunk.js.map",
"736.99255ac9.chunk.js.map": "./static/js/736.99255ac9.chunk.js.map",
"6577.3590592b.chunk.js.map": "./static/js/6577.3590592b.chunk.js.map",
"9561.57e6c274.chunk.js.map": "./static/js/9561.57e6c274.chunk.js.map",
"4394.b731122a.chunk.js.map": "./static/js/4394.b731122a.chunk.js.map",
"4781.f4794912.chunk.js.map": "./static/js/4781.f4794912.chunk.js.map",
"9478.dca1d314.chunk.js.map": "./static/js/9478.dca1d314.chunk.js.map",
"7164.3762a0c0.chunk.js.map": "./static/js/7164.3762a0c0.chunk.js.map",
"4414.4768f5bb.chunk.js.map": "./static/js/4414.4768f5bb.chunk.js.map",
"7798.f7fc00ff.chunk.js.map": "./static/js/7798.f7fc00ff.chunk.js.map",
"8833.d59bdcd8.chunk.js.map": "./static/js/8833.d59bdcd8.chunk.js.map",
"471.2305812b.chunk.js.map": "./static/js/471.2305812b.chunk.js.map",
"483.eb22af68.chunk.js.map": "./static/js/483.eb22af68.chunk.js.map",
"9467.fa37a011.chunk.js.map": "./static/js/9467.fa37a011.chunk.js.map",
"6895.e4e185e1.chunk.js.map": "./static/js/6895.e4e185e1.chunk.js.map",
"7925.565c799d.chunk.js.map": "./static/js/7925.565c799d.chunk.js.map",
"5588.5db89ec2.chunk.js.map": "./static/js/5588.5db89ec2.chunk.js.map",
"4133.1602db5d.chunk.js.map": "./static/js/4133.1602db5d.chunk.js.map",
"984.e60508f1.chunk.css.map": "./static/css/984.e60508f1.chunk.css.map",
"984.4ead34b2.chunk.js.map": "./static/js/984.4ead34b2.chunk.js.map",
"3956.9b6a6dff.chunk.js.map": "./static/js/3956.9b6a6dff.chunk.js.map",
"9076.46bf2c9e.chunk.js.map": "./static/js/9076.46bf2c9e.chunk.js.map",
"9221.064a4791.chunk.js.map": "./static/js/9221.064a4791.chunk.js.map",
"8896.3600ef1f.chunk.js.map": "./static/js/8896.3600ef1f.chunk.js.map",
"9134.11ed4367.chunk.js.map": "./static/js/9134.11ed4367.chunk.js.map",
"8138.e60508f1.chunk.css.map": "./static/css/8138.e60508f1.chunk.css.map",
"8138.41cc5427.chunk.js.map": "./static/js/8138.41cc5427.chunk.js.map",
"1030.9d4efe7b.chunk.js.map": "./static/js/1030.9d4efe7b.chunk.js.map",
"9145.e9982ac4.chunk.js.map": "./static/js/9145.e9982ac4.chunk.js.map",
"1379.1b932cb7.chunk.js.map": "./static/js/1379.1b932cb7.chunk.js.map",
"1501.e45e3e8d.chunk.js.map": "./static/js/1501.e45e3e8d.chunk.js.map",
"9605.9bcf6af3.chunk.js.map": "./static/js/9605.9bcf6af3.chunk.js.map",
"426.8e611cf9.chunk.js.map": "./static/js/426.8e611cf9.chunk.js.map",
"2878.a43d663c.chunk.js.map": "./static/js/2878.a43d663c.chunk.js.map",
"8495.71a61743.chunk.js.map": "./static/js/8495.71a61743.chunk.js.map",
"4934.064b787d.chunk.js.map": "./static/js/4934.064b787d.chunk.js.map",
"3518.0ed0b89a.chunk.js.map": "./static/js/3518.0ed0b89a.chunk.js.map",
"7021.ad5078e8.chunk.js.map": "./static/js/7021.ad5078e8.chunk.js.map",
"2684.b9fc03c6.chunk.js.map": "./static/js/2684.b9fc03c6.chunk.js.map",
"6683.fc3f5af3.chunk.js.map": "./static/js/6683.fc3f5af3.chunk.js.map",
"8350.a5a279cb.chunk.js.map": "./static/js/8350.a5a279cb.chunk.js.map",
"4873.ee12f6f7.chunk.js.map": "./static/js/4873.ee12f6f7.chunk.js.map",
"9449.d0d584ad.chunk.js.map": "./static/js/9449.d0d584ad.chunk.js.map",
"7659.2d03e3f6.chunk.js.map": "./static/js/7659.2d03e3f6.chunk.js.map",
"9968.aff741c4.chunk.js.map": "./static/js/9968.aff741c4.chunk.js.map",
"2180.50fad27b.chunk.js.map": "./static/js/2180.50fad27b.chunk.js.map",
"8253.18604e19.chunk.js.map": "./static/js/8253.18604e19.chunk.js.map",
"3328.cb6f26d0.chunk.js.map": "./static/js/3328.cb6f26d0.chunk.js.map",
"1440.427e7e65.chunk.js.map": "./static/js/1440.427e7e65.chunk.js.map",
"9179.4b036013.chunk.js.map": "./static/js/9179.4b036013.chunk.js.map",
"51.e2978f99.chunk.js.map": "./static/js/51.e2978f99.chunk.js.map",
"711.4afa02e3.chunk.js.map": "./static/js/711.4afa02e3.chunk.js.map",
"6901.d193e16b.chunk.js.map": "./static/js/6901.d193e16b.chunk.js.map",
"2185.2a906448.chunk.js.map": "./static/js/2185.2a906448.chunk.js.map",
"312.8294da96.chunk.js.map": "./static/js/312.8294da96.chunk.js.map",
"2112.dd0b4d48.chunk.js.map": "./static/js/2112.dd0b4d48.chunk.js.map",
"4619.aa018cb6.chunk.js.map": "./static/js/4619.aa018cb6.chunk.js.map",
"8990.ee4b3da7.chunk.js.map": "./static/js/8990.ee4b3da7.chunk.js.map",
"8455.6341f6aa.chunk.js.map": "./static/js/8455.6341f6aa.chunk.js.map",
"3631.e60508f1.chunk.css.map": "./static/css/3631.e60508f1.chunk.css.map",
"3631.93134db8.chunk.js.map": "./static/js/3631.93134db8.chunk.js.map",
"1604.c298cecf.chunk.js.map": "./static/js/1604.c298cecf.chunk.js.map",
"8391.6f343ba7.chunk.js.map": "./static/js/8391.6f343ba7.chunk.js.map",
"402.e7058288.chunk.js.map": "./static/js/402.e7058288.chunk.js.map",
"1705.58e59f26.chunk.js.map": "./static/js/1705.58e59f26.chunk.js.map",
"1581.c672f273.chunk.js.map": "./static/js/1581.c672f273.chunk.js.map",
"455.28c5aa40.chunk.js.map": "./static/js/455.28c5aa40.chunk.js.map",
"2661.1c28aeb7.chunk.js.map": "./static/js/2661.1c28aeb7.chunk.js.map",
"889.08464f2a.chunk.js.map": "./static/js/889.08464f2a.chunk.js.map",
"9088.022c4a1f.chunk.js.map": "./static/js/9088.022c4a1f.chunk.js.map",
"247.2d01bd01.chunk.js.map": "./static/js/247.2d01bd01.chunk.js.map",
"2763.2d19d316.chunk.js.map": "./static/js/2763.2d19d316.chunk.js.map",
"5171.2cf876b1.chunk.js.map": "./static/js/5171.2cf876b1.chunk.js.map",
"2426.172b5361.chunk.js.map": "./static/js/2426.172b5361.chunk.js.map",
"5561.c5000912.chunk.js.map": "./static/js/5561.c5000912.chunk.js.map",
"5609.0399a94c.chunk.js.map": "./static/js/5609.0399a94c.chunk.js.map",
"5561.c5000912.chunk.js.map": "./static/js/5561.c5000912.chunk.js.map",
"3801.a06455a2.chunk.js.map": "./static/js/3801.a06455a2.chunk.js.map",
"7757.3650a6cc.chunk.js.map": "./static/js/7757.3650a6cc.chunk.js.map",
"1918.ce3ab2e2.chunk.js.map": "./static/js/1918.ce3ab2e2.chunk.js.map",
"6523.f3c7724a.chunk.js.map": "./static/js/6523.f3c7724a.chunk.js.map",
"7757.3650a6cc.chunk.js.map": "./static/js/7757.3650a6cc.chunk.js.map",
"6523.fb65841b.chunk.js.map": "./static/js/6523.fb65841b.chunk.js.map",
"6431.5f2e5e6e.chunk.js.map": "./static/js/6431.5f2e5e6e.chunk.js.map",
"2011.53c6f61f.chunk.js.map": "./static/js/2011.53c6f61f.chunk.js.map",
"2011.9a9126b4.chunk.js.map": "./static/js/2011.9a9126b4.chunk.js.map",
"8810.b52e1e05.chunk.js.map": "./static/js/8810.b52e1e05.chunk.js.map",
"8152.83273cfb.chunk.js.map": "./static/js/8152.83273cfb.chunk.js.map",
"3909.cdbddaab.chunk.js.map": "./static/js/3909.cdbddaab.chunk.js.map",
"9437.1a158c7b.chunk.js.map": "./static/js/9437.1a158c7b.chunk.js.map",
"8152.83273cfb.chunk.js.map": "./static/js/8152.83273cfb.chunk.js.map",
"6172.098bf62e.chunk.js.map": "./static/js/6172.098bf62e.chunk.js.map",
"4509.0cb642e8.chunk.js.map": "./static/js/4509.0cb642e8.chunk.js.map",
"6852.94cb267a.chunk.js.map": "./static/js/6852.94cb267a.chunk.js.map",
"8396.49ac6668.chunk.js.map": "./static/js/8396.49ac6668.chunk.js.map",
"5085.49076139.chunk.js.map": "./static/js/5085.49076139.chunk.js.map",
"5749.d88c31a5.chunk.js.map": "./static/js/5749.d88c31a5.chunk.js.map",
"3402.e2a2d57b.chunk.js.map": "./static/js/3402.e2a2d57b.chunk.js.map",
"7002.c23dc7cf.chunk.js.map": "./static/js/7002.c23dc7cf.chunk.js.map",
"3461.f7b91f8d.chunk.js.map": "./static/js/3461.f7b91f8d.chunk.js.map",
"6484.be775902.chunk.js.map": "./static/js/6484.be775902.chunk.js.map",
"7142.957288ed.chunk.js.map": "./static/js/7142.957288ed.chunk.js.map",
"7923.552889f9.chunk.js.map": "./static/js/7923.552889f9.chunk.js.map",
"5586.a2da5401.chunk.js.map": "./static/js/5586.a2da5401.chunk.js.map",
"1788.280ca1f4.chunk.js.map": "./static/js/1788.280ca1f4.chunk.js.map",
"9785.7ccf0212.chunk.js.map": "./static/js/9785.7ccf0212.chunk.js.map",
"8735.52726eac.chunk.js.map": "./static/js/8735.52726eac.chunk.js.map",
"63.830fd6fc.chunk.js.map": "./static/js/63.830fd6fc.chunk.js.map",
"2983.66cf0ad4.chunk.js.map": "./static/js/2983.66cf0ad4.chunk.js.map",
"5289.8c388542.chunk.js.map": "./static/js/5289.8c388542.chunk.js.map",
"5026.0b30f6e2.chunk.js.map": "./static/js/5026.0b30f6e2.chunk.js.map"
"264.3c44e7e5.chunk.js.map": "./static/js/264.3c44e7e5.chunk.js.map",
"8959.b3179758.chunk.js.map": "./static/js/8959.b3179758.chunk.js.map",
"2983.fe24695f.chunk.js.map": "./static/js/2983.fe24695f.chunk.js.map",
"5289.d2bace8e.chunk.js.map": "./static/js/5289.d2bace8e.chunk.js.map",
"5026.cbf5a1ed.chunk.js.map": "./static/js/5026.cbf5a1ed.chunk.js.map"
},
"entrypoints": [
"static/css/main.90d417ae.css",
"static/js/main.eec275cb.js"
"static/js/main.55e03c75.js"
]
}

View File

@@ -0,0 +1,3 @@
<svg id="search-icn" xmlns="http://www.w3.org/2000/svg" width="14.787" height="14.96" viewBox="0 0 14.787 14.96">
<path id="Trazado_399" data-name="Trazado 399" d="M-2.643-45.114a6.418,6.418,0,0,0,1.4-4.008A6.48,6.48,0,0,0-7.722-55.6,6.48,6.48,0,0,0-14.2-49.122a6.48,6.48,0,0,0,6.478,6.478A6.418,6.418,0,0,0-3.887-43.9L-.881-40.9a.868.868,0,0,0,.6.259.838.838,0,0,0,.6-.259.855.855,0,0,0,0-1.227Zm-9.829-4.008a4.748,4.748,0,0,1,4.751-4.751,4.748,4.748,0,0,1,4.751,4.751,4.759,4.759,0,0,1-4.751,4.751A4.759,4.759,0,0,1-12.473-49.122Z" transform="translate(14.2 55.6)" fill="#afafaf"/>
</svg>

After

Width:  |  Height:  |  Size: 593 B

View File

@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><base href="/"/><meta content="width=device-width,initial-scale=1" name="viewport"/><meta content="#081C42" media="(prefers-color-scheme: light)" name="theme-color"/><meta content="#081C42" media="(prefers-color-scheme: dark)" name="theme-color"/><meta content="MinIO Console" name="description"/><link href="./styles/root-styles.css" rel="stylesheet"/><link href="./apple-icon-180x180.png" rel="apple-touch-icon" sizes="180x180"/><link href="./favicon-32x32.png" rel="icon" sizes="32x32" type="image/png"/><link href="./favicon-96x96.png" rel="icon" sizes="96x96" type="image/png"/><link href="./favicon-16x16.png" rel="icon" sizes="16x16" type="image/png"/><link href="./manifest.json" rel="manifest"/><link color="#3a4e54" href="./safari-pinned-tab.svg" rel="mask-icon"/><title>MinIO Console</title><script defer="defer" src="./static/js/main.eec275cb.js"></script><link href="./static/css/main.90d417ae.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"><div id="preload"><img src="./images/background.svg"/> <img src="./images/background-wave-orig2.svg"/></div><div id="loader-block"><img src="./Loader.svg"/></div></div></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><base href="/"/><meta content="width=device-width,initial-scale=1" name="viewport"/><meta content="#081C42" media="(prefers-color-scheme: light)" name="theme-color"/><meta content="#081C42" media="(prefers-color-scheme: dark)" name="theme-color"/><meta content="MinIO Console" name="description"/><link href="./styles/root-styles.css" rel="stylesheet"/><link href="./apple-icon-180x180.png" rel="apple-touch-icon" sizes="180x180"/><link href="./favicon-32x32.png" rel="icon" sizes="32x32" type="image/png"/><link href="./favicon-96x96.png" rel="icon" sizes="96x96" type="image/png"/><link href="./favicon-16x16.png" rel="icon" sizes="16x16" type="image/png"/><link href="./manifest.json" rel="manifest"/><link color="#3a4e54" href="./safari-pinned-tab.svg" rel="mask-icon"/><title>MinIO Console</title><script defer="defer" src="./static/js/main.55e03c75.js"></script><link href="./static/css/main.90d417ae.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"><div id="preload"><img src="./images/background.svg"/> <img src="./images/background-wave-orig2.svg"/></div><div id="loader-block"><img src="./Loader.svg"/></div></div></body></html>

View File

@@ -1,2 +1,2 @@
.cm-s-dracula .CodeMirror-gutters,.cm-s-dracula.CodeMirror{background-color:#282a36!important;border:none;color:#f8f8f2!important}.cm-s-dracula .CodeMirror-gutters{color:#282a36}.cm-s-dracula .CodeMirror-cursor{border-left:thin solid #f8f8f0}.cm-s-dracula .CodeMirror-linenumber{color:#6d8a88}.cm-s-dracula .CodeMirror-selected{background:hsla(0,0%,100%,.1)}.cm-s-dracula .CodeMirror-line::selection,.cm-s-dracula .CodeMirror-line>span::selection,.cm-s-dracula .CodeMirror-line>span>span::selection{background:hsla(0,0%,100%,.1)}.cm-s-dracula .CodeMirror-line::-moz-selection,.cm-s-dracula .CodeMirror-line>span::-moz-selection,.cm-s-dracula .CodeMirror-line>span>span::-moz-selection{background:hsla(0,0%,100%,.1)}.cm-s-dracula span.cm-comment{color:#6272a4}.cm-s-dracula span.cm-string,.cm-s-dracula span.cm-string-2{color:#f1fa8c}.cm-s-dracula span.cm-number{color:#bd93f9}.cm-s-dracula span.cm-variable{color:#50fa7b}.cm-s-dracula span.cm-variable-2{color:#fff}.cm-s-dracula span.cm-def{color:#50fa7b}.cm-s-dracula span.cm-keyword,.cm-s-dracula span.cm-operator{color:#ff79c6}.cm-s-dracula span.cm-atom{color:#bd93f9}.cm-s-dracula span.cm-meta{color:#f8f8f2}.cm-s-dracula span.cm-tag{color:#ff79c6}.cm-s-dracula span.cm-attribute,.cm-s-dracula span.cm-qualifier{color:#50fa7b}.cm-s-dracula span.cm-property{color:#66d9ef}.cm-s-dracula span.cm-builtin{color:#50fa7b}.cm-s-dracula span.cm-type,.cm-s-dracula span.cm-variable-3{color:#ffb86c}.cm-s-dracula .CodeMirror-activeline-background{background:hsla(0,0%,100%,.1)}.cm-s-dracula .CodeMirror-matchingbracket{color:#fff!important;text-decoration:underline}
/*# sourceMappingURL=1955.8313f811.chunk.css.map*/
/*# sourceMappingURL=2080.e60508f1.chunk.css.map*/

View File

@@ -1 +1 @@
{"version":3,"file":"static/css/3368.8313f811.chunk.css","mappings":"AAUA,2DACE,kCAAoC,CAEpC,WAAY,CADZ,uBAEF,CACA,kCAAoC,aAAgB,CACpD,iCAAmC,8BAAiC,CACpE,qCAAuC,aAAgB,CACvD,mCAAqC,6BAAuC,CAC5E,6IAAuJ,6BAAuC,CAC9L,4JAAsK,6BAAuC,CAC7M,8BAAgC,aAAgB,CAChD,4DAA+D,aAAgB,CAC/E,6BAA+B,aAAgB,CAC/C,+BAAiC,aAAgB,CACjD,iCAAmC,UAAc,CACjD,0BAA4B,aAAgB,CAE5C,6DAAgC,aAAgB,CAChD,2BAA6B,aAAgB,CAC7C,2BAA6B,aAAgB,CAC7C,0BAA4B,aAAgB,CAE5C,gEAAkC,aAAgB,CAClD,+BAAiC,aAAgB,CACjD,8BAAgC,aAAgB,CAChD,4DAA+D,aAAgB,CAE/E,gDAAkD,6BAAmC,CACrF,0CAAwE,oBAAuB,CAAnD,yBAAqD","sources":["../node_modules/codemirror/theme/dracula.css"],"sourcesContent":["/*\n\n Name: dracula\n Author: Michael Kaminsky (http://github.com/mkaminsky11)\n\n Original dracula color scheme by Zeno Rocha (https://github.com/zenorocha/dracula-theme)\n\n*/\n\n\n.cm-s-dracula.CodeMirror, .cm-s-dracula .CodeMirror-gutters {\n background-color: #282a36 !important;\n color: #f8f8f2 !important;\n border: none;\n}\n.cm-s-dracula .CodeMirror-gutters { color: #282a36; }\n.cm-s-dracula .CodeMirror-cursor { border-left: solid thin #f8f8f0; }\n.cm-s-dracula .CodeMirror-linenumber { color: #6D8A88; }\n.cm-s-dracula .CodeMirror-selected { background: rgba(255, 255, 255, 0.10); }\n.cm-s-dracula .CodeMirror-line::selection, .cm-s-dracula .CodeMirror-line > span::selection, .cm-s-dracula .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); }\n.cm-s-dracula .CodeMirror-line::-moz-selection, .cm-s-dracula .CodeMirror-line > span::-moz-selection, .cm-s-dracula .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); }\n.cm-s-dracula span.cm-comment { color: #6272a4; }\n.cm-s-dracula span.cm-string, .cm-s-dracula span.cm-string-2 { color: #f1fa8c; }\n.cm-s-dracula span.cm-number { color: #bd93f9; }\n.cm-s-dracula span.cm-variable { color: #50fa7b; }\n.cm-s-dracula span.cm-variable-2 { color: white; }\n.cm-s-dracula span.cm-def { color: #50fa7b; }\n.cm-s-dracula span.cm-operator { color: #ff79c6; }\n.cm-s-dracula span.cm-keyword { color: #ff79c6; }\n.cm-s-dracula span.cm-atom { color: #bd93f9; }\n.cm-s-dracula span.cm-meta { color: #f8f8f2; }\n.cm-s-dracula span.cm-tag { color: #ff79c6; }\n.cm-s-dracula span.cm-attribute { color: #50fa7b; }\n.cm-s-dracula span.cm-qualifier { color: #50fa7b; }\n.cm-s-dracula span.cm-property { color: #66d9ef; }\n.cm-s-dracula span.cm-builtin { color: #50fa7b; }\n.cm-s-dracula span.cm-variable-3, .cm-s-dracula span.cm-type { color: #ffb86c; }\n\n.cm-s-dracula .CodeMirror-activeline-background { background: rgba(255,255,255,0.1); }\n.cm-s-dracula .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }\n"],"names":[],"sourceRoot":""}
{"version":3,"file":"static/css/2080.e60508f1.chunk.css","mappings":"AAUA,2DACE,kCAAoC,CAEpC,WAAY,CADZ,uBAEF,CACA,kCAAoC,aAAgB,CACpD,iCAAmC,8BAAiC,CACpE,qCAAuC,aAAgB,CACvD,mCAAqC,6BAAuC,CAC5E,6IAAuJ,6BAAuC,CAC9L,4JAAsK,6BAAuC,CAC7M,8BAAgC,aAAgB,CAChD,4DAA+D,aAAgB,CAC/E,6BAA+B,aAAgB,CAC/C,+BAAiC,aAAgB,CACjD,iCAAmC,UAAc,CACjD,0BAA4B,aAAgB,CAE5C,6DAAgC,aAAgB,CAChD,2BAA6B,aAAgB,CAC7C,2BAA6B,aAAgB,CAC7C,0BAA4B,aAAgB,CAE5C,gEAAkC,aAAgB,CAClD,+BAAiC,aAAgB,CACjD,8BAAgC,aAAgB,CAChD,4DAA+D,aAAgB,CAE/E,gDAAkD,6BAAmC,CACrF,0CAAwE,oBAAuB,CAAnD,yBAAqD","sources":["../node_modules/codemirror/theme/dracula.css"],"sourcesContent":["/*\n\n Name: dracula\n Author: Michael Kaminsky (http://github.com/mkaminsky11)\n\n Original dracula color scheme by Zeno Rocha (https://github.com/zenorocha/dracula-theme)\n\n*/\n\n\n.cm-s-dracula.CodeMirror, .cm-s-dracula .CodeMirror-gutters {\n background-color: #282a36 !important;\n color: #f8f8f2 !important;\n border: none;\n}\n.cm-s-dracula .CodeMirror-gutters { color: #282a36; }\n.cm-s-dracula .CodeMirror-cursor { border-left: solid thin #f8f8f0; }\n.cm-s-dracula .CodeMirror-linenumber { color: #6D8A88; }\n.cm-s-dracula .CodeMirror-selected { background: rgba(255, 255, 255, 0.10); }\n.cm-s-dracula .CodeMirror-line::selection, .cm-s-dracula .CodeMirror-line > span::selection, .cm-s-dracula .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); }\n.cm-s-dracula .CodeMirror-line::-moz-selection, .cm-s-dracula .CodeMirror-line > span::-moz-selection, .cm-s-dracula .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); }\n.cm-s-dracula span.cm-comment { color: #6272a4; }\n.cm-s-dracula span.cm-string, .cm-s-dracula span.cm-string-2 { color: #f1fa8c; }\n.cm-s-dracula span.cm-number { color: #bd93f9; }\n.cm-s-dracula span.cm-variable { color: #50fa7b; }\n.cm-s-dracula span.cm-variable-2 { color: white; }\n.cm-s-dracula span.cm-def { color: #50fa7b; }\n.cm-s-dracula span.cm-operator { color: #ff79c6; }\n.cm-s-dracula span.cm-keyword { color: #ff79c6; }\n.cm-s-dracula span.cm-atom { color: #bd93f9; }\n.cm-s-dracula span.cm-meta { color: #f8f8f2; }\n.cm-s-dracula span.cm-tag { color: #ff79c6; }\n.cm-s-dracula span.cm-attribute { color: #50fa7b; }\n.cm-s-dracula span.cm-qualifier { color: #50fa7b; }\n.cm-s-dracula span.cm-property { color: #66d9ef; }\n.cm-s-dracula span.cm-builtin { color: #50fa7b; }\n.cm-s-dracula span.cm-variable-3, .cm-s-dracula span.cm-type { color: #ffb86c; }\n\n.cm-s-dracula .CodeMirror-activeline-background { background: rgba(255,255,255,0.1); }\n.cm-s-dracula .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }\n"],"names":[],"sourceRoot":""}

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