Compare commits
81 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62a8bf05bb | ||
|
|
d8754a2e3e | ||
|
|
64ffa039b4 | ||
|
|
822724a4f1 | ||
|
|
c18c843d03 | ||
|
|
1d362aceaf | ||
|
|
6f5cb4d1a5 | ||
|
|
2cefa0860d | ||
|
|
ea0c83ea74 | ||
|
|
90f64b685e | ||
|
|
62f925d93c | ||
|
|
1985c110b1 | ||
|
|
461bc94a0b | ||
|
|
aaa55a1f4a | ||
|
|
2eecabf5e6 | ||
|
|
fba9bd87df | ||
|
|
bf461b8b27 | ||
|
|
301c4a83b5 | ||
|
|
87468571ae | ||
|
|
7ad2df3e7f | ||
|
|
baef7b5ec0 | ||
|
|
fa8c59360a | ||
|
|
ceeacd2167 | ||
|
|
70214a6578 | ||
|
|
d1a5e5ba57 | ||
|
|
fcd50257ee | ||
|
|
2765fb0c97 | ||
|
|
d22f345d4a | ||
|
|
b658301725 | ||
|
|
1417375d99 | ||
|
|
676420a2b3 | ||
|
|
ffa9436276 | ||
|
|
f6d92d50e4 | ||
|
|
bc1cb820d1 | ||
|
|
8772c158c6 | ||
|
|
d673473d5e | ||
|
|
bb22a1d62a | ||
|
|
f582d83afc | ||
|
|
b12fa5edfd | ||
|
|
65eee7c1d0 | ||
|
|
de4cf3b554 | ||
|
|
cca04dca1c | ||
|
|
bef3897d0a | ||
|
|
842c3dee5f | ||
|
|
d1d39df71e | ||
|
|
2321343d5e | ||
|
|
ce4d9310aa | ||
|
|
58c53cbe0a | ||
|
|
144979b372 | ||
|
|
e29fa04051 | ||
|
|
5ab5232474 | ||
|
|
d7fef8d89e | ||
|
|
3a09361899 | ||
|
|
6ca17a3f9c | ||
|
|
6d40ff7e1b | ||
|
|
0b29eee9ed | ||
|
|
c7fdfdd035 | ||
|
|
d7626e187c | ||
|
|
39453de8fb | ||
|
|
0c38e93b83 | ||
|
|
bf8db812b8 | ||
|
|
0e35da8370 | ||
|
|
b11fa26162 | ||
|
|
e3836538fc | ||
|
|
9301e3b7de | ||
|
|
cf5e5a14b5 | ||
|
|
7f4546e879 | ||
|
|
1a92c59e3f | ||
|
|
ade9731773 | ||
|
|
cc43b3c743 | ||
|
|
b29f6a1640 | ||
|
|
62b8258989 | ||
|
|
75bc568e4b | ||
|
|
b0119a55df | ||
|
|
78983ce76f | ||
|
|
e060e1d97e | ||
|
|
82bdc228b2 | ||
|
|
1fa8311af7 | ||
|
|
93243f2c77 | ||
|
|
3b423826fd | ||
|
|
e44a7c94c6 |
94
.github/workflows/common.sh
vendored
Executable file
94
.github/workflows/common.sh
vendored
Executable file
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (C) 2022, MinIO, Inc.
|
||||
#
|
||||
# This code is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License, version 3,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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, version 3,
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
yell() { echo "$0: $*" >&2; }
|
||||
|
||||
die() {
|
||||
yell "$*"
|
||||
(kind delete cluster || true ) && exit 111
|
||||
}
|
||||
|
||||
try() { "$@" || die "cannot $*"; }
|
||||
|
||||
function setup_kind() {
|
||||
# TODO once feature is added: https://github.com/kubernetes-sigs/kind/issues/1300
|
||||
echo "kind: Cluster" > kind-config.yaml
|
||||
echo "apiVersion: kind.x-k8s.io/v1alpha4" >> kind-config.yaml
|
||||
echo "nodes:" >> kind-config.yaml
|
||||
echo " - role: control-plane" >> kind-config.yaml
|
||||
echo " - role: worker" >> kind-config.yaml
|
||||
echo " - role: worker" >> kind-config.yaml
|
||||
echo " - role: worker" >> kind-config.yaml
|
||||
echo " - role: worker" >> kind-config.yaml
|
||||
try kind create cluster --config kind-config.yaml
|
||||
echo "Kind is ready"
|
||||
try kubectl get nodes
|
||||
}
|
||||
|
||||
function install_operator() {
|
||||
echo "Installing Current Operator"
|
||||
|
||||
# TODO: Compile the current branch and create an overlay to use that image version
|
||||
try kubectl apply -k "${SCRIPT_DIR}/../../portal-ui/tests/scripts/resources"
|
||||
|
||||
echo "Waiting for k8s api"
|
||||
sleep 10
|
||||
echo "Waiting for Operator Pods to come online (2m timeout)"
|
||||
|
||||
try kubectl wait --namespace minio-operator \
|
||||
--for=condition=ready pod \
|
||||
--selector=name=minio-operator \
|
||||
--timeout=120s
|
||||
}
|
||||
|
||||
function destroy_kind() {
|
||||
kind delete cluster
|
||||
}
|
||||
|
||||
function check_tenant_status() {
|
||||
# Check MinIO is accessible
|
||||
|
||||
waitdone=0
|
||||
totalwait=0
|
||||
while true; do
|
||||
waitdone=$(kubectl -n $1 get pods -l v1.min.io/tenant=$2 --no-headers | wc -l)
|
||||
if [ "$waitdone" -ne 0 ]; then
|
||||
echo "Found $waitdone pods"
|
||||
break
|
||||
fi
|
||||
sleep 5
|
||||
totalwait=$((totalwait + 5))
|
||||
if [ "$totalwait" -gt 305 ]; then
|
||||
echo "Unable to create tenant after 5 minutes, exiting."
|
||||
try false
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Waiting for pods to be ready. (5m timeout)"
|
||||
|
||||
USER=$(kubectl -n $1 get secrets $2-env-configuration -o go-template='{{index .data "config.env"|base64decode }}' | grep 'export MINIO_ROOT_USER="' | sed -e 's/export MINIO_ROOT_USER="//g' | sed -e 's/"//g')
|
||||
PASSWORD=$(kubectl -n $1 get secrets $2-env-configuration -o go-template='{{index .data "config.env"|base64decode }}' | grep 'export MINIO_ROOT_PASSWORD="' | sed -e 's/export MINIO_ROOT_PASSWORD="//g' | sed -e 's/"//g')
|
||||
|
||||
try kubectl wait --namespace $1 \
|
||||
--for=condition=ready pod \
|
||||
--selector=v1.min.io/tenant=$2 \
|
||||
--timeout=300s
|
||||
|
||||
echo "Tenant is created successfully, proceeding to validate 'mc admin info minio/'"
|
||||
|
||||
kubectl run admin-mc -i --tty --image minio/mc --command -- bash -c "until (mc alias set minio/ https://minio.$1.svc.cluster.local $USER $PASSWORD); do echo \"...waiting... for 5secs\" && sleep 5; done; mc admin info minio/;"
|
||||
|
||||
echo "Done."
|
||||
}
|
||||
71
.github/workflows/deploy-tenant.sh
vendored
Executable file
71
.github/workflows/deploy-tenant.sh
vendored
Executable file
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (C) 2022, MinIO, Inc.
|
||||
#
|
||||
# This code is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License, version 3,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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, version 3,
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
# This script requires: kubectl, kind
|
||||
|
||||
SCRIPT_DIR=$(dirname "$0")
|
||||
export SCRIPT_DIR
|
||||
|
||||
source "${SCRIPT_DIR}/common.sh"
|
||||
|
||||
|
||||
|
||||
function install_tenant() {
|
||||
echo "Installing lite tenant"
|
||||
|
||||
try kubectl apply -k "${SCRIPT_DIR}/../../portal-ui/tests/scripts/tenant"
|
||||
|
||||
echo "Waiting for the tenant statefulset, this indicates the tenant is being fulfilled"
|
||||
waitdone=0
|
||||
totalwait=0
|
||||
while true; do
|
||||
waitdone=$(kubectl -n tenant-lite get pods -l v1.min.io/tenant=storage-lite --no-headers | wc -l)
|
||||
if [ "$waitdone" -ne 0 ]; then
|
||||
echo "Found $waitdone pods"
|
||||
break
|
||||
fi
|
||||
sleep 5
|
||||
totalwait=$((totalwait + 5))
|
||||
if [ "$totalwait" -gt 300 ]; then
|
||||
echo "Tenant never created statefulset after 5 minutes"
|
||||
try false
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Waiting for tenant pods to come online (5m timeout)"
|
||||
try kubectl wait --namespace tenant-lite \
|
||||
--for=condition=ready pod \
|
||||
--selector="v1.min.io/tenant=storage-lite" \
|
||||
--timeout=300s
|
||||
|
||||
echo "Build passes basic tenant creation"
|
||||
}
|
||||
|
||||
|
||||
function main() {
|
||||
destroy_kind
|
||||
|
||||
setup_kind
|
||||
|
||||
install_operator
|
||||
|
||||
install_tenant
|
||||
|
||||
check_tenant_status tenant-lite storage-lite
|
||||
|
||||
kubectl -n minio-operator port-forward svc/console 9090 &
|
||||
}
|
||||
|
||||
main "$@"
|
||||
689
.github/workflows/jobs.yaml
vendored
689
.github/workflows/jobs.yaml
vendored
@@ -15,6 +15,192 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
|
||||
replication:
|
||||
|
||||
name: Site Replication Test
|
||||
needs:
|
||||
- lint-job
|
||||
- no-warnings-and-make-assets
|
||||
- reuse-golang-dependencies
|
||||
- vulnerable-dependencies-checks
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [ 1.17.x ]
|
||||
|
||||
steps:
|
||||
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# To build minio image, we need to clone the repository first
|
||||
- name: clone https://github.com/minio/minio
|
||||
uses: actions/checkout@master
|
||||
with:
|
||||
|
||||
# Repository name with owner. For example, actions/checkout
|
||||
# Default: ${{ github.repository }}
|
||||
repository: minio/minio
|
||||
|
||||
# Relative path under $GITHUB_WORKSPACE to place the repository
|
||||
# To have two repositories under the same test
|
||||
path: 'minio_repository'
|
||||
|
||||
- uses: actions/cache@v2
|
||||
name: Go Mod Cache
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ github.run_id }}
|
||||
|
||||
- name: Build on ${{ matrix.os }}
|
||||
run: |
|
||||
echo "The idea is to build minio image from downloaded repository";
|
||||
cd $GITHUB_WORKSPACE/minio_repository;
|
||||
echo "Get git version to build MinIO Image";
|
||||
VERSION=`git rev-parse HEAD`;
|
||||
echo $VERSION;
|
||||
echo "Create minio image";
|
||||
make docker VERSION=$VERSION;
|
||||
echo "Jumping back to console repository to run the integration test"
|
||||
cd $GITHUB_WORKSPACE;
|
||||
echo "We are going to use the built image on test-integration";
|
||||
VERSION="minio/minio:$VERSION";
|
||||
echo $VERSION;
|
||||
make test-replication MINIO_VERSION=$VERSION;
|
||||
- uses: actions/cache@v2
|
||||
id: coverage-cache-replication
|
||||
name: Coverage Cache Replication
|
||||
with:
|
||||
path: |
|
||||
./replication/coverage/
|
||||
key: ${{ runner.os }}-replication-coverage-2-${{ github.run_id }}
|
||||
|
||||
sso-integration:
|
||||
|
||||
name: SSO Integration Test
|
||||
needs:
|
||||
- lint-job
|
||||
- no-warnings-and-make-assets
|
||||
- reuse-golang-dependencies
|
||||
- vulnerable-dependencies-checks
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [ 1.17.x ]
|
||||
|
||||
steps:
|
||||
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# To build minio image, we need to clone the repository first
|
||||
- name: clone https://github.com/minio/minio
|
||||
uses: actions/checkout@master
|
||||
with:
|
||||
|
||||
# Repository name with owner. For example, actions/checkout
|
||||
# Default: ${{ github.repository }}
|
||||
repository: minio/minio
|
||||
|
||||
# Relative path under $GITHUB_WORKSPACE to place the repository
|
||||
# To have two repositories under the same test
|
||||
path: 'minio_repository'
|
||||
|
||||
- uses: actions/cache@v2
|
||||
name: Go Mod Cache
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ github.run_id }}
|
||||
|
||||
- name: Build on ${{ matrix.os }}
|
||||
run: |
|
||||
echo "The idea is to build minio image from downloaded repository";
|
||||
cd $GITHUB_WORKSPACE/minio_repository;
|
||||
echo "Get git version to build MinIO Image";
|
||||
VERSION=`git rev-parse HEAD`;
|
||||
echo $VERSION;
|
||||
echo "Create minio image";
|
||||
make docker VERSION=$VERSION;
|
||||
echo "Jumping back to console repository to run the integration test"
|
||||
cd $GITHUB_WORKSPACE;
|
||||
echo "We are going to use the built image on test-integration";
|
||||
VERSION="minio/minio:$VERSION";
|
||||
echo $VERSION;
|
||||
make test-sso-integration MINIO_VERSION=$VERSION;
|
||||
- uses: actions/cache@v2
|
||||
id: coverage-cache-sso
|
||||
name: Coverage Cache SSO
|
||||
with:
|
||||
path: |
|
||||
./sso-integration/coverage/
|
||||
key: ${{ runner.os }}-sso-coverage-2-${{ github.run_id }}
|
||||
|
||||
c-operator-api-tests:
|
||||
|
||||
name: Operator API Tests
|
||||
needs:
|
||||
- lint-job
|
||||
- no-warnings-and-make-assets
|
||||
- reuse-golang-dependencies
|
||||
- vulnerable-dependencies-checks
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [ 1.17.x ]
|
||||
|
||||
steps:
|
||||
|
||||
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
id: go
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/cache@v2
|
||||
name: Go Mod Cache
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ github.run_id }}
|
||||
|
||||
- name: Operator API Tests
|
||||
run: |
|
||||
curl -sLO "https://dl.k8s.io/release/v1.23.1/bin/linux/amd64/kubectl" -o kubectl
|
||||
chmod +x kubectl
|
||||
mv kubectl /usr/local/bin
|
||||
"${GITHUB_WORKSPACE}/.github/workflows/deploy-tenant.sh"
|
||||
echo "start ---> make test-operator-integration";
|
||||
make test-operator-integration;
|
||||
|
||||
- uses: actions/cache@v2
|
||||
id: coverage-cache-operator
|
||||
name: Coverage Cache Operator
|
||||
with:
|
||||
path: |
|
||||
./operator-integration/coverage/
|
||||
key: ${{ runner.os }}-coverage-2-operator-${{ github.run_id }}
|
||||
|
||||
lint-job:
|
||||
name: Checking Lint
|
||||
runs-on: ${{ matrix.os }}
|
||||
@@ -157,6 +343,315 @@ jobs:
|
||||
~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ github.run_id }}
|
||||
|
||||
all-permissions-1:
|
||||
name: Permissions Tests Part 1
|
||||
needs:
|
||||
- lint-job
|
||||
- no-warnings-and-make-assets
|
||||
- reuse-golang-dependencies
|
||||
- vulnerable-dependencies-checks
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [ 1.17.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
id: go
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '16'
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
|
||||
- uses: actions/cache@v2
|
||||
id: yarn-cache
|
||||
name: Yarn Cache
|
||||
with:
|
||||
path: |
|
||||
${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
./portal-ui/node_modules/
|
||||
./portal-ui/build/
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('./portal-ui/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
|
||||
- uses: actions/cache@v2
|
||||
id: assets-cache
|
||||
name: Assets Cache
|
||||
with:
|
||||
path: |
|
||||
./portal-ui/build/
|
||||
key: ${{ runner.os }}-assets-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-assets-
|
||||
|
||||
- uses: actions/cache@v2
|
||||
name: Go Mod Cache
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ github.run_id }}
|
||||
|
||||
- name: Build Console on ${{ matrix.os }}
|
||||
env:
|
||||
GO111MODULE: on
|
||||
GOOS: linux
|
||||
run: |
|
||||
make console
|
||||
|
||||
- name: Start Console, front-end app and initialize users/policies
|
||||
run: |
|
||||
(./console server) & (make initialize-permissions)
|
||||
|
||||
- name: Run TestCafe Tests
|
||||
uses: DevExpress/testcafe-action@latest
|
||||
with:
|
||||
args: '"chrome:headless" portal-ui/tests/permissions-1/ --skip-js-errors -c 3'
|
||||
|
||||
- name: Clean up users & policies
|
||||
run: |
|
||||
make cleanup-permissions
|
||||
|
||||
all-permissions-2:
|
||||
name: Permissions Tests Part 2
|
||||
needs:
|
||||
- lint-job
|
||||
- no-warnings-and-make-assets
|
||||
- reuse-golang-dependencies
|
||||
- vulnerable-dependencies-checks
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [ 1.17.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
id: go
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '16'
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
|
||||
- uses: actions/cache@v2
|
||||
id: yarn-cache
|
||||
name: Yarn Cache
|
||||
with:
|
||||
path: |
|
||||
${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
./portal-ui/node_modules/
|
||||
./portal-ui/build/
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('./portal-ui/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
|
||||
- uses: actions/cache@v2
|
||||
id: assets-cache
|
||||
name: Assets Cache
|
||||
with:
|
||||
path: |
|
||||
./portal-ui/build/
|
||||
key: ${{ runner.os }}-assets-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-assets-
|
||||
|
||||
- uses: actions/cache@v2
|
||||
name: Go Mod Cache
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ github.run_id }}
|
||||
|
||||
- name: Build Console on ${{ matrix.os }}
|
||||
env:
|
||||
GO111MODULE: on
|
||||
GOOS: linux
|
||||
run: |
|
||||
make console
|
||||
|
||||
- name: Start Console, front-end app and initialize users/policies
|
||||
run: |
|
||||
(./console server) & (make initialize-permissions)
|
||||
|
||||
- name: Run TestCafe Tests
|
||||
uses: DevExpress/testcafe-action@latest
|
||||
with:
|
||||
args: '"chrome:headless" portal-ui/tests/permissions-2/ --skip-js-errors -c 3'
|
||||
|
||||
- name: Clean up users & policies
|
||||
run: |
|
||||
make cleanup-permissions
|
||||
|
||||
all-permissions-3:
|
||||
name: Permissions Tests Part 3
|
||||
needs:
|
||||
- lint-job
|
||||
- no-warnings-and-make-assets
|
||||
- reuse-golang-dependencies
|
||||
- vulnerable-dependencies-checks
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [ 1.17.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
id: go
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '16'
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
|
||||
- uses: actions/cache@v2
|
||||
id: yarn-cache
|
||||
name: Yarn Cache
|
||||
with:
|
||||
path: |
|
||||
${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
./portal-ui/node_modules/
|
||||
./portal-ui/build/
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('./portal-ui/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
|
||||
- uses: actions/cache@v2
|
||||
id: assets-cache
|
||||
name: Assets Cache
|
||||
with:
|
||||
path: |
|
||||
./portal-ui/build/
|
||||
key: ${{ runner.os }}-assets-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-assets-
|
||||
|
||||
- uses: actions/cache@v2
|
||||
name: Go Mod Cache
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ github.run_id }}
|
||||
|
||||
- name: Build Console on ${{ matrix.os }}
|
||||
env:
|
||||
GO111MODULE: on
|
||||
GOOS: linux
|
||||
run: |
|
||||
make console
|
||||
|
||||
- name: Start Console, front-end app and initialize users/policies
|
||||
run: |
|
||||
(./console server) & (make initialize-permissions)
|
||||
|
||||
- name: Run TestCafe Tests
|
||||
uses: DevExpress/testcafe-action@latest
|
||||
with:
|
||||
args: '"chrome:headless" portal-ui/tests/permissions-3/ --skip-js-errors -c 3'
|
||||
|
||||
- name: Clean up users & policies
|
||||
run: |
|
||||
make cleanup-permissions
|
||||
|
||||
|
||||
|
||||
all-operator-tests:
|
||||
name: Operator UI Tests
|
||||
needs:
|
||||
- lint-job
|
||||
- no-warnings-and-make-assets
|
||||
- reuse-golang-dependencies
|
||||
- vulnerable-dependencies-checks
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [ 1.17.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
id: go
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '16'
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
name: Go Mod Cache
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ github.run_id }}
|
||||
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
|
||||
- uses: actions/cache@v2
|
||||
id: yarn-cache
|
||||
name: Yarn Cache
|
||||
with:
|
||||
path: |
|
||||
${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
./portal-ui/node_modules/
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('./portal-ui/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
|
||||
- uses: actions/cache@v2
|
||||
id: assets-cache
|
||||
name: Assets Cache
|
||||
with:
|
||||
path: |
|
||||
./portal-ui/build/
|
||||
key: ${{ runner.os }}-assets-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-assets-
|
||||
|
||||
- name: Build Console on ${{ matrix.os }}
|
||||
env:
|
||||
GO111MODULE: on
|
||||
GOOS: linux
|
||||
run: |
|
||||
make console
|
||||
|
||||
# Runs a set of commands using the runners shell
|
||||
- name: Start Kind for Operator UI
|
||||
run: |
|
||||
"${GITHUB_WORKSPACE}/portal-ui/tests/scripts/operator.sh"
|
||||
|
||||
- name: Run TestCafe Tests
|
||||
uses: DevExpress/testcafe-action@latest
|
||||
with:
|
||||
args: '"chrome:headless" portal-ui/tests/operator/ --skip-js-errors -c 3'
|
||||
|
||||
compile-job:
|
||||
name: Compiles on Go ${{ matrix.go-version }} and ${{ matrix.os }}
|
||||
needs:
|
||||
@@ -461,7 +956,7 @@ jobs:
|
||||
./restapi/coverage/
|
||||
key: ${{ runner.os }}-coverage-restapi-2-${{ github.run_id }}
|
||||
|
||||
integration-tests:
|
||||
b-integration-tests:
|
||||
name: Integration Tests with Latest Distributed MinIO
|
||||
needs:
|
||||
- lint-job
|
||||
@@ -546,162 +1041,15 @@ jobs:
|
||||
working-directory: ./portal-ui
|
||||
run: yarn test
|
||||
|
||||
operator-tests:
|
||||
name: Operator Tests
|
||||
needs:
|
||||
- lint-job
|
||||
- no-warnings-and-make-assets
|
||||
- reuse-golang-dependencies
|
||||
- vulnerable-dependencies-checks
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [ 1.17.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
id: go
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '17'
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
name: Go Mod Cache
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ github.run_id }}
|
||||
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
|
||||
- uses: actions/cache@v2
|
||||
id: yarn-cache
|
||||
name: Yarn Cache
|
||||
with:
|
||||
path: |
|
||||
${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
./portal-ui/node_modules/
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('./portal-ui/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
|
||||
- uses: actions/cache@v2
|
||||
id: assets-cache
|
||||
name: Assets Cache
|
||||
with:
|
||||
path: |
|
||||
./portal-ui/build/
|
||||
key: ${{ runner.os }}-assets-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-assets-
|
||||
|
||||
- name: Build Console on ${{ matrix.os }}
|
||||
env:
|
||||
GO111MODULE: on
|
||||
GOOS: linux
|
||||
run: |
|
||||
make console
|
||||
|
||||
# Runs a set of commands using the runners shell
|
||||
- name: Start Kind for Operator UI
|
||||
run: |
|
||||
"${GITHUB_WORKSPACE}/portal-ui/tests/scripts/operator.sh"
|
||||
|
||||
- name: Run TestCafe Tests
|
||||
uses: DevExpress/testcafe-action@latest
|
||||
with:
|
||||
args: '"chrome:headless" portal-ui/tests/operator/ --skip-js-errors -c 3'
|
||||
|
||||
permissions:
|
||||
name: Permissions Tests
|
||||
needs:
|
||||
- lint-job
|
||||
- no-warnings-and-make-assets
|
||||
- reuse-golang-dependencies
|
||||
- vulnerable-dependencies-checks
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [ 1.17.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
id: go
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '17'
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
|
||||
- uses: actions/cache@v2
|
||||
id: yarn-cache
|
||||
name: Yarn Cache
|
||||
with:
|
||||
path: |
|
||||
${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
./portal-ui/node_modules/
|
||||
./portal-ui/build/
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('./portal-ui/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
|
||||
- uses: actions/cache@v2
|
||||
id: assets-cache
|
||||
name: Assets Cache
|
||||
with:
|
||||
path: |
|
||||
./portal-ui/build/
|
||||
key: ${{ runner.os }}-assets-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-assets-
|
||||
|
||||
- uses: actions/cache@v2
|
||||
name: Go Mod Cache
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ github.run_id }}
|
||||
|
||||
- name: Build Console on ${{ matrix.os }}
|
||||
env:
|
||||
GO111MODULE: on
|
||||
GOOS: linux
|
||||
run: |
|
||||
make console
|
||||
|
||||
- name: Start Console, front-end app and initialize users/policies
|
||||
run: |
|
||||
(./console server) & (make initialize-permissions)
|
||||
|
||||
- name: Run TestCafe Tests
|
||||
uses: DevExpress/testcafe-action@latest
|
||||
with:
|
||||
args: '"chrome:headless" portal-ui/tests/permissions/ --skip-js-errors -c 3'
|
||||
|
||||
- name: Clean up users & policies
|
||||
run: |
|
||||
make cleanup-permissions
|
||||
|
||||
coverage:
|
||||
name: "Coverage Limit Check"
|
||||
needs:
|
||||
- integration-tests
|
||||
- b-integration-tests
|
||||
- test-restapi-on-go
|
||||
- c-operator-api-tests
|
||||
- test-pkg-on-go
|
||||
- sso-integration
|
||||
- replication
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
@@ -713,9 +1061,6 @@ jobs:
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
id: go
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '17'
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
- name: Check out gocovmerge as a nested repository
|
||||
@@ -739,6 +1084,30 @@ jobs:
|
||||
./integration/coverage/
|
||||
key: ${{ runner.os }}-coverage-2-${{ github.run_id }}
|
||||
|
||||
- uses: actions/cache@v2
|
||||
id: coverage-cache-sso
|
||||
name: Coverage Cache SSO
|
||||
with:
|
||||
path: |
|
||||
./sso-integration/coverage/
|
||||
key: ${{ runner.os }}-sso-coverage-2-${{ github.run_id }}
|
||||
|
||||
- uses: actions/cache@v2
|
||||
id: coverage-cache-replication
|
||||
name: Coverage Cache Replication
|
||||
with:
|
||||
path: |
|
||||
./replication/coverage/
|
||||
key: ${{ runner.os }}-replication-coverage-2-${{ github.run_id }}
|
||||
|
||||
- uses: actions/cache@v2
|
||||
id: coverage-cache-operator
|
||||
name: Coverage Cache Operator
|
||||
with:
|
||||
path: |
|
||||
./operator-integration/coverage/
|
||||
key: ${{ runner.os }}-coverage-2-operator-${{ github.run_id }}
|
||||
|
||||
- uses: actions/cache@v2
|
||||
id: coverage-cache-restapi
|
||||
name: Coverage Cache RestAPI
|
||||
@@ -766,17 +1135,17 @@ jobs:
|
||||
echo "go build gocoverage.go"
|
||||
go build gocovmerge.go
|
||||
echo "put together the outs for final coverage resolution"
|
||||
./gocovmerge ../integration/coverage/system.out ../restapi/coverage/coverage.out ../pkg/coverage/coverage-pkg.out > all.out
|
||||
./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 "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=49.4
|
||||
threshold=54.00
|
||||
if (( $(echo "$result >= $threshold" |bc -l) )); then
|
||||
echo "greater than threshold, passed!"
|
||||
echo "It is equal or greater than threshold, passed!"
|
||||
else
|
||||
echo "smaller than threshold, failed!"
|
||||
echo "It is smaller than threshold value, failed!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
126
Makefile
126
Makefile
@@ -72,21 +72,135 @@ test-integration:
|
||||
@(docker network create --subnet=173.18.0.0/29 mynet123)
|
||||
@echo "docker run with MinIO Version below:"
|
||||
@echo $(MINIO_VERSION)
|
||||
@(docker run -v /data1 -v /data2 -v /data3 -v /data4 --net=mynet123 -d --name minio --rm -p 9000:9000 -e MINIO_KMS_SECRET_KEY=my-minio-key:OSMM+vkKUTCvQs9YL/CVMIMt43HFhkUpqJxTmGl6rYw= $(MINIO_VERSION) server /data{1...4} && sleep 5)
|
||||
@(docker run -v /data1 -v /data2 -v /data3 -v /data4 --net=mynet123 -d --name minio --rm -p 9000:9000 -p 9001:9001 -e MINIO_KMS_SECRET_KEY=my-minio-key:OSMM+vkKUTCvQs9YL/CVMIMt43HFhkUpqJxTmGl6rYw= $(MINIO_VERSION) server /data{1...4} --console-address ':9001' && sleep 5)
|
||||
@(docker run --net=mynet123 --ip=173.18.0.3 --name pgsqlcontainer --rm -p 5432:5432 -e POSTGRES_PASSWORD=password -d postgres && sleep 5)
|
||||
@echo "execute test and get coverage"
|
||||
@(cd integration && go test -coverpkg=../restapi -c -tags testrunmain . && mkdir -p coverage && ./integration.test -test.run "^Test*" -test.coverprofile=coverage/system.out)
|
||||
@(cd integration && go test -coverpkg=../restapi -c -tags testrunmain . && mkdir -p coverage && ./integration.test -test.v -test.run "^Test*" -test.coverprofile=coverage/system.out)
|
||||
@(docker stop pgsqlcontainer)
|
||||
@(docker stop minio)
|
||||
@(docker network rm mynet123)
|
||||
|
||||
test-replication:
|
||||
@(docker stop minio || true)
|
||||
@(docker stop minio1 || true)
|
||||
@(docker stop minio2 || true)
|
||||
@(docker network rm mynet123 || true)
|
||||
@(docker network create mynet123)
|
||||
@(docker run -v /data1 -v /data2 -v /data3 -v /data4 \
|
||||
--net=mynet123 -d \
|
||||
--name minio \
|
||||
--rm \
|
||||
-p 9000:9000 \
|
||||
-p 6000:6000 \
|
||||
-e MINIO_KMS_SECRET_KEY=my-minio-key:OSMM+vkKUTCvQs9YL/CVMIMt43HFhkUpqJxTmGl6rYw= \
|
||||
-e MINIO_ROOT_USER="minioadmin" \
|
||||
-e MINIO_ROOT_PASSWORD="minioadmin" \
|
||||
$(MINIO_VERSION) server /data{1...4} \
|
||||
--address :9000 \
|
||||
--console-address :6000)
|
||||
@(docker run -v /data1 -v /data2 -v /data3 -v /data4 \
|
||||
--net=mynet123 -d \
|
||||
--name minio1 \
|
||||
--rm \
|
||||
-p 9001:9001 \
|
||||
-p 6001:6001 \
|
||||
-e MINIO_KMS_SECRET_KEY=my-minio-key:OSMM+vkKUTCvQs9YL/CVMIMt43HFhkUpqJxTmGl6rYw= \
|
||||
-e MINIO_ROOT_USER="minioadmin" \
|
||||
-e MINIO_ROOT_PASSWORD="minioadmin" \
|
||||
$(MINIO_VERSION) server /data{1...4} \
|
||||
--address :9001 \
|
||||
--console-address :6001)
|
||||
@(docker run -v /data1 -v /data2 -v /data3 -v /data4 \
|
||||
--net=mynet123 -d \
|
||||
--name minio2 \
|
||||
--rm \
|
||||
-p 9002:9002 \
|
||||
-p 6002:6002 \
|
||||
-e MINIO_KMS_SECRET_KEY=my-minio-key:OSMM+vkKUTCvQs9YL/CVMIMt43HFhkUpqJxTmGl6rYw= \
|
||||
-e MINIO_ROOT_USER="minioadmin" \
|
||||
-e MINIO_ROOT_PASSWORD="minioadmin" \
|
||||
$(MINIO_VERSION) server /data{1...4} \
|
||||
--address :9002 \
|
||||
--console-address :6002)
|
||||
@(cd replication && go test -coverpkg=../restapi -c -tags testrunmain . && mkdir -p coverage && ./replication.test -test.v -test.run "^Test*" -test.coverprofile=coverage/replication.out)
|
||||
@(docker stop minio || true)
|
||||
@(docker stop minio1 || true)
|
||||
@(docker stop minio2 || true)
|
||||
@(docker network rm mynet123 || true)
|
||||
|
||||
test-sso-integration:
|
||||
@echo "create the network in bridge mode to communicate all containers"
|
||||
@(docker network create my-net)
|
||||
@echo "execute latest keycloak container"
|
||||
@(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"
|
||||
@(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)
|
||||
@echo "running minio server"
|
||||
@(docker run \
|
||||
-v /data1 -v /data2 -v /data3 -v /data4 \
|
||||
--network my-net \
|
||||
-d \
|
||||
--name minio \
|
||||
--rm \
|
||||
-p 9000:9000 \
|
||||
-p 9001:9001 \
|
||||
-e MINIO_IDENTITY_OPENID_CLIENT_SECRET=0nfJuqIt0iPnRIUJkvetve5l38C6gi9W \
|
||||
-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"
|
||||
@(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 "starting bash script"
|
||||
@(env bash $(PWD)/sso-integration/set-sso.sh)
|
||||
@echo "install jq"
|
||||
@(sudo apt install jq)
|
||||
@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)
|
||||
|
||||
test-operator-integration:
|
||||
@(echo "Start cd operator-integration && go test:")
|
||||
@(pwd)
|
||||
@(cd operator-integration && go test -coverpkg=../restapi -c -tags testrunmain . && mkdir -p coverage && ./operator-integration.test -test.v -test.run "^Test*" -test.coverprofile=coverage/operator-api.out)
|
||||
|
||||
test-operator:
|
||||
@(env bash $(PWD)/portal-ui/tests/scripts/operator.sh)
|
||||
@(docker stop minio)
|
||||
|
||||
test-permissions:
|
||||
test-permissions-1:
|
||||
@(docker run -v /data1 -v /data2 -v /data3 -v /data4 -d --name minio --rm -p 9000:9000 quay.io/minio/minio:latest server /data{1...4})
|
||||
@(env bash $(PWD)/portal-ui/tests/scripts/permissions.sh)
|
||||
@(env bash $(PWD)/portal-ui/tests/scripts/permissions.sh "portal-ui/tests/permissions-1/")
|
||||
@(docker stop minio)
|
||||
|
||||
test-permissions-2:
|
||||
@(docker run -v /data1 -v /data2 -v /data3 -v /data4 -d --name minio --rm -p 9000:9000 quay.io/minio/minio:latest server /data{1...4})
|
||||
@(env bash $(PWD)/portal-ui/tests/scripts/permissions.sh "portal-ui/tests/permissions-2/")
|
||||
@(docker stop minio)
|
||||
|
||||
test-permissions-3:
|
||||
@(docker run -v /data1 -v /data2 -v /data3 -v /data4 -d --name minio --rm -p 9000:9000 quay.io/minio/minio:latest server /data{1...4})
|
||||
@(env bash $(PWD)/portal-ui/tests/scripts/permissions.sh "portal-ui/tests/permissions-3/")
|
||||
@(docker stop minio)
|
||||
|
||||
test-apply-permissions:
|
||||
@@ -107,11 +221,11 @@ cleanup-permissions:
|
||||
|
||||
test:
|
||||
@echo "execute test and get coverage"
|
||||
@(cd restapi && mkdir coverage && GO111MODULE=on go test -coverprofile=coverage/coverage.out)
|
||||
@(cd restapi && mkdir coverage && GO111MODULE=on go test -test.v -coverprofile=coverage/coverage.out)
|
||||
|
||||
test-pkg:
|
||||
@echo "execute test and get coverage"
|
||||
@(cd pkg && mkdir coverage && GO111MODULE=on go test -coverprofile=coverage/coverage-pkg.out)
|
||||
@(cd pkg && mkdir coverage && GO111MODULE=on go test -test.v -coverprofile=coverage/coverage-pkg.out)
|
||||
|
||||
coverage:
|
||||
@(GO111MODULE=on go test -v -coverprofile=coverage.out github.com/minio/console/restapi/... && go tool cover -html=coverage.out && open coverage.html)
|
||||
|
||||
@@ -58,16 +58,6 @@ func GetNsFromFile() string {
|
||||
return string(dat)
|
||||
}
|
||||
|
||||
// Namespace will run only once at console startup
|
||||
var Namespace = GetNsFromFile()
|
||||
|
||||
var latestMinIOImage, errLatestMinIOImage = utils.GetLatestMinIOImage(
|
||||
&utils.HTTPClient{
|
||||
Client: &http.Client{
|
||||
Timeout: 15 * time.Second,
|
||||
},
|
||||
})
|
||||
|
||||
// GetMinioImage returns the image URL to be used when deploying a MinIO instance, if there is
|
||||
// a preferred image to be used (configured via ENVIRONMENT VARIABLES) GetMinioImage will return that
|
||||
// if not, GetMinioImage will try to obtain the image URL for the latest version of MinIO and return that
|
||||
@@ -77,17 +67,15 @@ func GetMinioImage() (*string, error) {
|
||||
if image != "" {
|
||||
return &image, nil
|
||||
}
|
||||
latestMinIOImage, errLatestMinIOImage := utils.GetLatestMinIOImage(
|
||||
&utils.HTTPClient{
|
||||
Client: &http.Client{
|
||||
Timeout: 5 * time.Second,
|
||||
},
|
||||
})
|
||||
|
||||
if errLatestMinIOImage != nil {
|
||||
return nil, errLatestMinIOImage
|
||||
}
|
||||
return latestMinIOImage, nil
|
||||
}
|
||||
|
||||
// GetLatestMinioImage returns the latest image URL on minio repository
|
||||
func GetLatestMinioImage(client utils.HTTPClientI) (*string, error) {
|
||||
latestMinIOImage, err := utils.GetLatestMinIOImage(client)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return latestMinIOImage, nil
|
||||
}
|
||||
|
||||
@@ -20,5 +20,4 @@ const (
|
||||
ConsoleK8sAPIServer = "CONSOLE_K8S_API_SERVER"
|
||||
ConsoleK8SAPIServerTLSRootCA = "CONSOLE_K8S_API_SERVER_TLS_ROOT_CA"
|
||||
ConsoleMinioImage = "CONSOLE_MINIO_IMAGE"
|
||||
ConsoleMCImage = "CONSOLE_MC_IMAGE"
|
||||
)
|
||||
|
||||
2
go.mod
2
go.mod
@@ -22,7 +22,7 @@ require (
|
||||
github.com/minio/madmin-go v1.3.5
|
||||
github.com/minio/mc v0.0.0-20220302011226-f13defa54577
|
||||
github.com/minio/minio-go/v7 v7.0.23
|
||||
github.com/minio/operator v0.0.0-20220110040724-a5d59a342b7f
|
||||
github.com/minio/operator v0.0.0-20220401213108-1e35dbf22c40
|
||||
github.com/minio/pkg v1.1.20
|
||||
github.com/minio/selfupdate v0.4.0
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
|
||||
@@ -55,6 +55,29 @@ func RestartService() (*http.Response, error) {
|
||||
return response, err
|
||||
}
|
||||
|
||||
func GetNodes() (*http.Response, error) {
|
||||
/*
|
||||
Helper function to get nodes
|
||||
HTTP Verb: GET
|
||||
URL: /api/v1/nodes
|
||||
*/
|
||||
request, err := http.NewRequest(
|
||||
"GET",
|
||||
"http://localhost:9090/api/v1/nodes",
|
||||
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: 2000 * time.Second, // increased timeout since restart takes time, more than other APIs.
|
||||
}
|
||||
response, err := client.Do(request)
|
||||
return response, err
|
||||
}
|
||||
|
||||
func NotifyPostgres() (*http.Response, error) {
|
||||
/*
|
||||
Helper function to add Postgres Notification
|
||||
@@ -131,7 +154,7 @@ func NotifyPostgres() (*http.Response, error) {
|
||||
}
|
||||
|
||||
func TestNotifyPostgres(t *testing.T) {
|
||||
printStartFunc("TestNotifyPostgres")
|
||||
|
||||
// Variables
|
||||
assert := assert.New(t)
|
||||
|
||||
@@ -147,11 +170,11 @@ func TestNotifyPostgres(t *testing.T) {
|
||||
if response != nil {
|
||||
assert.Equal(200, response.StatusCode, finalResponse)
|
||||
}
|
||||
printEndFunc("TestNotifyPostgres")
|
||||
|
||||
}
|
||||
|
||||
func TestRestartService(t *testing.T) {
|
||||
printStartFunc("TestRestartService")
|
||||
|
||||
assert := assert.New(t)
|
||||
restartResponse, restartError := RestartService()
|
||||
assert.Nil(restartError)
|
||||
@@ -167,5 +190,113 @@ func TestRestartService(t *testing.T) {
|
||||
addObjRsp,
|
||||
)
|
||||
}
|
||||
printEndFunc("TestRestartService")
|
||||
|
||||
}
|
||||
|
||||
func ListPoliciesWithBucket(bucketName string) (*http.Response, error) {
|
||||
/*
|
||||
Helper function to List Policies With Given Bucket
|
||||
HTTP Verb: GET
|
||||
URL: /bucket-policy/{bucket}
|
||||
*/
|
||||
request, err := http.NewRequest(
|
||||
"GET", "http://localhost:9090/api/v1/bucket-policy/"+bucketName, 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 TestListPoliciesWithBucket(t *testing.T) {
|
||||
|
||||
// Test Variables
|
||||
bucketName := "testlistpolicieswithbucket"
|
||||
assert := assert.New(t)
|
||||
|
||||
// Test
|
||||
response, err := ListPoliciesWithBucket(bucketName)
|
||||
assert.Nil(err)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
parsedResponse := inspectHTTPResponse(response)
|
||||
if response != nil {
|
||||
assert.Equal(
|
||||
200,
|
||||
response.StatusCode,
|
||||
parsedResponse,
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func ListUsersWithAccessToBucket(bucketName string) (*http.Response, error) {
|
||||
/*
|
||||
Helper function to List Users With Access to a Given Bucket
|
||||
HTTP Verb: GET
|
||||
URL: /bucket-users/{bucket}
|
||||
*/
|
||||
request, err := http.NewRequest(
|
||||
"GET", "http://localhost:9090/api/v1/bucket-users/"+bucketName, 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 TestListUsersWithAccessToBucket(t *testing.T) {
|
||||
|
||||
// Test Variables
|
||||
bucketName := "testlistuserswithaccesstobucket1"
|
||||
assert := assert.New(t)
|
||||
|
||||
// Test
|
||||
response, err := ListUsersWithAccessToBucket(bucketName)
|
||||
assert.Nil(err)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
parsedResponse := inspectHTTPResponse(response)
|
||||
if response != nil {
|
||||
assert.Equal(
|
||||
200,
|
||||
response.StatusCode,
|
||||
parsedResponse,
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestGetNodes(t *testing.T) {
|
||||
|
||||
assert := assert.New(t)
|
||||
getNodesResponse, getNodesError := GetNodes()
|
||||
assert.Nil(getNodesError)
|
||||
if getNodesError != nil {
|
||||
log.Println(getNodesError)
|
||||
return
|
||||
}
|
||||
addObjRsp := inspectHTTPResponse(getNodesResponse)
|
||||
if getNodesResponse != nil {
|
||||
assert.Equal(
|
||||
200,
|
||||
getNodesResponse.StatusCode,
|
||||
addObjRsp,
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -55,37 +55,6 @@ func inspectHTTPResponse(httpResponse *http.Response) string {
|
||||
return "Http Response: " + string(b)
|
||||
}
|
||||
|
||||
func printMessage(message string) {
|
||||
/*
|
||||
Helper function to print HTTP response.
|
||||
*/
|
||||
fmt.Println(message)
|
||||
}
|
||||
|
||||
func printLoggingMessage(message string, functionName string) {
|
||||
/*
|
||||
Helper function to have standard output across the tests.
|
||||
*/
|
||||
finalString := "......................." + functionName + "(): " + message
|
||||
printMessage(finalString)
|
||||
}
|
||||
|
||||
func printStartFunc(functionName string) {
|
||||
/*
|
||||
Common function for all tests to tell that test has started
|
||||
*/
|
||||
printMessage("")
|
||||
printLoggingMessage("started", functionName)
|
||||
}
|
||||
|
||||
func printEndFunc(functionName string) {
|
||||
/*
|
||||
Helper function for all tests to tell that test has ended, is completed
|
||||
*/
|
||||
printLoggingMessage("completed", functionName)
|
||||
printMessage("")
|
||||
}
|
||||
|
||||
func initConsoleServer() (*restapi.Server, error) {
|
||||
|
||||
//os.Setenv("CONSOLE_MINIO_SERVER", "localhost:9000")
|
||||
@@ -123,7 +92,7 @@ func initConsoleServer() (*restapi.Server, error) {
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
printStartFunc("TestMain")
|
||||
|
||||
// start console server
|
||||
go func() {
|
||||
fmt.Println("start server")
|
||||
@@ -212,6 +181,6 @@ func TestMain(m *testing.M) {
|
||||
if response != nil {
|
||||
fmt.Println("DELETE StatusCode:", response.StatusCode)
|
||||
}
|
||||
printEndFunc("TestMain")
|
||||
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ import (
|
||||
)
|
||||
|
||||
func TestLoginStrategy(t *testing.T) {
|
||||
printStartFunc("TestLoginStrategy")
|
||||
|
||||
assert := assert.New(t)
|
||||
|
||||
// image for now:
|
||||
@@ -68,5 +68,5 @@ func TestLoginStrategy(t *testing.T) {
|
||||
assert.Equal(models.LoginDetailsLoginStrategyForm, loginDetails.LoginStrategy, "Login Details don't match")
|
||||
|
||||
}
|
||||
printEndFunc("TestLoginStrategy")
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-openapi/swag"
|
||||
|
||||
iampolicy "github.com/minio/pkg/iam/policy"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
@@ -38,7 +40,7 @@ func TestAddServiceAccount(t *testing.T) {
|
||||
tests like users.ts can run over clean data and we don't collide against
|
||||
it.
|
||||
*/
|
||||
printStartFunc("TestAddServiceAccount")
|
||||
|
||||
assert := assert.New(t)
|
||||
|
||||
client := &http.Client{
|
||||
@@ -159,5 +161,249 @@ func TestAddServiceAccount(t *testing.T) {
|
||||
fmt.Println("DELETE StatusCode:", response.StatusCode)
|
||||
assert.Equal(204, response.StatusCode, "has to be 204 when delete user")
|
||||
}
|
||||
printEndFunc("TestAddServiceAccount")
|
||||
|
||||
}
|
||||
|
||||
func Test_ServiceAccountsAPI(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
type args struct {
|
||||
api string
|
||||
policy *string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
expectedStatus int
|
||||
expectedError error
|
||||
}{
|
||||
{
|
||||
name: "Create Service Account - Default",
|
||||
args: args{
|
||||
api: "/service-accounts",
|
||||
policy: nil,
|
||||
},
|
||||
expectedStatus: 201,
|
||||
expectedError: nil,
|
||||
},
|
||||
{
|
||||
name: "Create Service Account - Valid Policy",
|
||||
args: args{
|
||||
api: "/service-accounts",
|
||||
policy: swag.String(`
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"s3:GetBucketLocation",
|
||||
"s3:GetObject"
|
||||
],
|
||||
"Resource": [
|
||||
"arn:aws:s3:::*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}`),
|
||||
},
|
||||
expectedStatus: 201,
|
||||
expectedError: nil,
|
||||
},
|
||||
{
|
||||
name: "Create Service Account - Invalid Policy",
|
||||
args: args{
|
||||
api: "/service-accounts",
|
||||
policy: swag.String(`
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"s3:GetBucketLocation"
|
||||
"s3:GetObject"
|
||||
],
|
||||
"Resource": [
|
||||
"arn:aws:s3:::*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}`),
|
||||
},
|
||||
expectedStatus: 500,
|
||||
expectedError: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
client := &http.Client{
|
||||
Timeout: 3 * time.Second,
|
||||
}
|
||||
|
||||
// Add service account
|
||||
|
||||
requestDataPolicy := map[string]interface{}{}
|
||||
if tt.args.policy != nil {
|
||||
requestDataPolicy["policy"] = *tt.args.policy
|
||||
}
|
||||
|
||||
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)
|
||||
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 DeleteMultipleServiceAccounts(serviceAccounts []string) (*http.Response, error) {
|
||||
/*
|
||||
Helper function to delete multiple service accounts
|
||||
URL: http://localhost:9001/api/v1/service-accounts/delete-multi
|
||||
HTTP Verb: DELETE
|
||||
Data: ["U3RADB7J2ZZHELR0WSBB","ZE8H1HYOA6AVGKFCV6YU"]
|
||||
Response: Status Code: 204 No Content
|
||||
*/
|
||||
client := &http.Client{
|
||||
Timeout: 3 * time.Second,
|
||||
}
|
||||
requestDataJSON, _ := json.Marshal(serviceAccounts)
|
||||
requestDataBody := bytes.NewReader(requestDataJSON)
|
||||
request, err := http.NewRequest(
|
||||
"DELETE", "http://localhost:9090/api/v1/service-accounts/delete-multi", requestDataBody)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
|
||||
request.Header.Add("Content-Type", "application/json")
|
||||
response, err := client.Do(request)
|
||||
return response, err
|
||||
}
|
||||
|
||||
func TestCreateServiceAccountForUserWithCredentials(t *testing.T) {
|
||||
/*
|
||||
To test creation of service account for a user.
|
||||
*/
|
||||
|
||||
// Test's variables
|
||||
userName := "testcreateserviceaccountforuserwithcredentials1"
|
||||
assert := assert.New(t)
|
||||
policy := ""
|
||||
serviceAccountLengthInBytes := 40 // As observed, update as needed
|
||||
|
||||
// 1. Create the user
|
||||
var groups = []string{}
|
||||
var policies = []string{}
|
||||
var secretKey = "testcreateserviceaccountforuserwithcrede"
|
||||
response, err := AddUser(userName, "secretKey", groups, policies)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
if response != nil {
|
||||
fmt.Println("StatusCode:", response.StatusCode)
|
||||
assert.Equal(201, response.StatusCode, "Status Code is incorrect")
|
||||
}
|
||||
|
||||
// Table driven testing part
|
||||
type args struct {
|
||||
accessKey string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
expectedStatus int
|
||||
}{
|
||||
{
|
||||
name: "Service Account With Valid Credentials",
|
||||
expectedStatus: 201,
|
||||
args: args{
|
||||
accessKey: "testcreateserviceacc",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Service Account With Invalid Credentials",
|
||||
expectedStatus: 500,
|
||||
args: args{
|
||||
accessKey: "tooooooooooooooooooooolongggggggggggggggggg",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// 2. Create the service account for the user
|
||||
createServiceAccountWithCredentialsResponse,
|
||||
createServiceAccountWithCredentialsError := CreateServiceAccountForUserWithCredentials(
|
||||
userName,
|
||||
policy,
|
||||
tt.args.accessKey,
|
||||
secretKey,
|
||||
)
|
||||
if createServiceAccountWithCredentialsError != nil {
|
||||
log.Println(createServiceAccountWithCredentialsError)
|
||||
assert.Fail("Error in createServiceAccountWithCredentialsError")
|
||||
}
|
||||
if createServiceAccountWithCredentialsResponse != nil {
|
||||
fmt.Println("StatusCode:", createServiceAccountWithCredentialsResponse.StatusCode)
|
||||
assert.Equal(
|
||||
tt.expectedStatus, // different status expected per table's row
|
||||
createServiceAccountWithCredentialsResponse.StatusCode,
|
||||
inspectHTTPResponse(createServiceAccountWithCredentialsResponse),
|
||||
)
|
||||
}
|
||||
|
||||
// 3. Verify the service account for the user
|
||||
listOfAccountsResponse,
|
||||
listOfAccountsError := ReturnsAListOfServiceAccountsForAUser(userName)
|
||||
if listOfAccountsError != nil {
|
||||
log.Println(listOfAccountsError)
|
||||
assert.Fail("Error in listOfAccountsError")
|
||||
}
|
||||
finalResponse := inspectHTTPResponse(listOfAccountsResponse)
|
||||
if listOfAccountsResponse != nil {
|
||||
fmt.Println("StatusCode:", listOfAccountsResponse.StatusCode)
|
||||
assert.Equal(
|
||||
200, listOfAccountsResponse.StatusCode,
|
||||
finalResponse,
|
||||
)
|
||||
}
|
||||
assert.Equal(len(finalResponse), serviceAccountLengthInBytes, finalResponse)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete Multiple Service Accounts
|
||||
serviceAccount := make([]string, 1)
|
||||
serviceAccount[0] = "testcreateserviceacc"
|
||||
response, err = DeleteMultipleServiceAccounts(serviceAccount)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
if response != nil {
|
||||
fmt.Println("StatusCode:", response.StatusCode)
|
||||
assert.Equal(
|
||||
204,
|
||||
response.StatusCode,
|
||||
inspectHTTPResponse(response),
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -359,7 +359,7 @@ func TestAddUser(t *testing.T) {
|
||||
tests like users.ts can run over clean data and we don't collide against
|
||||
it.
|
||||
*/
|
||||
printStartFunc("TestAddUser")
|
||||
|
||||
assert := assert.New(t)
|
||||
|
||||
// With no groups & no policies
|
||||
@@ -384,7 +384,7 @@ func TestAddUser(t *testing.T) {
|
||||
fmt.Println("DELETE StatusCode:", response.StatusCode)
|
||||
assert.Equal(204, response.StatusCode, "has to be 204 when delete user")
|
||||
}
|
||||
printEndFunc("TestAddUser")
|
||||
|
||||
}
|
||||
|
||||
func TestListUsers(t *testing.T) {
|
||||
@@ -394,7 +394,7 @@ func TestListUsers(t *testing.T) {
|
||||
2. Then, it lists the users <------ 200 is expected when listing them.
|
||||
3. Finally, it deletes the users
|
||||
*/
|
||||
printStartFunc("TestListUsers")
|
||||
|
||||
assert := assert.New(t)
|
||||
|
||||
// With no groups & no policies
|
||||
@@ -454,14 +454,14 @@ func TestListUsers(t *testing.T) {
|
||||
response.StatusCode, "has to be 204 when delete user")
|
||||
}
|
||||
}
|
||||
printEndFunc("TestListUsers")
|
||||
|
||||
}
|
||||
|
||||
func TestGetUserInfo(t *testing.T) {
|
||||
/*
|
||||
Test to get the user information via API.
|
||||
*/
|
||||
printStartFunc("TestGetUserInfo")
|
||||
|
||||
// 1. Create the user
|
||||
fmt.Println("TestGetUserInfo(): 1. Create the user")
|
||||
assert := assert.New(t)
|
||||
@@ -500,14 +500,14 @@ 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")
|
||||
printEndFunc("TestGetUserInfo")
|
||||
|
||||
}
|
||||
|
||||
func TestUpdateUserInfoSuccessfulResponse(t *testing.T) {
|
||||
/*
|
||||
Update User Information Test with Successful Response
|
||||
*/
|
||||
printStartFunc("TestGetUserInfo")
|
||||
|
||||
assert := assert.New(t)
|
||||
|
||||
// 1. Create an active user
|
||||
@@ -545,14 +545,14 @@ func TestUpdateUserInfoSuccessfulResponse(t *testing.T) {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
assert.True(strings.Contains(string(b), "disabled"))
|
||||
printEndFunc("TestGetUserInfo")
|
||||
|
||||
}
|
||||
|
||||
func TestUpdateUserInfoGenericErrorResponse(t *testing.T) {
|
||||
/*
|
||||
Update User Information Test with Generic Error Response
|
||||
*/
|
||||
printStartFunc("TestUpdateUserInfoGenericErrorResponse")
|
||||
|
||||
assert := assert.New(t)
|
||||
|
||||
// 1. Create an active user
|
||||
@@ -590,14 +590,14 @@ func TestUpdateUserInfoGenericErrorResponse(t *testing.T) {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
assert.True(strings.Contains(string(b), "status not valid"))
|
||||
printEndFunc("TestUpdateUserInfoGenericErrorResponse")
|
||||
|
||||
}
|
||||
|
||||
func TestRemoveUserSuccessfulResponse(t *testing.T) {
|
||||
/*
|
||||
To test removing a user from API
|
||||
*/
|
||||
printStartFunc("TestRemoveUserSuccessfulResponse")
|
||||
|
||||
assert := assert.New(t)
|
||||
|
||||
// 1. Create an active user
|
||||
@@ -641,17 +641,17 @@ func TestRemoveUserSuccessfulResponse(t *testing.T) {
|
||||
404, getUserInfoResponse.StatusCode, "Status Code is incorrect")
|
||||
}
|
||||
finalResponse := inspectHTTPResponse(getUserInfoResponse)
|
||||
printMessage(finalResponse)
|
||||
fmt.Println(finalResponse)
|
||||
assert.True(strings.Contains(
|
||||
finalResponse, "The specified user does not exist"), finalResponse)
|
||||
printEndFunc("TestRemoveUserSuccessfulResponse")
|
||||
|
||||
}
|
||||
|
||||
func TestUpdateGroupsForAUser(t *testing.T) {
|
||||
/*
|
||||
To test Update Groups For a User End Point.
|
||||
*/
|
||||
printStartFunc("TestUpdateGroupsForAUser")
|
||||
|
||||
// 1. Create the user
|
||||
numberOfGroups := 3
|
||||
groupName := "updategroupforausergroup"
|
||||
@@ -701,14 +701,14 @@ func TestUpdateGroupsForAUser(t *testing.T) {
|
||||
assert.True(strings.Contains(
|
||||
finalResponse, groupName+strconv.Itoa(i)), finalResponse)
|
||||
}
|
||||
printEndFunc("TestUpdateGroupsForAUser")
|
||||
|
||||
}
|
||||
|
||||
func TestCreateServiceAccountForUser(t *testing.T) {
|
||||
/*
|
||||
To test creation of service account for a user.
|
||||
*/
|
||||
printStartFunc("TestCreateServiceAccountForUser")
|
||||
|
||||
// Test's variables
|
||||
userName := "testcreateserviceaccountforuser1"
|
||||
assert := assert.New(t)
|
||||
@@ -762,107 +762,14 @@ func TestCreateServiceAccountForUser(t *testing.T) {
|
||||
)
|
||||
}
|
||||
assert.Equal(len(finalResponse), serviceAccountLengthInBytes, finalResponse)
|
||||
printEndFunc("TestCreateServiceAccountForUser")
|
||||
}
|
||||
|
||||
func TestCreateServiceAccountForUserWithCredentials(t *testing.T) {
|
||||
/*
|
||||
To test creation of service account for a user.
|
||||
*/
|
||||
printStartFunc("TestCreateServiceAccountForUserWithCredentials")
|
||||
// Test's variables
|
||||
userName := "testcreateserviceaccountforuserwithcredentials1"
|
||||
assert := assert.New(t)
|
||||
policy := ""
|
||||
serviceAccountLengthInBytes := 40 // As observed, update as needed
|
||||
|
||||
// 1. Create the user
|
||||
var groups = []string{}
|
||||
var policies = []string{}
|
||||
var secretKey = "testcreateserviceaccountforuserwithcrede"
|
||||
response, err := AddUser(userName, "secretKey", groups, policies)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
if response != nil {
|
||||
fmt.Println("StatusCode:", response.StatusCode)
|
||||
assert.Equal(201, response.StatusCode, "Status Code is incorrect")
|
||||
}
|
||||
|
||||
// Table driven testing part
|
||||
type args struct {
|
||||
accessKey string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
expectedStatus int
|
||||
}{
|
||||
{
|
||||
name: "Service Account With Valid Credentials",
|
||||
expectedStatus: 201,
|
||||
args: args{
|
||||
accessKey: "testcreateserviceacc",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Service Account With Invalid Credentials",
|
||||
expectedStatus: 500,
|
||||
args: args{
|
||||
accessKey: "tooooooooooooooooooooolongggggggggggggggggg",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// 2. Create the service account for the user
|
||||
createServiceAccountWithCredentialsResponse,
|
||||
createServiceAccountWithCredentialsError := CreateServiceAccountForUserWithCredentials(
|
||||
userName,
|
||||
policy,
|
||||
tt.args.accessKey,
|
||||
secretKey,
|
||||
)
|
||||
if createServiceAccountWithCredentialsError != nil {
|
||||
log.Println(createServiceAccountWithCredentialsError)
|
||||
assert.Fail("Error in createServiceAccountWithCredentialsError")
|
||||
}
|
||||
if createServiceAccountWithCredentialsResponse != nil {
|
||||
fmt.Println("StatusCode:", createServiceAccountWithCredentialsResponse.StatusCode)
|
||||
assert.Equal(
|
||||
tt.expectedStatus, // different status expected per table's row
|
||||
createServiceAccountWithCredentialsResponse.StatusCode,
|
||||
inspectHTTPResponse(createServiceAccountWithCredentialsResponse),
|
||||
)
|
||||
}
|
||||
|
||||
// 3. Verify the service account for the user
|
||||
listOfAccountsResponse,
|
||||
listOfAccountsError := ReturnsAListOfServiceAccountsForAUser(userName)
|
||||
if listOfAccountsError != nil {
|
||||
log.Println(listOfAccountsError)
|
||||
assert.Fail("Error in listOfAccountsError")
|
||||
}
|
||||
finalResponse := inspectHTTPResponse(listOfAccountsResponse)
|
||||
if listOfAccountsResponse != nil {
|
||||
fmt.Println("StatusCode:", listOfAccountsResponse.StatusCode)
|
||||
assert.Equal(
|
||||
200, listOfAccountsResponse.StatusCode,
|
||||
finalResponse,
|
||||
)
|
||||
}
|
||||
assert.Equal(len(finalResponse), serviceAccountLengthInBytes, finalResponse)
|
||||
})
|
||||
}
|
||||
printEndFunc("TestCreateServiceAccountForUserWithCredentials")
|
||||
}
|
||||
|
||||
func TestUsersGroupsBulk(t *testing.T) {
|
||||
/*
|
||||
To test UsersGroupsBulk End Point
|
||||
*/
|
||||
printStartFunc("TestUsersGroupsBulk")
|
||||
|
||||
// Vars
|
||||
assert := assert.New(t)
|
||||
numberOfUsers := 5
|
||||
@@ -945,5 +852,5 @@ func TestUsersGroupsBulk(t *testing.T) {
|
||||
// Make sure the user belongs to the created group
|
||||
assert.True(strings.Contains(string(finalResponse), groupName))
|
||||
}
|
||||
printEndFunc("TestUsersGroupsBulk")
|
||||
|
||||
}
|
||||
|
||||
75
integration/version_test.go
Normal file
75
integration/version_test.go
Normal file
@@ -0,0 +1,75 @@
|
||||
// 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 (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_VersionAPI(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
type args struct {
|
||||
api string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
expectedStatus int
|
||||
expectedError error
|
||||
}{
|
||||
{
|
||||
name: "Check Version",
|
||||
args: args{
|
||||
api: "/check-version",
|
||||
},
|
||||
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("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")
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,7 +15,7 @@ spec:
|
||||
serviceAccountName: console-sa
|
||||
containers:
|
||||
- name: console
|
||||
image: 'minio/console:v0.15.2'
|
||||
image: 'minio/console:v0.15.9'
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
env:
|
||||
- name: CONSOLE_OPERATOR_MODE
|
||||
|
||||
@@ -32,7 +32,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: console
|
||||
image: 'minio/console:v0.15.2'
|
||||
image: 'minio/console:v0.15.9'
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
env:
|
||||
- name: CONSOLE_MINIO_SERVER
|
||||
|
||||
67
models/bucket_replication_rule_list.go
Normal file
67
models/bucket_replication_rule_list.go
Normal 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"
|
||||
)
|
||||
|
||||
// BucketReplicationRuleList bucket replication rule list
|
||||
//
|
||||
// swagger:model bucketReplicationRuleList
|
||||
type BucketReplicationRuleList struct {
|
||||
|
||||
// rules
|
||||
Rules []string `json:"rules"`
|
||||
}
|
||||
|
||||
// Validate validates this bucket replication rule list
|
||||
func (m *BucketReplicationRuleList) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this bucket replication rule list based on context it is used
|
||||
func (m *BucketReplicationRuleList) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *BucketReplicationRuleList) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *BucketReplicationRuleList) UnmarshalBinary(b []byte) error {
|
||||
var res BucketReplicationRuleList
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
73
models/peer_info.go
Normal file
73
models/peer_info.go
Normal 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"
|
||||
)
|
||||
|
||||
// PeerInfo peer info
|
||||
//
|
||||
// swagger:model peerInfo
|
||||
type PeerInfo struct {
|
||||
|
||||
// deployment ID
|
||||
DeploymentID string `json:"deploymentID,omitempty"`
|
||||
|
||||
// endpoint
|
||||
Endpoint string `json:"endpoint,omitempty"`
|
||||
|
||||
// name
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this peer info
|
||||
func (m *PeerInfo) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this peer info based on context it is used
|
||||
func (m *PeerInfo) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *PeerInfo) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *PeerInfo) UnmarshalBinary(b []byte) error {
|
||||
var res PeerInfo
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
91
models/peer_info_remove.go
Normal file
91
models/peer_info_remove.go
Normal file
@@ -0,0 +1,91 @@
|
||||
// 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"
|
||||
"github.com/go-openapi/validate"
|
||||
)
|
||||
|
||||
// PeerInfoRemove peer info remove
|
||||
//
|
||||
// swagger:model peerInfoRemove
|
||||
type PeerInfoRemove struct {
|
||||
|
||||
// all
|
||||
All bool `json:"all,omitempty"`
|
||||
|
||||
// sites
|
||||
// Required: true
|
||||
Sites []string `json:"sites"`
|
||||
}
|
||||
|
||||
// Validate validates this peer info remove
|
||||
func (m *PeerInfoRemove) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateSites(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *PeerInfoRemove) validateSites(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("sites", "body", m.Sites); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this peer info remove based on context it is used
|
||||
func (m *PeerInfoRemove) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *PeerInfoRemove) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *PeerInfoRemove) UnmarshalBinary(b []byte) error {
|
||||
var res PeerInfoRemove
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
76
models/peer_site.go
Normal file
76
models/peer_site.go
Normal 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"
|
||||
)
|
||||
|
||||
// PeerSite peer site
|
||||
//
|
||||
// swagger:model peerSite
|
||||
type PeerSite struct {
|
||||
|
||||
// access key
|
||||
AccessKey string `json:"accessKey,omitempty"`
|
||||
|
||||
// endpoint
|
||||
Endpoint string `json:"endpoint,omitempty"`
|
||||
|
||||
// name
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// secret key
|
||||
SecretKey string `json:"secretKey,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this peer site
|
||||
func (m *PeerSite) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this peer site based on context it is used
|
||||
func (m *PeerSite) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *PeerSite) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *PeerSite) UnmarshalBinary(b []byte) error {
|
||||
var res PeerSite
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
73
models/peer_site_edit_response.go
Normal file
73
models/peer_site_edit_response.go
Normal 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"
|
||||
)
|
||||
|
||||
// PeerSiteEditResponse peer site edit response
|
||||
//
|
||||
// swagger:model peerSiteEditResponse
|
||||
type PeerSiteEditResponse struct {
|
||||
|
||||
// error detail
|
||||
ErrorDetail string `json:"errorDetail,omitempty"`
|
||||
|
||||
// status
|
||||
Status string `json:"status,omitempty"`
|
||||
|
||||
// success
|
||||
Success bool `json:"success,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this peer site edit response
|
||||
func (m *PeerSiteEditResponse) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this peer site edit response based on context it is used
|
||||
func (m *PeerSiteEditResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *PeerSiteEditResponse) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *PeerSiteEditResponse) UnmarshalBinary(b []byte) error {
|
||||
var res PeerSiteEditResponse
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
70
models/peer_site_remove_response.go
Normal file
70
models/peer_site_remove_response.go
Normal 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"
|
||||
)
|
||||
|
||||
// PeerSiteRemoveResponse peer site remove response
|
||||
//
|
||||
// swagger:model peerSiteRemoveResponse
|
||||
type PeerSiteRemoveResponse struct {
|
||||
|
||||
// error detail
|
||||
ErrorDetail string `json:"errorDetail,omitempty"`
|
||||
|
||||
// status
|
||||
Status string `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this peer site remove response
|
||||
func (m *PeerSiteRemoveResponse) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this peer site remove response based on context it is used
|
||||
func (m *PeerSiteRemoveResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *PeerSiteRemoveResponse) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *PeerSiteRemoveResponse) UnmarshalBinary(b []byte) error {
|
||||
var res PeerSiteRemoveResponse
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
// 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"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/validate"
|
||||
)
|
||||
|
||||
// ProfilerType profiler type
|
||||
//
|
||||
// swagger:model profilerType
|
||||
type ProfilerType string
|
||||
|
||||
func NewProfilerType(value ProfilerType) *ProfilerType {
|
||||
return &value
|
||||
}
|
||||
|
||||
// Pointer returns a pointer to a freshly-allocated ProfilerType.
|
||||
func (m ProfilerType) Pointer() *ProfilerType {
|
||||
return &m
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
// ProfilerTypeCPU captures enum value "cpu"
|
||||
ProfilerTypeCPU ProfilerType = "cpu"
|
||||
|
||||
// ProfilerTypeMem captures enum value "mem"
|
||||
ProfilerTypeMem ProfilerType = "mem"
|
||||
|
||||
// ProfilerTypeBlock captures enum value "block"
|
||||
ProfilerTypeBlock ProfilerType = "block"
|
||||
|
||||
// ProfilerTypeMutex captures enum value "mutex"
|
||||
ProfilerTypeMutex ProfilerType = "mutex"
|
||||
|
||||
// ProfilerTypeTrace captures enum value "trace"
|
||||
ProfilerTypeTrace ProfilerType = "trace"
|
||||
|
||||
// ProfilerTypeThreads captures enum value "threads"
|
||||
ProfilerTypeThreads ProfilerType = "threads"
|
||||
|
||||
// ProfilerTypeGoroutines captures enum value "goroutines"
|
||||
ProfilerTypeGoroutines ProfilerType = "goroutines"
|
||||
)
|
||||
|
||||
// for schema
|
||||
var profilerTypeEnum []interface{}
|
||||
|
||||
func init() {
|
||||
var res []ProfilerType
|
||||
if err := json.Unmarshal([]byte(`["cpu","mem","block","mutex","trace","threads","goroutines"]`), &res); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, v := range res {
|
||||
profilerTypeEnum = append(profilerTypeEnum, v)
|
||||
}
|
||||
}
|
||||
|
||||
func (m ProfilerType) validateProfilerTypeEnum(path, location string, value ProfilerType) error {
|
||||
if err := validate.EnumCase(path, location, value, profilerTypeEnum, true); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate validates this profiler type
|
||||
func (m ProfilerType) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
// value enum
|
||||
if err := m.validateProfilerTypeEnum("", "body", m); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this profiler type based on context it is used
|
||||
func (m ProfilerType) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
@@ -38,7 +38,7 @@ type ProfilingStartRequest struct {
|
||||
|
||||
// type
|
||||
// Required: true
|
||||
Type *ProfilerType `json:"type"`
|
||||
Type *string `json:"type"`
|
||||
}
|
||||
|
||||
// Validate validates this profiling start request
|
||||
@@ -61,51 +61,11 @@ func (m *ProfilingStartRequest) validateType(formats strfmt.Registry) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validate.Required("type", "body", m.Type); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if m.Type != nil {
|
||||
if err := m.Type.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("type")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("type")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this profiling start request based on the context it is used
|
||||
// ContextValidate validates this profiling start request based on context it is used
|
||||
func (m *ProfilingStartRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateType(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ProfilingStartRequest) contextValidateType(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.Type != nil {
|
||||
if err := m.Type.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("type")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("type")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
90
models/site_replication_add_request.go
Normal file
90
models/site_replication_add_request.go
Normal file
@@ -0,0 +1,90 @@
|
||||
// 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"
|
||||
)
|
||||
|
||||
// SiteReplicationAddRequest site replication add request
|
||||
//
|
||||
// swagger:model siteReplicationAddRequest
|
||||
type SiteReplicationAddRequest []*PeerSite
|
||||
|
||||
// Validate validates this site replication add request
|
||||
func (m SiteReplicationAddRequest) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
for i := 0; i < len(m); i++ {
|
||||
if swag.IsZero(m[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m[i] != nil {
|
||||
if err := m[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName(strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName(strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this site replication add request based on the context it is used
|
||||
func (m SiteReplicationAddRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
for i := 0; i < len(m); i++ {
|
||||
|
||||
if m[i] != nil {
|
||||
if err := m[i].ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName(strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName(strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
76
models/site_replication_add_response.go
Normal file
76
models/site_replication_add_response.go
Normal 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"
|
||||
)
|
||||
|
||||
// SiteReplicationAddResponse site replication add response
|
||||
//
|
||||
// swagger:model siteReplicationAddResponse
|
||||
type SiteReplicationAddResponse struct {
|
||||
|
||||
// error detail
|
||||
ErrorDetail string `json:"errorDetail,omitempty"`
|
||||
|
||||
// initial sync error message
|
||||
InitialSyncErrorMessage string `json:"initialSyncErrorMessage,omitempty"`
|
||||
|
||||
// status
|
||||
Status string `json:"status,omitempty"`
|
||||
|
||||
// success
|
||||
Success bool `json:"success,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this site replication add response
|
||||
func (m *SiteReplicationAddResponse) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this site replication add response based on context it is used
|
||||
func (m *SiteReplicationAddResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *SiteReplicationAddResponse) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *SiteReplicationAddResponse) UnmarshalBinary(b []byte) error {
|
||||
var res SiteReplicationAddResponse
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
142
models/site_replication_info_response.go
Normal file
142
models/site_replication_info_response.go
Normal file
@@ -0,0 +1,142 @@
|
||||
// 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"
|
||||
)
|
||||
|
||||
// SiteReplicationInfoResponse site replication info response
|
||||
//
|
||||
// swagger:model siteReplicationInfoResponse
|
||||
type SiteReplicationInfoResponse struct {
|
||||
|
||||
// enabled
|
||||
Enabled bool `json:"enabled,omitempty"`
|
||||
|
||||
// name
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// service account access key
|
||||
ServiceAccountAccessKey string `json:"serviceAccountAccessKey,omitempty"`
|
||||
|
||||
// sites
|
||||
Sites []*PeerInfo `json:"sites"`
|
||||
}
|
||||
|
||||
// Validate validates this site replication info response
|
||||
func (m *SiteReplicationInfoResponse) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateSites(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *SiteReplicationInfoResponse) validateSites(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Sites) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.Sites); i++ {
|
||||
if swag.IsZero(m.Sites[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.Sites[i] != nil {
|
||||
if err := m.Sites[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("sites" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("sites" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this site replication info response based on the context it is used
|
||||
func (m *SiteReplicationInfoResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateSites(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *SiteReplicationInfoResponse) contextValidateSites(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.Sites); i++ {
|
||||
|
||||
if m.Sites[i] != nil {
|
||||
if err := m.Sites[i].ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("sites" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("sites" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *SiteReplicationInfoResponse) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *SiteReplicationInfoResponse) UnmarshalBinary(b []byte) error {
|
||||
var res SiteReplicationInfoResponse
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -24,7 +24,9 @@ package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
@@ -70,6 +72,9 @@ type TenantList struct {
|
||||
// pool count
|
||||
PoolCount int64 `json:"pool_count,omitempty"`
|
||||
|
||||
// tiers
|
||||
Tiers []*TenantTierElement `json:"tiers"`
|
||||
|
||||
// total size
|
||||
TotalSize int64 `json:"total_size,omitempty"`
|
||||
|
||||
@@ -79,11 +84,75 @@ type TenantList struct {
|
||||
|
||||
// Validate validates this tenant list
|
||||
func (m *TenantList) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateTiers(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this tenant list based on context it is used
|
||||
func (m *TenantList) validateTiers(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Tiers) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.Tiers); i++ {
|
||||
if swag.IsZero(m.Tiers[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.Tiers[i] != nil {
|
||||
if err := m.Tiers[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("tiers" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("tiers" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this tenant list based on the context it is used
|
||||
func (m *TenantList) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateTiers(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *TenantList) contextValidateTiers(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.Tiers); i++ {
|
||||
|
||||
if m.Tiers[i] != nil {
|
||||
if err := m.Tiers[i].ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("tiers" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("tiers" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
73
models/tenant_tier_element.go
Normal file
73
models/tenant_tier_element.go
Normal 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"
|
||||
)
|
||||
|
||||
// TenantTierElement tenant tier element
|
||||
//
|
||||
// swagger:model tenantTierElement
|
||||
type TenantTierElement struct {
|
||||
|
||||
// name
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// size
|
||||
Size int64 `json:"size,omitempty"`
|
||||
|
||||
// type
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this tenant tier element
|
||||
func (m *TenantTierElement) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this tenant tier element based on context it is used
|
||||
func (m *TenantTierElement) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *TenantTierElement) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *TenantTierElement) UnmarshalBinary(b []byte) error {
|
||||
var res TenantTierElement
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
531
operator-integration/tenant_test.go
Normal file
531
operator-integration/tenant_test.go
Normal file
@@ -0,0 +1,531 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package operatorintegration
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
b64 "encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-openapi/loads"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var token string
|
||||
|
||||
func inspectHTTPResponse(httpResponse *http.Response) string {
|
||||
/*
|
||||
Helper function to inspect the content of a HTTP response.
|
||||
*/
|
||||
b, err := io.ReadAll(httpResponse.Body)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
return "Http Response: " + string(b)
|
||||
}
|
||||
|
||||
func decodeBase64(value string) string {
|
||||
/*
|
||||
Helper function to decode in base64
|
||||
*/
|
||||
result, err := b64.StdEncoding.DecodeString(value)
|
||||
if err != nil {
|
||||
log.Fatal("error:", err)
|
||||
}
|
||||
return string(result)
|
||||
}
|
||||
|
||||
func printLoggingMessage(message string, functionName string) {
|
||||
/*
|
||||
Helper function to have standard output across the tests.
|
||||
*/
|
||||
finalString := "......................." + functionName + "(): " + message
|
||||
fmt.Println(finalString)
|
||||
}
|
||||
|
||||
func printStartFunc(functionName string) {
|
||||
/*
|
||||
Common function for all tests to tell that test has started
|
||||
*/
|
||||
fmt.Println("")
|
||||
printLoggingMessage("started", functionName)
|
||||
}
|
||||
|
||||
func printEndFunc(functionName string) {
|
||||
/*
|
||||
Helper function for all tests to tell that test has ended, is completed
|
||||
*/
|
||||
printLoggingMessage("completed", functionName)
|
||||
fmt.Println("")
|
||||
}
|
||||
|
||||
func initConsoleServer() (*restapi.Server, error) {
|
||||
|
||||
//os.Setenv("CONSOLE_MINIO_SERVER", "localhost:9000")
|
||||
|
||||
swaggerSpec, err := loads.Embedded(restapi.SwaggerJSON, restapi.FlatSwaggerJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
noLog := func(string, ...interface{}) {
|
||||
// nothing to log
|
||||
}
|
||||
|
||||
// Initialize MinIO loggers
|
||||
restapi.LogInfo = noLog
|
||||
restapi.LogError = noLog
|
||||
|
||||
api := operations.NewConsoleAPI(swaggerSpec)
|
||||
api.Logger = noLog
|
||||
|
||||
server := restapi.NewServer(api)
|
||||
// register all APIs
|
||||
server.ConfigureAPI()
|
||||
|
||||
//restapi.GlobalRootCAs, restapi.GlobalPublicCerts, restapi.GlobalTLSCertsManager = globalRootCAs, globalPublicCerts, globalTLSCerts
|
||||
|
||||
consolePort, _ := strconv.Atoi("9090")
|
||||
|
||||
server.Host = "0.0.0.0"
|
||||
server.Port = consolePort
|
||||
restapi.Port = "9090"
|
||||
restapi.Hostname = "0.0.0.0"
|
||||
|
||||
return server, nil
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
printStartFunc("TestMain")
|
||||
// start console server
|
||||
go func() {
|
||||
fmt.Println("start server")
|
||||
srv, err := initConsoleServer()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
log.Println("init fail")
|
||||
return
|
||||
}
|
||||
srv.Serve()
|
||||
|
||||
}()
|
||||
|
||||
fmt.Println("sleeping")
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
client := &http.Client{
|
||||
Timeout: 2 * time.Second,
|
||||
}
|
||||
|
||||
// kubectl to get token
|
||||
app := "kubectl"
|
||||
arg0 := "get"
|
||||
arg1 := "serviceaccount"
|
||||
arg2 := "console-sa"
|
||||
arg3 := "--namespace"
|
||||
arg4 := "minio-operator"
|
||||
arg5 := "-o"
|
||||
arg6 := "jsonpath=\"{.secrets[0].name}\""
|
||||
cmd := exec.Command(app, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
|
||||
var out bytes.Buffer
|
||||
var stderr bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
cmd.Stderr = &stderr
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
|
||||
return
|
||||
}
|
||||
secret := out.String() // "console-sa-token-kxdw2" <-- secret
|
||||
app2 := "kubectl"
|
||||
argu0 := "--namespace"
|
||||
argu1 := "minio-operator"
|
||||
argu2 := "get"
|
||||
argu3 := "secret"
|
||||
argu4 := secret[1 : len(secret)-1]
|
||||
argu5 := "-o"
|
||||
argu6 := "jsonpath=\"{.data.token}\""
|
||||
cmd2 := exec.Command(app2, argu0, argu1, argu2, argu3, argu4, argu5, argu6)
|
||||
var out2 bytes.Buffer
|
||||
var stderr2 bytes.Buffer
|
||||
cmd2.Stdout = &out2
|
||||
cmd2.Stderr = &stderr2
|
||||
err2 := cmd2.Run()
|
||||
if err2 != nil {
|
||||
fmt.Println(fmt.Sprint(err2) + ": -> " + stderr2.String())
|
||||
return
|
||||
}
|
||||
secret2 := out2.String()
|
||||
secret3 := decodeBase64(secret2[1 : len(secret2)-1])
|
||||
requestData := map[string]string{
|
||||
"jwt": secret3,
|
||||
}
|
||||
|
||||
requestDataJSON, _ := json.Marshal(requestData)
|
||||
|
||||
requestDataBody := bytes.NewReader(requestDataJSON)
|
||||
|
||||
request, err := http.NewRequest("POST", "http://localhost:9090/api/v1/login/operator", requestDataBody)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
request.Header.Add("Content-Type", "application/json")
|
||||
|
||||
response, err := client.Do(request)
|
||||
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
if response != nil {
|
||||
for _, cookie := range response.Cookies() {
|
||||
if cookie.Name == "token" {
|
||||
token = cookie.Value
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if token == "" {
|
||||
log.Println("authentication token not found in cookies response")
|
||||
return
|
||||
}
|
||||
|
||||
code := m.Run()
|
||||
printEndFunc("TestMain")
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
func ListTenants() (*http.Response, error) {
|
||||
/*
|
||||
Helper function to list buckets
|
||||
HTTP Verb: GET
|
||||
URL: http://localhost:9090/api/v1/tenants
|
||||
*/
|
||||
request, err := http.NewRequest(
|
||||
"GET", "http://localhost:9090/api/v1/tenants", 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 TestListTenants(t *testing.T) {
|
||||
// Tenants can be listed via API: https://github.com/miniohq/engineering/issues/591
|
||||
printStartFunc("TestListTenants")
|
||||
assert := assert.New(t)
|
||||
resp, err := ListTenants()
|
||||
assert.Nil(err)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
if resp != nil {
|
||||
assert.Equal(
|
||||
200, resp.StatusCode, "Status Code is incorrect")
|
||||
}
|
||||
bodyBytes, _ := ioutil.ReadAll(resp.Body)
|
||||
result := models.ListTenantsResponse{}
|
||||
err = json.Unmarshal(bodyBytes, &result)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
assert.Nil(err)
|
||||
}
|
||||
TenantName := &result.Tenants[0].Name // The array has to be empty, no index accessible
|
||||
fmt.Println(*TenantName)
|
||||
assert.Equal("storage-lite", *TenantName, *TenantName)
|
||||
printEndFunc("TestListTenants")
|
||||
}
|
||||
|
||||
func CreateTenant(tenantName string, namespace string, accessKey string, secretKey string, accessKeys []string, idp map[string]interface{}, tls map[string]interface{}, prometheusConfiguration map[string]interface{}, logSearchConfiguration map[string]interface{}, erasureCodingParity int, pools []map[string]interface{}, exposeConsole bool, exposeMinIO bool, image string, serviceName string, enablePrometheus bool, enableConsole bool, enableTLS bool, secretKeys []string) (*http.Response, error) {
|
||||
/*
|
||||
Helper function to create a tenant
|
||||
HTTP Verb: POST
|
||||
API: /api/v1/tenants
|
||||
*/
|
||||
requestDataAdd := map[string]interface{}{
|
||||
"name": tenantName,
|
||||
"namespace": namespace,
|
||||
"access_key": accessKey,
|
||||
"secret_key": secretKey,
|
||||
"access_keys": accessKeys,
|
||||
"secret_keys": secretKeys,
|
||||
"enable_tls": enableTLS,
|
||||
"enable_console": enableConsole,
|
||||
"enable_prometheus": enablePrometheus,
|
||||
"service_name": serviceName,
|
||||
"image": image,
|
||||
"expose_minio": exposeMinIO,
|
||||
"expose_console": exposeConsole,
|
||||
"pools": pools,
|
||||
"erasureCodingParity": erasureCodingParity,
|
||||
"logSearchConfiguration": logSearchConfiguration,
|
||||
"prometheusConfiguration": prometheusConfiguration,
|
||||
"tls": tls,
|
||||
"idp": idp,
|
||||
}
|
||||
requestDataJSON, _ := json.Marshal(requestDataAdd)
|
||||
requestDataBody := bytes.NewReader(requestDataJSON)
|
||||
request, err := http.NewRequest(
|
||||
"POST",
|
||||
"http://localhost:9090/api/v1/tenants",
|
||||
requestDataBody,
|
||||
)
|
||||
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 TestCreateTenant(t *testing.T) {
|
||||
printStartFunc("TestCreateTenant")
|
||||
|
||||
// Variables
|
||||
assert := assert.New(t)
|
||||
erasureCodingParity := 2
|
||||
tenantName := "new-tenant"
|
||||
namespace := "default"
|
||||
accessKey := ""
|
||||
secretKey := ""
|
||||
var accessKeys []string
|
||||
var secretKeys []string
|
||||
var minio []string
|
||||
var caCertificates []string
|
||||
var consoleCAcertificates []string
|
||||
enableTLS := true
|
||||
enableConsole := true
|
||||
enablePrometheus := true
|
||||
serviceName := ""
|
||||
image := ""
|
||||
exposeMinIO := true
|
||||
exposeConsole := true
|
||||
values := make([]string, 1)
|
||||
values[0] = "new-tenant"
|
||||
values2 := make([]string, 1)
|
||||
values2[0] = "pool-0"
|
||||
keys := make([]map[string]interface{}, 1)
|
||||
keys[0] = map[string]interface{}{
|
||||
"access_key": "IGLksSXdiU3fjcRI",
|
||||
"secret_key": "EqeCPZ1xBYdnygizxxRWnkH09N2350nO",
|
||||
}
|
||||
pools := make([]map[string]interface{}, 1)
|
||||
matchExpressions := make([]map[string]interface{}, 2)
|
||||
matchExpressions[0] = map[string]interface{}{
|
||||
"key": "v1.min.io/tenant",
|
||||
"operator": "In",
|
||||
"values": values,
|
||||
}
|
||||
matchExpressions[1] = map[string]interface{}{
|
||||
"key": "v1.min.io/pool",
|
||||
"operator": "In",
|
||||
"values": values2,
|
||||
}
|
||||
requiredDuringSchedulingIgnoredDuringExecution := make([]map[string]interface{}, 1)
|
||||
requiredDuringSchedulingIgnoredDuringExecution[0] = map[string]interface{}{
|
||||
"labelSelector": map[string]interface{}{
|
||||
"matchExpressions": matchExpressions,
|
||||
},
|
||||
"topologyKey": "kubernetes.io/hostname",
|
||||
}
|
||||
pools0 := map[string]interface{}{
|
||||
"name": "pool-0",
|
||||
"servers": 4,
|
||||
"volumes_per_server": 1,
|
||||
"volume_configuration": map[string]interface{}{
|
||||
"size": 26843545600,
|
||||
"storage_class_name": "standard",
|
||||
},
|
||||
"securityContext": nil,
|
||||
"affinity": map[string]interface{}{
|
||||
"podAntiAffinity": map[string]interface{}{
|
||||
"requiredDuringSchedulingIgnoredDuringExecution": requiredDuringSchedulingIgnoredDuringExecution,
|
||||
},
|
||||
},
|
||||
"resources": map[string]interface{}{
|
||||
"requests": map[string]interface{}{
|
||||
"cpu": 2,
|
||||
"memory": 2,
|
||||
},
|
||||
},
|
||||
}
|
||||
logSearchConfiguration := map[string]interface{}{
|
||||
"image": "",
|
||||
"postgres_image": "",
|
||||
"postgres_init_image": "",
|
||||
}
|
||||
prometheusConfiguration := map[string]interface{}{
|
||||
"image": "",
|
||||
"sidecar_image": "",
|
||||
"init_image": "",
|
||||
}
|
||||
tls := map[string]interface{}{
|
||||
"minio": minio,
|
||||
"ca_certificates": caCertificates,
|
||||
"console_ca_certificates": consoleCAcertificates,
|
||||
}
|
||||
idp := map[string]interface{}{
|
||||
"keys": keys,
|
||||
}
|
||||
pools[0] = pools0
|
||||
|
||||
// 1. Create Tenant
|
||||
resp, err := CreateTenant(
|
||||
tenantName,
|
||||
namespace,
|
||||
accessKey,
|
||||
secretKey,
|
||||
accessKeys,
|
||||
idp,
|
||||
tls,
|
||||
prometheusConfiguration,
|
||||
logSearchConfiguration,
|
||||
erasureCodingParity,
|
||||
pools,
|
||||
exposeConsole,
|
||||
exposeMinIO,
|
||||
image,
|
||||
serviceName,
|
||||
enablePrometheus,
|
||||
enableConsole,
|
||||
enableTLS,
|
||||
secretKeys,
|
||||
)
|
||||
assert.Nil(err)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
if resp != nil {
|
||||
assert.Equal(
|
||||
200, resp.StatusCode, "Status Code is incorrect")
|
||||
}
|
||||
|
||||
printEndFunc("TestCreateTenant")
|
||||
}
|
||||
|
||||
func ListTenantsByNameSpace(namespace string) (*http.Response, error) {
|
||||
/*
|
||||
Helper function to list buckets
|
||||
HTTP Verb: GET
|
||||
URL: http://localhost:9090/api/v1/namespaces/{namespace}/tenants
|
||||
*/
|
||||
request, err := http.NewRequest(
|
||||
"GET", "http://localhost:9090/api/v1/namespaces/"+namespace+"/tenants", 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 TestListTenantsByNameSpace(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
namespace := "default"
|
||||
resp, err := ListTenantsByNameSpace(namespace)
|
||||
assert.Nil(err)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
if resp != nil {
|
||||
assert.Equal(
|
||||
200, resp.StatusCode, "Status Code is incorrect")
|
||||
}
|
||||
bodyBytes, _ := ioutil.ReadAll(resp.Body)
|
||||
result := models.ListTenantsResponse{}
|
||||
err = json.Unmarshal(bodyBytes, &result)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
assert.Nil(err)
|
||||
}
|
||||
TenantName := &result.Tenants[0].Name // The array has to be empty, no index accessible
|
||||
fmt.Println(*TenantName)
|
||||
assert.Equal("new-tenant", *TenantName, *TenantName)
|
||||
}
|
||||
|
||||
func ListNodeLabels() (*http.Response, error) {
|
||||
/*
|
||||
Helper function to list buckets
|
||||
HTTP Verb: GET
|
||||
URL: http://localhost:9090/api/v1/nodes/labels
|
||||
*/
|
||||
request, err := http.NewRequest(
|
||||
"GET", "http://localhost:9090/api/v1/nodes/labels", 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 TestListNodeLabels(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
resp, err := ListNodeLabels()
|
||||
assert.Nil(err)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
finalResponse := inspectHTTPResponse(resp)
|
||||
if resp != nil {
|
||||
assert.Equal(
|
||||
200, resp.StatusCode, finalResponse)
|
||||
}
|
||||
// "beta.kubernetes.io/arch" is a label of our nodes and is expected
|
||||
assert.True(
|
||||
strings.Contains(finalResponse, "beta.kubernetes.io/arch"),
|
||||
finalResponse)
|
||||
}
|
||||
@@ -47,7 +47,6 @@ var (
|
||||
|
||||
// LicenseKey in memory license key used by console ui
|
||||
LicenseKey = ""
|
||||
|
||||
// GlobalRootCAs is CA root certificates, a nil value means system certs pool will be used
|
||||
GlobalRootCAs *x509.CertPool
|
||||
// GlobalPublicCerts has certificates Console will use to serve clients
|
||||
|
||||
@@ -3454,6 +3454,12 @@ func init() {
|
||||
"pool_count": {
|
||||
"type": "integer"
|
||||
},
|
||||
"tiers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/tenantTierElement"
|
||||
}
|
||||
},
|
||||
"total_size": {
|
||||
"type": "integer"
|
||||
},
|
||||
@@ -3696,6 +3702,21 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"tenantTierElement": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"size": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tenantUsage": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -8044,6 +8065,12 @@ func init() {
|
||||
"pool_count": {
|
||||
"type": "integer"
|
||||
},
|
||||
"tiers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/tenantTierElement"
|
||||
}
|
||||
},
|
||||
"total_size": {
|
||||
"type": "integer"
|
||||
},
|
||||
@@ -8286,6 +8313,21 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"tenantTierElement": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"size": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tenantUsage": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -255,6 +255,8 @@ func serveProxy(responseWriter http.ResponseWriter, req *http.Request) {
|
||||
// Allow iframes
|
||||
responseWriter.Header().Set("X-Frame-Options", "SAMEORIGIN")
|
||||
responseWriter.Header().Set("X-XSS-Protection", "1; mode=block")
|
||||
// Pass HTTP status code to proxy response
|
||||
responseWriter.WriteHeader(resp.StatusCode)
|
||||
|
||||
io.Copy(responseWriter, resp.Body)
|
||||
|
||||
|
||||
156
operatorapi/tenant_get.go
Normal file
156
operatorapi/tenant_get.go
Normal file
@@ -0,0 +1,156 @@
|
||||
// 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 (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/minio/console/cluster"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/operatorapi/operations/operator_api"
|
||||
"github.com/minio/console/restapi"
|
||||
miniov2 "github.com/minio/operator/pkg/apis/minio.min.io/v2"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func getTenantDetailsResponse(session *models.Principal, params operator_api.TenantDetailsParams) (*models.Tenant, *models.Error) {
|
||||
// 5 seconds timeout
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
opClientClientSet, err := cluster.OperatorClient(session.STSSessionToken)
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
|
||||
opClient := &operatorClient{
|
||||
client: opClientClientSet,
|
||||
}
|
||||
|
||||
minTenant, err := getTenant(ctx, opClient, params.Namespace, params.Tenant)
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
|
||||
info := getTenantInfo(minTenant)
|
||||
|
||||
// get Kubernetes Client
|
||||
clientSet, err := cluster.K8sClient(session.STSSessionToken)
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
|
||||
k8sClient := k8sClient{
|
||||
client: clientSet,
|
||||
}
|
||||
|
||||
tenantConfiguration, err := GetTenantConfiguration(ctx, &k8sClient, minTenant)
|
||||
if err != nil {
|
||||
restapi.LogError("unable to fetch configuration for tenant %s: %v", minTenant.Name, err)
|
||||
}
|
||||
|
||||
// detect if AD/LDAP is enabled
|
||||
ldapEnabled := false
|
||||
if string(tenantConfiguration["MINIO_IDENTITY_LDAP_SERVER_ADDR"]) != "" {
|
||||
ldapEnabled = true
|
||||
}
|
||||
|
||||
// detect if OpenID is enabled
|
||||
oidcEnabled := false
|
||||
if string(tenantConfiguration["MINIO_IDENTITY_OPENID_CONFIG_URL"]) != "" {
|
||||
oidcEnabled = true
|
||||
}
|
||||
|
||||
// detect if encryption is enabled
|
||||
if minTenant.HasKESEnabled() || string(tenantConfiguration["MINIO_KMS_SECRET_KEY"]) != "" {
|
||||
info.EncryptionEnabled = true
|
||||
}
|
||||
|
||||
info.LogEnabled = minTenant.HasLogEnabled()
|
||||
info.MonitoringEnabled = minTenant.HasPrometheusEnabled()
|
||||
info.IdpAdEnabled = ldapEnabled
|
||||
info.IdpOidcEnabled = oidcEnabled
|
||||
info.MinioTLS = minTenant.TLS()
|
||||
|
||||
// attach status information
|
||||
info.Status = &models.TenantStatus{
|
||||
HealthStatus: string(minTenant.Status.HealthStatus),
|
||||
DrivesHealing: minTenant.Status.DrivesHealing,
|
||||
DrivesOffline: minTenant.Status.DrivesOffline,
|
||||
DrivesOnline: minTenant.Status.DrivesOnline,
|
||||
WriteQuorum: minTenant.Status.WriteQuorum,
|
||||
Usage: &models.TenantStatusUsage{
|
||||
Raw: minTenant.Status.Usage.RawCapacity,
|
||||
RawUsage: minTenant.Status.Usage.RawUsage,
|
||||
Capacity: minTenant.Status.Usage.Capacity,
|
||||
CapacityUsage: minTenant.Status.Usage.Usage,
|
||||
},
|
||||
}
|
||||
|
||||
// get tenant service
|
||||
minTenant.EnsureDefaults()
|
||||
//minio service
|
||||
minSvc, err := k8sClient.getService(ctx, minTenant.Namespace, minTenant.MinIOCIServiceName(), metav1.GetOptions{})
|
||||
if err != nil {
|
||||
// we can tolerate this error
|
||||
restapi.LogError("Unable to get MinIO service name: %v, continuing", err)
|
||||
}
|
||||
//console service
|
||||
conSvc, err := k8sClient.getService(ctx, minTenant.Namespace, minTenant.ConsoleCIServiceName(), metav1.GetOptions{})
|
||||
if err != nil {
|
||||
// we can tolerate this error
|
||||
restapi.LogError("Unable to get MinIO console service name: %v, continuing", err)
|
||||
}
|
||||
|
||||
schema := "http"
|
||||
consoleSchema := "http"
|
||||
consolePort := fmt.Sprintf(":%d", miniov2.ConsolePort)
|
||||
if minTenant.TLS() {
|
||||
schema = "https"
|
||||
consoleSchema = "https"
|
||||
consolePort = fmt.Sprintf(":%d", miniov2.ConsoleTLSPort)
|
||||
}
|
||||
var minioEndpoint string
|
||||
var consoleEndpoint string
|
||||
if minSvc != nil && len(minSvc.Status.LoadBalancer.Ingress) > 0 {
|
||||
if minSvc.Status.LoadBalancer.Ingress[0].IP != "" {
|
||||
minioEndpoint = fmt.Sprintf("%s://%s", schema, minSvc.Status.LoadBalancer.Ingress[0].IP)
|
||||
}
|
||||
|
||||
if minSvc.Status.LoadBalancer.Ingress[0].Hostname != "" {
|
||||
minioEndpoint = fmt.Sprintf("%s://%s", schema, minSvc.Status.LoadBalancer.Ingress[0].Hostname)
|
||||
}
|
||||
|
||||
}
|
||||
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)
|
||||
}
|
||||
if conSvc.Status.LoadBalancer.Ingress[0].Hostname != "" {
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
return info, nil
|
||||
}
|
||||
103
operatorapi/tenant_update.go
Normal file
103
operatorapi/tenant_update.go
Normal file
@@ -0,0 +1,103 @@
|
||||
// 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 (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/minio/console/operatorapi/operations/operator_api"
|
||||
utils2 "github.com/minio/console/pkg/utils"
|
||||
"github.com/minio/console/restapi"
|
||||
miniov2 "github.com/minio/operator/pkg/apis/minio.min.io/v2"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
v1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
)
|
||||
|
||||
// updateTenantAction does an update on the minioTenant by patching the desired changes
|
||||
func updateTenantAction(ctx context.Context, operatorClient OperatorClientI, clientset v1.CoreV1Interface, httpCl utils2.HTTPClientI, namespace string, params operator_api.UpdateTenantParams) error {
|
||||
imageToUpdate := params.Body.Image
|
||||
imageRegistryReq := params.Body.ImageRegistry
|
||||
|
||||
minInst, err := operatorClient.TenantGet(ctx, namespace, params.Tenant, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// we can take either the `image_pull_secret` of the `image_registry` but not both
|
||||
if params.Body.ImagePullSecret != "" {
|
||||
minInst.Spec.ImagePullSecret.Name = params.Body.ImagePullSecret
|
||||
} else {
|
||||
// update the image pull secret content
|
||||
if _, err := setImageRegistry(ctx, imageRegistryReq, clientset, namespace, params.Tenant); err != nil {
|
||||
restapi.LogError("error setting image registry secret: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// if image to update is empty we'll use the latest image by default
|
||||
if strings.TrimSpace(imageToUpdate) != "" {
|
||||
minInst.Spec.Image = imageToUpdate
|
||||
} else {
|
||||
im, err := utils2.GetLatestMinIOImage(httpCl)
|
||||
// if we can't get the MinIO image, we won' auto-update it unless it's explicit by name
|
||||
if err == nil {
|
||||
minInst.Spec.Image = *im
|
||||
}
|
||||
}
|
||||
|
||||
// Prometheus Annotations
|
||||
currentAnnotations := minInst.Annotations
|
||||
prometheusAnnotations := map[string]string{
|
||||
prometheusPath: "/minio/prometheus/metrics",
|
||||
prometheusPort: fmt.Sprint(miniov2.MinIOPort),
|
||||
prometheusScrape: "true",
|
||||
}
|
||||
if params.Body.EnablePrometheus && currentAnnotations != nil {
|
||||
// add prometheus annotations to the tenant
|
||||
minInst.Annotations = addAnnotations(currentAnnotations, prometheusAnnotations)
|
||||
// add prometheus annotations to the each pool
|
||||
if minInst.Spec.Pools != nil {
|
||||
for _, pool := range minInst.Spec.Pools {
|
||||
poolAnnotations := pool.VolumeClaimTemplate.GetObjectMeta().GetAnnotations()
|
||||
pool.VolumeClaimTemplate.GetObjectMeta().SetAnnotations(addAnnotations(poolAnnotations, prometheusAnnotations))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// remove prometheus annotations to the tenant
|
||||
minInst.Annotations = removeAnnotations(currentAnnotations, prometheusAnnotations)
|
||||
// add prometheus annotations from each pool
|
||||
if minInst.Spec.Pools != nil {
|
||||
for _, pool := range minInst.Spec.Pools {
|
||||
poolAnnotations := pool.VolumeClaimTemplate.GetObjectMeta().GetAnnotations()
|
||||
pool.VolumeClaimTemplate.GetObjectMeta().SetAnnotations(removeAnnotations(poolAnnotations, prometheusAnnotations))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
payloadBytes, err := json.Marshal(minInst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = operatorClient.TenantPatch(ctx, namespace, minInst.Name, types.MergePatchType, payloadBytes, metav1.PatchOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -528,132 +528,6 @@ func getTenantInfo(tenant *miniov2.Tenant) *models.Tenant {
|
||||
}
|
||||
}
|
||||
|
||||
func getTenantDetailsResponse(session *models.Principal, params operator_api.TenantDetailsParams) (*models.Tenant, *models.Error) {
|
||||
// 5 seconds timeout
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
opClientClientSet, err := cluster.OperatorClient(session.STSSessionToken)
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
|
||||
opClient := &operatorClient{
|
||||
client: opClientClientSet,
|
||||
}
|
||||
|
||||
minTenant, err := getTenant(ctx, opClient, params.Namespace, params.Tenant)
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
|
||||
info := getTenantInfo(minTenant)
|
||||
|
||||
// get Kubernetes Client
|
||||
clientSet, err := cluster.K8sClient(session.STSSessionToken)
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
|
||||
k8sClient := k8sClient{
|
||||
client: clientSet,
|
||||
}
|
||||
|
||||
tenantConfiguration, err := GetTenantConfiguration(ctx, &k8sClient, minTenant)
|
||||
if err != nil {
|
||||
restapi.LogError("unable to fetch configuration for tenant %s: %v", minTenant.Name, err)
|
||||
}
|
||||
|
||||
// detect if AD/LDAP is enabled
|
||||
ldapEnabled := false
|
||||
if string(tenantConfiguration["MINIO_IDENTITY_LDAP_SERVER_ADDR"]) != "" {
|
||||
ldapEnabled = true
|
||||
}
|
||||
|
||||
// detect if OpenID is enabled
|
||||
oidcEnabled := false
|
||||
if string(tenantConfiguration["MINIO_IDENTITY_OPENID_CONFIG_URL"]) != "" {
|
||||
oidcEnabled = true
|
||||
}
|
||||
|
||||
// detect if encryption is enabled
|
||||
if minTenant.HasKESEnabled() || string(tenantConfiguration["MINIO_KMS_SECRET_KEY"]) != "" {
|
||||
info.EncryptionEnabled = true
|
||||
}
|
||||
|
||||
info.LogEnabled = minTenant.HasLogEnabled()
|
||||
info.MonitoringEnabled = minTenant.HasPrometheusEnabled()
|
||||
info.IdpAdEnabled = ldapEnabled
|
||||
info.IdpOidcEnabled = oidcEnabled
|
||||
info.MinioTLS = minTenant.TLS()
|
||||
|
||||
// attach status information
|
||||
info.Status = &models.TenantStatus{
|
||||
HealthStatus: string(minTenant.Status.HealthStatus),
|
||||
DrivesHealing: minTenant.Status.DrivesHealing,
|
||||
DrivesOffline: minTenant.Status.DrivesOffline,
|
||||
DrivesOnline: minTenant.Status.DrivesOnline,
|
||||
WriteQuorum: minTenant.Status.WriteQuorum,
|
||||
Usage: &models.TenantStatusUsage{
|
||||
Raw: minTenant.Status.Usage.RawCapacity,
|
||||
RawUsage: minTenant.Status.Usage.RawUsage,
|
||||
Capacity: minTenant.Status.Usage.Capacity,
|
||||
CapacityUsage: minTenant.Status.Usage.Usage,
|
||||
},
|
||||
}
|
||||
|
||||
// get tenant service
|
||||
minTenant.EnsureDefaults()
|
||||
//minio service
|
||||
minSvc, err := k8sClient.getService(ctx, minTenant.Namespace, minTenant.MinIOCIServiceName(), metav1.GetOptions{})
|
||||
if err != nil {
|
||||
// we can tolerate this error
|
||||
restapi.LogError("Unable to get MinIO service name: %v, continuing", err)
|
||||
}
|
||||
//console service
|
||||
conSvc, err := k8sClient.getService(ctx, minTenant.Namespace, minTenant.ConsoleCIServiceName(), metav1.GetOptions{})
|
||||
if err != nil {
|
||||
// we can tolerate this error
|
||||
restapi.LogError("Unable to get MinIO console service name: %v, continuing", err)
|
||||
}
|
||||
|
||||
schema := "http"
|
||||
consoleSchema := "http"
|
||||
consolePort := fmt.Sprintf(":%d", miniov2.ConsolePort)
|
||||
if minTenant.TLS() {
|
||||
schema = "https"
|
||||
consoleSchema = "https"
|
||||
consolePort = fmt.Sprintf(":%d", miniov2.ConsoleTLSPort)
|
||||
}
|
||||
var minioEndpoint string
|
||||
var consoleEndpoint string
|
||||
if minSvc != nil && len(minSvc.Status.LoadBalancer.Ingress) > 0 {
|
||||
if minSvc.Status.LoadBalancer.Ingress[0].IP != "" {
|
||||
minioEndpoint = fmt.Sprintf("%s://%s", schema, minSvc.Status.LoadBalancer.Ingress[0].IP)
|
||||
}
|
||||
|
||||
if minSvc.Status.LoadBalancer.Ingress[0].Hostname != "" {
|
||||
minioEndpoint = fmt.Sprintf("%s://%s", schema, minSvc.Status.LoadBalancer.Ingress[0].Hostname)
|
||||
}
|
||||
|
||||
}
|
||||
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)
|
||||
}
|
||||
if conSvc.Status.LoadBalancer.Ingress[0].Hostname != "" {
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func parseCertificate(name string, rawCert []byte) (*models.CertificateInfo, error) {
|
||||
block, _ := pem.Decode(rawCert)
|
||||
if block == nil {
|
||||
@@ -698,32 +572,44 @@ func parseTenantCertificates(ctx context.Context, clientSet K8sClientI, namespac
|
||||
}
|
||||
// Extract public key from certificate TLS secret
|
||||
if rawCert, ok := keyPair.Data[publicKey]; ok {
|
||||
block, _ := pem.Decode(rawCert)
|
||||
if block == nil {
|
||||
// If certificate failed to decode skip
|
||||
continue
|
||||
var blocks []byte
|
||||
for {
|
||||
var block *pem.Block
|
||||
block, rawCert = pem.Decode(rawCert)
|
||||
if block == nil {
|
||||
break
|
||||
}
|
||||
if block.Type == "CERTIFICATE" {
|
||||
blocks = append(blocks, block.Bytes...)
|
||||
}
|
||||
}
|
||||
cert, err := x509.ParseCertificate(block.Bytes)
|
||||
// parse all certificates we found on this k8s secret
|
||||
certs, err := x509.ParseCertificates(blocks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
domains := []string{}
|
||||
// append certificate domain names
|
||||
if len(cert.DNSNames) > 0 {
|
||||
domains = append(domains, cert.DNSNames...)
|
||||
}
|
||||
// append certificate IPs
|
||||
if len(cert.IPAddresses) > 0 {
|
||||
for _, ip := range cert.IPAddresses {
|
||||
domains = append(domains, ip.String())
|
||||
for _, cert := range certs {
|
||||
var domains []string
|
||||
if cert.Subject.CommonName != "" {
|
||||
domains = append(domains, cert.Subject.CommonName)
|
||||
}
|
||||
// append certificate domain names
|
||||
if len(cert.DNSNames) > 0 {
|
||||
domains = append(domains, cert.DNSNames...)
|
||||
}
|
||||
// append certificate IPs
|
||||
if len(cert.IPAddresses) > 0 {
|
||||
for _, ip := range cert.IPAddresses {
|
||||
domains = append(domains, ip.String())
|
||||
}
|
||||
}
|
||||
certificates = append(certificates, &models.CertificateInfo{
|
||||
SerialNumber: cert.SerialNumber.String(),
|
||||
Name: secret.Name,
|
||||
Domains: domains,
|
||||
Expiry: cert.NotAfter.Format(time.RFC3339),
|
||||
})
|
||||
}
|
||||
certificates = append(certificates, &models.CertificateInfo{
|
||||
SerialNumber: cert.SerialNumber.String(),
|
||||
Name: secret.Name,
|
||||
Domains: domains,
|
||||
Expiry: cert.NotAfter.Format(time.RFC3339),
|
||||
})
|
||||
}
|
||||
}
|
||||
return certificates, nil
|
||||
@@ -753,8 +639,6 @@ func getTenantSecurityResponse(session *models.Principal, params operator_api.Te
|
||||
// 5 seconds timeout
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
//ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
//defer cancel()
|
||||
opClientClientSet, err := cluster.OperatorClient(session.STSSessionToken)
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
@@ -924,6 +808,18 @@ func listTenants(ctx context.Context, operatorClient OperatorClientI, namespace
|
||||
deletion = tenant.ObjectMeta.DeletionTimestamp.Format(time.RFC3339)
|
||||
}
|
||||
|
||||
var tiers []*models.TenantTierElement
|
||||
|
||||
for _, tier := range tenant.Status.Usage.Tiers {
|
||||
tierItem := &models.TenantTierElement{
|
||||
Name: tier.Name,
|
||||
Type: tier.Type,
|
||||
Size: tier.TotalSize,
|
||||
}
|
||||
|
||||
tiers = append(tiers, tierItem)
|
||||
}
|
||||
|
||||
tenants = append(tenants, &models.TenantList{
|
||||
CreationDate: tenant.ObjectMeta.CreationTimestamp.Format(time.RFC3339),
|
||||
DeletionDate: deletion,
|
||||
@@ -939,6 +835,7 @@ func listTenants(ctx context.Context, operatorClient OperatorClientI, namespace
|
||||
CapacityRawUsage: tenant.Status.Usage.RawUsage,
|
||||
Capacity: tenant.Status.Usage.Capacity,
|
||||
CapacityUsage: tenant.Status.Usage.Usage,
|
||||
Tiers: tiers,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1040,77 +937,6 @@ func setImageRegistry(ctx context.Context, req *models.ImageRegistry, clientset
|
||||
return pullSecretName, nil
|
||||
}
|
||||
|
||||
// updateTenantAction does an update on the minioTenant by patching the desired changes
|
||||
func updateTenantAction(ctx context.Context, operatorClient OperatorClientI, clientset v1.CoreV1Interface, httpCl utils2.HTTPClientI, namespace string, params operator_api.UpdateTenantParams) error {
|
||||
imageToUpdate := params.Body.Image
|
||||
imageRegistryReq := params.Body.ImageRegistry
|
||||
|
||||
minInst, err := operatorClient.TenantGet(ctx, namespace, params.Tenant, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// we can take either the `image_pull_secret` of the `image_registry` but not both
|
||||
if params.Body.ImagePullSecret != "" {
|
||||
minInst.Spec.ImagePullSecret.Name = params.Body.ImagePullSecret
|
||||
} else {
|
||||
// update the image pull secret content
|
||||
if _, err := setImageRegistry(ctx, imageRegistryReq, clientset, namespace, params.Tenant); err != nil {
|
||||
restapi.LogError("error setting image registry secret: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// if image to update is empty we'll use the latest image by default
|
||||
if strings.TrimSpace(imageToUpdate) != "" {
|
||||
minInst.Spec.Image = imageToUpdate
|
||||
} else {
|
||||
im, err := cluster.GetLatestMinioImage(httpCl)
|
||||
// if we can't get the MinIO image, we won' auto-update it unless it's explicit by name
|
||||
if err == nil {
|
||||
minInst.Spec.Image = *im
|
||||
}
|
||||
}
|
||||
|
||||
// Prometheus Annotations
|
||||
currentAnnotations := minInst.Annotations
|
||||
prometheusAnnotations := map[string]string{
|
||||
prometheusPath: "/minio/prometheus/metrics",
|
||||
prometheusPort: fmt.Sprint(miniov2.MinIOPort),
|
||||
prometheusScrape: "true",
|
||||
}
|
||||
if params.Body.EnablePrometheus && currentAnnotations != nil {
|
||||
// add prometheus annotations to the tenant
|
||||
minInst.Annotations = addAnnotations(currentAnnotations, prometheusAnnotations)
|
||||
// add prometheus annotations to the each pool
|
||||
if minInst.Spec.Pools != nil {
|
||||
for _, pool := range minInst.Spec.Pools {
|
||||
poolAnnotations := pool.VolumeClaimTemplate.GetObjectMeta().GetAnnotations()
|
||||
pool.VolumeClaimTemplate.GetObjectMeta().SetAnnotations(addAnnotations(poolAnnotations, prometheusAnnotations))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// remove prometheus annotations to the tenant
|
||||
minInst.Annotations = removeAnnotations(currentAnnotations, prometheusAnnotations)
|
||||
// add prometheus annotations from each pool
|
||||
if minInst.Spec.Pools != nil {
|
||||
for _, pool := range minInst.Spec.Pools {
|
||||
poolAnnotations := pool.VolumeClaimTemplate.GetObjectMeta().GetAnnotations()
|
||||
pool.VolumeClaimTemplate.GetObjectMeta().SetAnnotations(removeAnnotations(poolAnnotations, prometheusAnnotations))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
payloadBytes, err := json.Marshal(minInst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = operatorClient.TenantPatch(ctx, namespace, minInst.Name, types.MergePatchType, payloadBytes, metav1.PatchOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// addAnnotations will merge two annotation maps
|
||||
func addAnnotations(annotationsOne, annotationsTwo map[string]string) map[string]string {
|
||||
if annotationsOne == nil {
|
||||
@@ -34,8 +34,6 @@ var (
|
||||
// SchemeBuilder points to a list of functions added to Scheme.
|
||||
SchemeBuilder runtime.SchemeBuilder
|
||||
localSchemeBuilder = &SchemeBuilder
|
||||
// AddToScheme applies all stored functions to Scheme.
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -143,30 +143,33 @@ func getLoginCallbackURL(r *http.Request) string {
|
||||
return redirectURL
|
||||
}
|
||||
|
||||
var supportedResponseTypes = set.CreateStringSet([]string{
|
||||
"code id_token",
|
||||
"code token id_token",
|
||||
}...)
|
||||
var requiredResponseTypes = set.CreateStringSet("code")
|
||||
|
||||
// NewOauth2ProviderClient instantiates a new oauth2 client using the configured credentials
|
||||
// it returns a *Provider object that contains the necessary configuration to initiate an
|
||||
// oauth2 authentication flow
|
||||
// oauth2 authentication flow.
|
||||
//
|
||||
// We only support Authentication with the Authorization Code Flow - spec:
|
||||
// https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth
|
||||
func NewOauth2ProviderClient(scopes []string, r *http.Request, httpClient *http.Client) (*Provider, error) {
|
||||
ddoc, err := parseDiscoveryDoc(GetIDPURL(), httpClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var supported bool
|
||||
supportedResponseTypes := set.NewStringSet()
|
||||
for _, responseType := range ddoc.ResponseTypesSupported {
|
||||
if supportedResponseTypes.Contains(responseType) {
|
||||
supported = true
|
||||
break // one support is enough
|
||||
// FIXME: ResponseTypesSupported is a JSON array of strings - it
|
||||
// may not actually have strings with spaces inside them -
|
||||
// making the following code unnecessary.
|
||||
for _, s := range strings.Fields(responseType) {
|
||||
supportedResponseTypes.Add(s)
|
||||
}
|
||||
}
|
||||
isSupported := requiredResponseTypes.Difference(supportedResponseTypes).IsEmpty()
|
||||
|
||||
if !supported {
|
||||
return nil, fmt.Errorf("expected 'code id_token' response type - got %s, login not allowed", ddoc.ResponseTypesSupported)
|
||||
if !isSupported {
|
||||
return nil, fmt.Errorf("expected 'code' response type - got %s, login not allowed", ddoc.ResponseTypesSupported)
|
||||
}
|
||||
|
||||
// If provided scopes are empty we use a default list or the user configured list
|
||||
|
||||
@@ -1,317 +1,309 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "./static/css/main.90d417ae.css",
|
||||
"main.js": "./static/js/main.69273a1d.js",
|
||||
"static/js/1660.1a3b5397.chunk.js": "./static/js/1660.1a3b5397.chunk.js",
|
||||
"static/js/5282.cb13b8c4.chunk.js": "./static/js/5282.cb13b8c4.chunk.js",
|
||||
"static/js/2818.a52e5730.chunk.js": "./static/js/2818.a52e5730.chunk.js",
|
||||
"static/js/9560.6e9b7779.chunk.js": "./static/js/9560.6e9b7779.chunk.js",
|
||||
"static/js/9661.92a4e63a.chunk.js": "./static/js/9661.92a4e63a.chunk.js",
|
||||
"static/js/9330.122bf1a7.chunk.js": "./static/js/9330.122bf1a7.chunk.js",
|
||||
"static/js/7436.fed787a2.chunk.js": "./static/js/7436.fed787a2.chunk.js",
|
||||
"static/js/8428.f4d88368.chunk.js": "./static/js/8428.f4d88368.chunk.js",
|
||||
"static/js/9779.fed48861.chunk.js": "./static/js/9779.fed48861.chunk.js",
|
||||
"static/js/3617.b62a9bb2.chunk.js": "./static/js/3617.b62a9bb2.chunk.js",
|
||||
"static/js/7274.9c913af6.chunk.js": "./static/js/7274.9c913af6.chunk.js",
|
||||
"static/js/7842.8dfd596a.chunk.js": "./static/js/7842.8dfd596a.chunk.js",
|
||||
"static/js/4745.27ab197f.chunk.js": "./static/js/4745.27ab197f.chunk.js",
|
||||
"static/js/1796.26462172.chunk.js": "./static/js/1796.26462172.chunk.js",
|
||||
"static/js/8259.3b2561ab.chunk.js": "./static/js/8259.3b2561ab.chunk.js",
|
||||
"static/js/6023.aec2d9d1.chunk.js": "./static/js/6023.aec2d9d1.chunk.js",
|
||||
"static/js/6147.f2a7d841.chunk.js": "./static/js/6147.f2a7d841.chunk.js",
|
||||
"static/js/9275.6a834668.chunk.js": "./static/js/9275.6a834668.chunk.js",
|
||||
"static/js/8190.d56fddaa.chunk.js": "./static/js/8190.d56fddaa.chunk.js",
|
||||
"static/js/7314.0058a98f.chunk.js": "./static/js/7314.0058a98f.chunk.js",
|
||||
"static/js/7456.e2ad891d.chunk.js": "./static/js/7456.e2ad891d.chunk.js",
|
||||
"static/css/5822.dd80c1b6.chunk.css": "./static/css/5822.dd80c1b6.chunk.css",
|
||||
"static/js/5822.c1d62c79.chunk.js": "./static/js/5822.c1d62c79.chunk.js",
|
||||
"static/js/2699.3102be0f.chunk.js": "./static/js/2699.3102be0f.chunk.js",
|
||||
"static/js/5808.8da21793.chunk.js": "./static/js/5808.8da21793.chunk.js",
|
||||
"static/js/1237.b46ec019.chunk.js": "./static/js/1237.b46ec019.chunk.js",
|
||||
"static/js/189.06df2d49.chunk.js": "./static/js/189.06df2d49.chunk.js",
|
||||
"static/css/964.dd80c1b6.chunk.css": "./static/css/964.dd80c1b6.chunk.css",
|
||||
"static/js/964.c1751e75.chunk.js": "./static/js/964.c1751e75.chunk.js",
|
||||
"static/css/9807.dd80c1b6.chunk.css": "./static/css/9807.dd80c1b6.chunk.css",
|
||||
"static/js/9807.731eb17a.chunk.js": "./static/js/9807.731eb17a.chunk.js",
|
||||
"static/js/3806.b5b2c03c.chunk.js": "./static/js/3806.b5b2c03c.chunk.js",
|
||||
"static/js/8661.ade9e15c.chunk.js": "./static/js/8661.ade9e15c.chunk.js",
|
||||
"static/js/2886.a03a185d.chunk.js": "./static/js/2886.a03a185d.chunk.js",
|
||||
"static/js/4577.cd5b16fc.chunk.js": "./static/js/4577.cd5b16fc.chunk.js",
|
||||
"static/js/4298.e6c437dd.chunk.js": "./static/js/4298.e6c437dd.chunk.js",
|
||||
"static/js/2805.b4302353.chunk.js": "./static/js/2805.b4302353.chunk.js",
|
||||
"static/js/6873.27fbf284.chunk.js": "./static/js/6873.27fbf284.chunk.js",
|
||||
"static/js/428.ad58c353.chunk.js": "./static/js/428.ad58c353.chunk.js",
|
||||
"static/js/1069.77bb316e.chunk.js": "./static/js/1069.77bb316e.chunk.js",
|
||||
"static/js/9080.884725e7.chunk.js": "./static/js/9080.884725e7.chunk.js",
|
||||
"static/js/3276.1afa9e35.chunk.js": "./static/js/3276.1afa9e35.chunk.js",
|
||||
"static/js/6458.c6bf60f8.chunk.js": "./static/js/6458.c6bf60f8.chunk.js",
|
||||
"static/js/7551.b8d5fd21.chunk.js": "./static/js/7551.b8d5fd21.chunk.js",
|
||||
"static/js/7950.1793a548.chunk.js": "./static/js/7950.1793a548.chunk.js",
|
||||
"static/js/290.3a78b888.chunk.js": "./static/js/290.3a78b888.chunk.js",
|
||||
"static/js/8961.c7471e8d.chunk.js": "./static/js/8961.c7471e8d.chunk.js",
|
||||
"static/js/3967.eefb50e4.chunk.js": "./static/js/3967.eefb50e4.chunk.js",
|
||||
"static/css/4084.dd80c1b6.chunk.css": "./static/css/4084.dd80c1b6.chunk.css",
|
||||
"static/js/4084.57e7784d.chunk.js": "./static/js/4084.57e7784d.chunk.js",
|
||||
"static/js/8394.fa043a82.chunk.js": "./static/js/8394.fa043a82.chunk.js",
|
||||
"static/js/7664.b099b462.chunk.js": "./static/js/7664.b099b462.chunk.js",
|
||||
"static/js/1140.044ef809.chunk.js": "./static/js/1140.044ef809.chunk.js",
|
||||
"static/js/5961.7a71f2c5.chunk.js": "./static/js/5961.7a71f2c5.chunk.js",
|
||||
"static/js/2401.dcfa0659.chunk.js": "./static/js/2401.dcfa0659.chunk.js",
|
||||
"static/js/7498.adcacaca.chunk.js": "./static/js/7498.adcacaca.chunk.js",
|
||||
"static/js/9421.a6974f61.chunk.js": "./static/js/9421.a6974f61.chunk.js",
|
||||
"static/js/4860.3bea7736.chunk.js": "./static/js/4860.3bea7736.chunk.js",
|
||||
"static/js/5245.04e84402.chunk.js": "./static/js/5245.04e84402.chunk.js",
|
||||
"static/js/6549.bc76401b.chunk.js": "./static/js/6549.bc76401b.chunk.js",
|
||||
"static/css/8724.dd80c1b6.chunk.css": "./static/css/8724.dd80c1b6.chunk.css",
|
||||
"static/js/8724.2fda7628.chunk.js": "./static/js/8724.2fda7628.chunk.js",
|
||||
"static/js/2182.e1389a8d.chunk.js": "./static/js/2182.e1389a8d.chunk.js",
|
||||
"static/js/7764.7133a78a.chunk.js": "./static/js/7764.7133a78a.chunk.js",
|
||||
"static/js/4220.8d9a9028.chunk.js": "./static/js/4220.8d9a9028.chunk.js",
|
||||
"static/js/1719.a1c5fbc9.chunk.js": "./static/js/1719.a1c5fbc9.chunk.js",
|
||||
"static/js/3320.cf0913be.chunk.js": "./static/js/3320.cf0913be.chunk.js",
|
||||
"static/js/6645.1d65ce48.chunk.js": "./static/js/6645.1d65ce48.chunk.js",
|
||||
"static/js/9923.3911a310.chunk.js": "./static/js/9923.3911a310.chunk.js",
|
||||
"static/js/9586.f3d3466d.chunk.js": "./static/js/9586.f3d3466d.chunk.js",
|
||||
"static/js/9125.a86e3119.chunk.js": "./static/js/9125.a86e3119.chunk.js",
|
||||
"static/js/5781.33738b7f.chunk.js": "./static/js/5781.33738b7f.chunk.js",
|
||||
"static/js/7261.916fdbf6.chunk.js": "./static/js/7261.916fdbf6.chunk.js",
|
||||
"static/js/8306.047e9e54.chunk.js": "./static/js/8306.047e9e54.chunk.js",
|
||||
"static/js/6436.690eb2b9.chunk.js": "./static/js/6436.690eb2b9.chunk.js",
|
||||
"static/js/8343.67a940b1.chunk.js": "./static/js/8343.67a940b1.chunk.js",
|
||||
"static/js/2841.9d475dfe.chunk.js": "./static/js/2841.9d475dfe.chunk.js",
|
||||
"static/js/6167.d5f52864.chunk.js": "./static/js/6167.d5f52864.chunk.js",
|
||||
"static/js/7346.47702cc8.chunk.js": "./static/js/7346.47702cc8.chunk.js",
|
||||
"static/js/5144.19c094a4.chunk.js": "./static/js/5144.19c094a4.chunk.js",
|
||||
"static/js/5125.58c2feff.chunk.js": "./static/js/5125.58c2feff.chunk.js",
|
||||
"static/js/528.d01b02af.chunk.js": "./static/js/528.d01b02af.chunk.js",
|
||||
"static/js/7187.171b28f4.chunk.js": "./static/js/7187.171b28f4.chunk.js",
|
||||
"static/js/6173.925ab9b7.chunk.js": "./static/js/6173.925ab9b7.chunk.js",
|
||||
"static/js/953.677ddb95.chunk.js": "./static/js/953.677ddb95.chunk.js",
|
||||
"static/js/9193.feaac1ba.chunk.js": "./static/js/9193.feaac1ba.chunk.js",
|
||||
"static/js/7451.dabaf18f.chunk.js": "./static/js/7451.dabaf18f.chunk.js",
|
||||
"static/js/9924.020057ee.chunk.js": "./static/js/9924.020057ee.chunk.js",
|
||||
"static/css/9645.dd80c1b6.chunk.css": "./static/css/9645.dd80c1b6.chunk.css",
|
||||
"static/js/9645.71cc858a.chunk.js": "./static/js/9645.71cc858a.chunk.js",
|
||||
"static/js/5710.7386de50.chunk.js": "./static/js/5710.7386de50.chunk.js",
|
||||
"static/js/4121.0e3d5ae5.chunk.js": "./static/js/4121.0e3d5ae5.chunk.js",
|
||||
"static/js/3421.666af5cb.chunk.js": "./static/js/3421.666af5cb.chunk.js",
|
||||
"static/js/2892.f87668de.chunk.js": "./static/js/2892.f87668de.chunk.js",
|
||||
"static/js/7926.c65ecfc3.chunk.js": "./static/js/7926.c65ecfc3.chunk.js",
|
||||
"static/js/6145.9665a7b2.chunk.js": "./static/js/6145.9665a7b2.chunk.js",
|
||||
"static/css/3816.dd80c1b6.chunk.css": "./static/css/3816.dd80c1b6.chunk.css",
|
||||
"static/js/3816.c0b2fb6b.chunk.js": "./static/js/3816.c0b2fb6b.chunk.js",
|
||||
"static/js/2966.0b278e3b.chunk.js": "./static/js/2966.0b278e3b.chunk.js",
|
||||
"static/js/4177.381caad6.chunk.js": "./static/js/4177.381caad6.chunk.js",
|
||||
"static/js/9679.c1fd0ae5.chunk.js": "./static/js/9679.c1fd0ae5.chunk.js",
|
||||
"static/js/8333.d2ede110.chunk.js": "./static/js/8333.d2ede110.chunk.js",
|
||||
"static/js/1711.dfdfce0a.chunk.js": "./static/js/1711.dfdfce0a.chunk.js",
|
||||
"static/js/9.caa73b0e.chunk.js": "./static/js/9.caa73b0e.chunk.js",
|
||||
"static/js/4487.8cae9359.chunk.js": "./static/js/4487.8cae9359.chunk.js",
|
||||
"static/js/6866.a519feef.chunk.js": "./static/js/6866.a519feef.chunk.js",
|
||||
"static/js/8564.16b674dd.chunk.js": "./static/js/8564.16b674dd.chunk.js",
|
||||
"static/js/1666.9098f0d4.chunk.js": "./static/js/1666.9098f0d4.chunk.js",
|
||||
"static/js/7007.d9ef3b97.chunk.js": "./static/js/7007.d9ef3b97.chunk.js",
|
||||
"static/js/14.25ecb28d.chunk.js": "./static/js/14.25ecb28d.chunk.js",
|
||||
"static/js/3152.d03e4df4.chunk.js": "./static/js/3152.d03e4df4.chunk.js",
|
||||
"static/js/2066.16320a68.chunk.js": "./static/js/2066.16320a68.chunk.js",
|
||||
"static/js/5444.e8727da9.chunk.js": "./static/js/5444.e8727da9.chunk.js",
|
||||
"static/js/3690.536fb187.chunk.js": "./static/js/3690.536fb187.chunk.js",
|
||||
"static/js/875.130c3ed4.chunk.js": "./static/js/875.130c3ed4.chunk.js",
|
||||
"static/js/5399.6bc650ac.chunk.js": "./static/js/5399.6bc650ac.chunk.js",
|
||||
"static/js/606.28fdb5bc.chunk.js": "./static/js/606.28fdb5bc.chunk.js",
|
||||
"static/js/9769.a2bfb4d7.chunk.js": "./static/js/9769.a2bfb4d7.chunk.js",
|
||||
"static/js/6117.0fcd3d09.chunk.js": "./static/js/6117.0fcd3d09.chunk.js",
|
||||
"static/js/8954.00599ff1.chunk.js": "./static/js/8954.00599ff1.chunk.js",
|
||||
"static/js/2309.49be65c5.chunk.js": "./static/js/2309.49be65c5.chunk.js",
|
||||
"static/js/7248.1e0c4e19.chunk.js": "./static/js/7248.1e0c4e19.chunk.js",
|
||||
"static/js/3360.453f0701.chunk.js": "./static/js/3360.453f0701.chunk.js",
|
||||
"static/js/4322.ddc888e0.chunk.js": "./static/js/4322.ddc888e0.chunk.js",
|
||||
"static/js/9056.41f0e489.chunk.js": "./static/js/9056.41f0e489.chunk.js",
|
||||
"static/js/4837.98af4cfe.chunk.js": "./static/js/4837.98af4cfe.chunk.js",
|
||||
"static/js/3356.05b42758.chunk.js": "./static/js/3356.05b42758.chunk.js",
|
||||
"static/js/3020.3b2e782c.chunk.js": "./static/js/3020.3b2e782c.chunk.js",
|
||||
"static/js/2320.ad204ae5.chunk.js": "./static/js/2320.ad204ae5.chunk.js",
|
||||
"static/js/195.58f4f3fe.chunk.js": "./static/js/195.58f4f3fe.chunk.js",
|
||||
"static/js/8420.ac8efcdd.chunk.js": "./static/js/8420.ac8efcdd.chunk.js",
|
||||
"static/js/728.92b72106.chunk.js": "./static/js/728.92b72106.chunk.js",
|
||||
"static/js/187.c9da1b03.chunk.js": "./static/js/187.c9da1b03.chunk.js",
|
||||
"static/js/849.1c67c5fb.chunk.js": "./static/js/849.1c67c5fb.chunk.js",
|
||||
"static/js/7869.d312e0cb.chunk.js": "./static/js/7869.d312e0cb.chunk.js",
|
||||
"static/js/7939.d60313ae.chunk.js": "./static/js/7939.d60313ae.chunk.js",
|
||||
"static/js/3538.60e98cef.chunk.js": "./static/js/3538.60e98cef.chunk.js",
|
||||
"static/js/5676.7a115ec7.chunk.js": "./static/js/5676.7a115ec7.chunk.js",
|
||||
"static/js/1757.5d1b8ae4.chunk.js": "./static/js/1757.5d1b8ae4.chunk.js",
|
||||
"static/js/7663.e9d514d1.chunk.js": "./static/js/7663.e9d514d1.chunk.js",
|
||||
"static/js/3383.ab285f5a.chunk.js": "./static/js/3383.ab285f5a.chunk.js",
|
||||
"static/js/3045.cfe6cbf4.chunk.js": "./static/js/3045.cfe6cbf4.chunk.js",
|
||||
"static/js/6554.53f930ae.chunk.js": "./static/js/6554.53f930ae.chunk.js",
|
||||
"static/js/9831.1b5a6bb6.chunk.js": "./static/js/9831.1b5a6bb6.chunk.js",
|
||||
"static/js/9382.581734f3.chunk.js": "./static/js/9382.581734f3.chunk.js",
|
||||
"static/js/8174.6e95ea0c.chunk.js": "./static/js/8174.6e95ea0c.chunk.js",
|
||||
"static/js/1116.6c0eed8e.chunk.js": "./static/js/1116.6c0eed8e.chunk.js",
|
||||
"static/js/6430.e747de7c.chunk.js": "./static/js/6430.e747de7c.chunk.js",
|
||||
"static/js/4966.c825dc1c.chunk.js": "./static/js/4966.c825dc1c.chunk.js",
|
||||
"static/js/2363.5fc6aebe.chunk.js": "./static/js/2363.5fc6aebe.chunk.js",
|
||||
"static/js/2464.5dc72a90.chunk.js": "./static/js/2464.5dc72a90.chunk.js",
|
||||
"static/js/7520.087167a1.chunk.js": "./static/js/7520.087167a1.chunk.js",
|
||||
"main.js": "./static/js/main.5a7c25ee.js",
|
||||
"static/js/2483.511e6a32.chunk.js": "./static/js/2483.511e6a32.chunk.js",
|
||||
"static/js/6914.e9919921.chunk.js": "./static/js/6914.e9919921.chunk.js",
|
||||
"static/js/4209.7c3855ef.chunk.js": "./static/js/4209.7c3855ef.chunk.js",
|
||||
"static/js/1829.202650e3.chunk.js": "./static/js/1829.202650e3.chunk.js",
|
||||
"static/js/6041.a11c2e9a.chunk.js": "./static/js/6041.a11c2e9a.chunk.js",
|
||||
"static/js/5088.921b2534.chunk.js": "./static/js/5088.921b2534.chunk.js",
|
||||
"static/js/5140.8f5521e6.chunk.js": "./static/js/5140.8f5521e6.chunk.js",
|
||||
"static/js/1434.2cbee404.chunk.js": "./static/js/1434.2cbee404.chunk.js",
|
||||
"static/js/3176.640e537b.chunk.js": "./static/js/3176.640e537b.chunk.js",
|
||||
"static/js/6137.ac2c3fb7.chunk.js": "./static/js/6137.ac2c3fb7.chunk.js",
|
||||
"static/js/7045.e30cf01e.chunk.js": "./static/js/7045.e30cf01e.chunk.js",
|
||||
"static/js/9635.083b4e05.chunk.js": "./static/js/9635.083b4e05.chunk.js",
|
||||
"static/js/2338.8b9b592f.chunk.js": "./static/js/2338.8b9b592f.chunk.js",
|
||||
"static/js/4335.71899795.chunk.js": "./static/js/4335.71899795.chunk.js",
|
||||
"static/js/321.eedfb3a5.chunk.js": "./static/js/321.eedfb3a5.chunk.js",
|
||||
"static/js/6763.1da82d5c.chunk.js": "./static/js/6763.1da82d5c.chunk.js",
|
||||
"static/js/3543.24923c9d.chunk.js": "./static/js/3543.24923c9d.chunk.js",
|
||||
"static/js/4061.8bd849a7.chunk.js": "./static/js/4061.8bd849a7.chunk.js",
|
||||
"static/js/2249.39222819.chunk.js": "./static/js/2249.39222819.chunk.js",
|
||||
"static/js/9611.30185102.chunk.js": "./static/js/9611.30185102.chunk.js",
|
||||
"static/js/2637.79b0ea29.chunk.js": "./static/js/2637.79b0ea29.chunk.js",
|
||||
"static/css/380.f0806840.chunk.css": "./static/css/380.f0806840.chunk.css",
|
||||
"static/js/380.1b0b26c2.chunk.js": "./static/js/380.1b0b26c2.chunk.js",
|
||||
"static/js/5926.c044ad6b.chunk.js": "./static/js/5926.c044ad6b.chunk.js",
|
||||
"static/js/701.06a6587d.chunk.js": "./static/js/701.06a6587d.chunk.js",
|
||||
"static/js/7821.f798ffe1.chunk.js": "./static/js/7821.f798ffe1.chunk.js",
|
||||
"static/js/2625.eff40583.chunk.js": "./static/js/2625.eff40583.chunk.js",
|
||||
"static/css/9033.f0806840.chunk.css": "./static/css/9033.f0806840.chunk.css",
|
||||
"static/js/9033.d40f5fa2.chunk.js": "./static/js/9033.d40f5fa2.chunk.js",
|
||||
"static/css/9299.f0806840.chunk.css": "./static/css/9299.f0806840.chunk.css",
|
||||
"static/js/9299.5442941e.chunk.js": "./static/js/9299.5442941e.chunk.js",
|
||||
"static/js/191.92f7d06b.chunk.js": "./static/js/191.92f7d06b.chunk.js",
|
||||
"static/js/7585.2a9cb3d4.chunk.js": "./static/js/7585.2a9cb3d4.chunk.js",
|
||||
"static/js/1836.761ade1e.chunk.js": "./static/js/1836.761ade1e.chunk.js",
|
||||
"static/js/4653.957113df.chunk.js": "./static/js/4653.957113df.chunk.js",
|
||||
"static/js/255.7603092b.chunk.js": "./static/js/255.7603092b.chunk.js",
|
||||
"static/js/4394.2fa16d38.chunk.js": "./static/js/4394.2fa16d38.chunk.js",
|
||||
"static/js/4781.ca99434f.chunk.js": "./static/js/4781.ca99434f.chunk.js",
|
||||
"static/js/9478.c2c2c220.chunk.js": "./static/js/9478.c2c2c220.chunk.js",
|
||||
"static/js/7164.e4aebe46.chunk.js": "./static/js/7164.e4aebe46.chunk.js",
|
||||
"static/js/4414.80189a53.chunk.js": "./static/js/4414.80189a53.chunk.js",
|
||||
"static/js/7798.9bd6994f.chunk.js": "./static/js/7798.9bd6994f.chunk.js",
|
||||
"static/js/8833.d4d792a2.chunk.js": "./static/js/8833.d4d792a2.chunk.js",
|
||||
"static/js/471.3ac500ed.chunk.js": "./static/js/471.3ac500ed.chunk.js",
|
||||
"static/js/483.3fa229ad.chunk.js": "./static/js/483.3fa229ad.chunk.js",
|
||||
"static/js/9467.d4860f23.chunk.js": "./static/js/9467.d4860f23.chunk.js",
|
||||
"static/js/6895.af17fed5.chunk.js": "./static/js/6895.af17fed5.chunk.js",
|
||||
"static/js/6233.589f83fe.chunk.js": "./static/js/6233.589f83fe.chunk.js",
|
||||
"static/js/5588.1a32c1c3.chunk.js": "./static/js/5588.1a32c1c3.chunk.js",
|
||||
"static/js/4874.80bf31e6.chunk.js": "./static/js/4874.80bf31e6.chunk.js",
|
||||
"static/css/1955.f0806840.chunk.css": "./static/css/1955.f0806840.chunk.css",
|
||||
"static/js/1955.95db0000.chunk.js": "./static/js/1955.95db0000.chunk.js",
|
||||
"static/js/2653.d0c6bbf1.chunk.js": "./static/js/2653.d0c6bbf1.chunk.js",
|
||||
"static/js/3956.74bfef51.chunk.js": "./static/js/3956.74bfef51.chunk.js",
|
||||
"static/js/7015.bf4c7dc4.chunk.js": "./static/js/7015.bf4c7dc4.chunk.js",
|
||||
"static/js/7524.c226828c.chunk.js": "./static/js/7524.c226828c.chunk.js",
|
||||
"static/js/8771.b2727bdd.chunk.js": "./static/js/8771.b2727bdd.chunk.js",
|
||||
"static/js/9076.bfebbb14.chunk.js": "./static/js/9076.bfebbb14.chunk.js",
|
||||
"static/js/9221.505f4336.chunk.js": "./static/js/9221.505f4336.chunk.js",
|
||||
"static/js/8896.e9be20fb.chunk.js": "./static/js/8896.e9be20fb.chunk.js",
|
||||
"static/js/7413.a6fe6f9f.chunk.js": "./static/js/7413.a6fe6f9f.chunk.js",
|
||||
"static/js/9134.9336f36c.chunk.js": "./static/js/9134.9336f36c.chunk.js",
|
||||
"static/css/8138.f0806840.chunk.css": "./static/css/8138.f0806840.chunk.css",
|
||||
"static/js/8138.4c6a5b7f.chunk.js": "./static/js/8138.4c6a5b7f.chunk.js",
|
||||
"static/js/8183.8c64a361.chunk.js": "./static/js/8183.8c64a361.chunk.js",
|
||||
"static/js/9145.1af8c238.chunk.js": "./static/js/9145.1af8c238.chunk.js",
|
||||
"static/js/8822.6030f20d.chunk.js": "./static/js/8822.6030f20d.chunk.js",
|
||||
"static/js/7331.106a6938.chunk.js": "./static/js/7331.106a6938.chunk.js",
|
||||
"static/js/9605.e2f1ac95.chunk.js": "./static/js/9605.e2f1ac95.chunk.js",
|
||||
"static/js/426.0124a3b9.chunk.js": "./static/js/426.0124a3b9.chunk.js",
|
||||
"static/js/2878.174d0b14.chunk.js": "./static/js/2878.174d0b14.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.0178dcf1.chunk.js": "./static/js/3518.0178dcf1.chunk.js",
|
||||
"static/js/2684.3e7eb9b1.chunk.js": "./static/js/2684.3e7eb9b1.chunk.js",
|
||||
"static/js/6683.18e77b71.chunk.js": "./static/js/6683.18e77b71.chunk.js",
|
||||
"static/js/8350.501e9b49.chunk.js": "./static/js/8350.501e9b49.chunk.js",
|
||||
"static/js/2676.47150957.chunk.js": "./static/js/2676.47150957.chunk.js",
|
||||
"static/js/9449.035d0f2d.chunk.js": "./static/js/9449.035d0f2d.chunk.js",
|
||||
"static/js/7659.5504cc60.chunk.js": "./static/js/7659.5504cc60.chunk.js",
|
||||
"static/js/9968.f0284b3d.chunk.js": "./static/js/9968.f0284b3d.chunk.js",
|
||||
"static/js/2180.f0842e9e.chunk.js": "./static/js/2180.f0842e9e.chunk.js",
|
||||
"static/js/8253.964026c0.chunk.js": "./static/js/8253.964026c0.chunk.js",
|
||||
"static/js/3328.04821285.chunk.js": "./static/js/3328.04821285.chunk.js",
|
||||
"static/js/1440.146b37eb.chunk.js": "./static/js/1440.146b37eb.chunk.js",
|
||||
"static/js/9002.8057e34f.chunk.js": "./static/js/9002.8057e34f.chunk.js",
|
||||
"static/js/51.76f011ea.chunk.js": "./static/js/51.76f011ea.chunk.js",
|
||||
"static/js/711.121af87a.chunk.js": "./static/js/711.121af87a.chunk.js",
|
||||
"static/js/6901.5bbc1914.chunk.js": "./static/js/6901.5bbc1914.chunk.js",
|
||||
"static/js/3678.568378f8.chunk.js": "./static/js/3678.568378f8.chunk.js",
|
||||
"static/css/3320.f0806840.chunk.css": "./static/css/3320.f0806840.chunk.css",
|
||||
"static/js/3320.b01c2bc8.chunk.js": "./static/js/3320.b01c2bc8.chunk.js",
|
||||
"static/js/312.256db0f7.chunk.js": "./static/js/312.256db0f7.chunk.js",
|
||||
"static/js/2112.6991f0b0.chunk.js": "./static/js/2112.6991f0b0.chunk.js",
|
||||
"static/js/4619.c6ef5989.chunk.js": "./static/js/4619.c6ef5989.chunk.js",
|
||||
"static/js/8990.4fcc1b0f.chunk.js": "./static/js/8990.4fcc1b0f.chunk.js",
|
||||
"static/js/8455.f9b61de1.chunk.js": "./static/js/8455.f9b61de1.chunk.js",
|
||||
"static/css/3631.f0806840.chunk.css": "./static/css/3631.f0806840.chunk.css",
|
||||
"static/js/3631.a3bc3d9b.chunk.js": "./static/js/3631.a3bc3d9b.chunk.js",
|
||||
"static/js/1604.c6070715.chunk.js": "./static/js/1604.c6070715.chunk.js",
|
||||
"static/js/8391.cf78366d.chunk.js": "./static/js/8391.cf78366d.chunk.js",
|
||||
"static/js/402.3ec8985e.chunk.js": "./static/js/402.3ec8985e.chunk.js",
|
||||
"static/js/1705.b90dd0eb.chunk.js": "./static/js/1705.b90dd0eb.chunk.js",
|
||||
"static/js/1581.3e4f9436.chunk.js": "./static/js/1581.3e4f9436.chunk.js",
|
||||
"static/js/455.855a38c2.chunk.js": "./static/js/455.855a38c2.chunk.js",
|
||||
"static/js/2661.ed2f4fc2.chunk.js": "./static/js/2661.ed2f4fc2.chunk.js",
|
||||
"static/js/889.73054a10.chunk.js": "./static/js/889.73054a10.chunk.js",
|
||||
"static/js/9088.2ed52eb5.chunk.js": "./static/js/9088.2ed52eb5.chunk.js",
|
||||
"static/js/247.64d57eaf.chunk.js": "./static/js/247.64d57eaf.chunk.js",
|
||||
"static/js/2763.02f8a4d8.chunk.js": "./static/js/2763.02f8a4d8.chunk.js",
|
||||
"static/js/3772.8f7b248e.chunk.js": "./static/js/3772.8f7b248e.chunk.js",
|
||||
"static/js/5171.2cf876b1.chunk.js": "./static/js/5171.2cf876b1.chunk.js",
|
||||
"static/js/2442.c325186c.chunk.js": "./static/js/2442.c325186c.chunk.js",
|
||||
"static/js/1520.5385d6f6.chunk.js": "./static/js/1520.5385d6f6.chunk.js",
|
||||
"static/js/2426.bc0cfae1.chunk.js": "./static/js/2426.bc0cfae1.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/3801.a06455a2.chunk.js": "./static/js/3801.a06455a2.chunk.js",
|
||||
"static/js/1918.ce3ab2e2.chunk.js": "./static/js/1918.ce3ab2e2.chunk.js",
|
||||
"static/js/6431.5f2e5e6e.chunk.js": "./static/js/6431.5f2e5e6e.chunk.js",
|
||||
"static/js/7757.3650a6cc.chunk.js": "./static/js/7757.3650a6cc.chunk.js",
|
||||
"static/js/6523.f3c7724a.chunk.js": "./static/js/6523.f3c7724a.chunk.js",
|
||||
"static/js/8760.e06a6adc.chunk.js": "./static/js/8760.e06a6adc.chunk.js",
|
||||
"static/js/5315.f76aa5f9.chunk.js": "./static/js/5315.f76aa5f9.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/8354.e837d480.chunk.js": "./static/js/8354.e837d480.chunk.js",
|
||||
"static/js/9437.1a158c7b.chunk.js": "./static/js/9437.1a158c7b.chunk.js",
|
||||
"static/js/6172.098bf62e.chunk.js": "./static/js/6172.098bf62e.chunk.js",
|
||||
"static/js/3909.cdbddaab.chunk.js": "./static/js/3909.cdbddaab.chunk.js",
|
||||
"static/js/7315.f1bb4245.chunk.js": "./static/js/7315.f1bb4245.chunk.js",
|
||||
"static/js/5317.c7a235b3.chunk.js": "./static/js/5317.c7a235b3.chunk.js",
|
||||
"static/js/2723.c7e2034f.chunk.js": "./static/js/2723.c7e2034f.chunk.js",
|
||||
"static/js/2076.e7bf07b8.chunk.js": "./static/js/2076.e7bf07b8.chunk.js",
|
||||
"static/js/1326.19aa2326.chunk.js": "./static/js/1326.19aa2326.chunk.js",
|
||||
"static/js/7142.957288ed.chunk.js": "./static/js/7142.957288ed.chunk.js",
|
||||
"static/js/7931.9fe0101a.chunk.js": "./static/js/7931.9fe0101a.chunk.js",
|
||||
"static/js/9362.63d03757.chunk.js": "./static/js/9362.63d03757.chunk.js",
|
||||
"static/js/2879.69834509.chunk.js": "./static/js/2879.69834509.chunk.js",
|
||||
"static/js/8735.52726eac.chunk.js": "./static/js/8735.52726eac.chunk.js",
|
||||
"static/js/8915.be25a5c1.chunk.js": "./static/js/8915.be25a5c1.chunk.js",
|
||||
"static/js/3096.63d4ac67.chunk.js": "./static/js/3096.63d4ac67.chunk.js",
|
||||
"static/js/2983.26ce456f.chunk.js": "./static/js/2983.26ce456f.chunk.js",
|
||||
"static/js/770.c5b57a95.chunk.js": "./static/js/770.c5b57a95.chunk.js",
|
||||
"static/js/5662.0998d919.chunk.js": "./static/js/5662.0998d919.chunk.js",
|
||||
"static/js/5165.0fcf4d2d.chunk.js": "./static/js/5165.0fcf4d2d.chunk.js",
|
||||
"static/js/6496.0cee9f03.chunk.js": "./static/js/6496.0cee9f03.chunk.js",
|
||||
"static/js/1687.72fad20d.chunk.js": "./static/js/1687.72fad20d.chunk.js",
|
||||
"index.html": "./index.html",
|
||||
"main.90d417ae.css.map": "./static/css/main.90d417ae.css.map",
|
||||
"main.69273a1d.js.map": "./static/js/main.69273a1d.js.map",
|
||||
"1660.1a3b5397.chunk.js.map": "./static/js/1660.1a3b5397.chunk.js.map",
|
||||
"5282.cb13b8c4.chunk.js.map": "./static/js/5282.cb13b8c4.chunk.js.map",
|
||||
"2818.a52e5730.chunk.js.map": "./static/js/2818.a52e5730.chunk.js.map",
|
||||
"9560.6e9b7779.chunk.js.map": "./static/js/9560.6e9b7779.chunk.js.map",
|
||||
"9661.92a4e63a.chunk.js.map": "./static/js/9661.92a4e63a.chunk.js.map",
|
||||
"9330.122bf1a7.chunk.js.map": "./static/js/9330.122bf1a7.chunk.js.map",
|
||||
"7436.fed787a2.chunk.js.map": "./static/js/7436.fed787a2.chunk.js.map",
|
||||
"8428.f4d88368.chunk.js.map": "./static/js/8428.f4d88368.chunk.js.map",
|
||||
"9779.fed48861.chunk.js.map": "./static/js/9779.fed48861.chunk.js.map",
|
||||
"3617.b62a9bb2.chunk.js.map": "./static/js/3617.b62a9bb2.chunk.js.map",
|
||||
"7274.9c913af6.chunk.js.map": "./static/js/7274.9c913af6.chunk.js.map",
|
||||
"7842.8dfd596a.chunk.js.map": "./static/js/7842.8dfd596a.chunk.js.map",
|
||||
"4745.27ab197f.chunk.js.map": "./static/js/4745.27ab197f.chunk.js.map",
|
||||
"1796.26462172.chunk.js.map": "./static/js/1796.26462172.chunk.js.map",
|
||||
"8259.3b2561ab.chunk.js.map": "./static/js/8259.3b2561ab.chunk.js.map",
|
||||
"6023.aec2d9d1.chunk.js.map": "./static/js/6023.aec2d9d1.chunk.js.map",
|
||||
"6147.f2a7d841.chunk.js.map": "./static/js/6147.f2a7d841.chunk.js.map",
|
||||
"9275.6a834668.chunk.js.map": "./static/js/9275.6a834668.chunk.js.map",
|
||||
"8190.d56fddaa.chunk.js.map": "./static/js/8190.d56fddaa.chunk.js.map",
|
||||
"7314.0058a98f.chunk.js.map": "./static/js/7314.0058a98f.chunk.js.map",
|
||||
"7456.e2ad891d.chunk.js.map": "./static/js/7456.e2ad891d.chunk.js.map",
|
||||
"5822.dd80c1b6.chunk.css.map": "./static/css/5822.dd80c1b6.chunk.css.map",
|
||||
"5822.c1d62c79.chunk.js.map": "./static/js/5822.c1d62c79.chunk.js.map",
|
||||
"2699.3102be0f.chunk.js.map": "./static/js/2699.3102be0f.chunk.js.map",
|
||||
"5808.8da21793.chunk.js.map": "./static/js/5808.8da21793.chunk.js.map",
|
||||
"1237.b46ec019.chunk.js.map": "./static/js/1237.b46ec019.chunk.js.map",
|
||||
"189.06df2d49.chunk.js.map": "./static/js/189.06df2d49.chunk.js.map",
|
||||
"964.dd80c1b6.chunk.css.map": "./static/css/964.dd80c1b6.chunk.css.map",
|
||||
"964.c1751e75.chunk.js.map": "./static/js/964.c1751e75.chunk.js.map",
|
||||
"9807.dd80c1b6.chunk.css.map": "./static/css/9807.dd80c1b6.chunk.css.map",
|
||||
"9807.731eb17a.chunk.js.map": "./static/js/9807.731eb17a.chunk.js.map",
|
||||
"3806.b5b2c03c.chunk.js.map": "./static/js/3806.b5b2c03c.chunk.js.map",
|
||||
"8661.ade9e15c.chunk.js.map": "./static/js/8661.ade9e15c.chunk.js.map",
|
||||
"2886.a03a185d.chunk.js.map": "./static/js/2886.a03a185d.chunk.js.map",
|
||||
"4577.cd5b16fc.chunk.js.map": "./static/js/4577.cd5b16fc.chunk.js.map",
|
||||
"4298.e6c437dd.chunk.js.map": "./static/js/4298.e6c437dd.chunk.js.map",
|
||||
"2805.b4302353.chunk.js.map": "./static/js/2805.b4302353.chunk.js.map",
|
||||
"6873.27fbf284.chunk.js.map": "./static/js/6873.27fbf284.chunk.js.map",
|
||||
"428.ad58c353.chunk.js.map": "./static/js/428.ad58c353.chunk.js.map",
|
||||
"1069.77bb316e.chunk.js.map": "./static/js/1069.77bb316e.chunk.js.map",
|
||||
"9080.884725e7.chunk.js.map": "./static/js/9080.884725e7.chunk.js.map",
|
||||
"3276.1afa9e35.chunk.js.map": "./static/js/3276.1afa9e35.chunk.js.map",
|
||||
"6458.c6bf60f8.chunk.js.map": "./static/js/6458.c6bf60f8.chunk.js.map",
|
||||
"7551.b8d5fd21.chunk.js.map": "./static/js/7551.b8d5fd21.chunk.js.map",
|
||||
"7950.1793a548.chunk.js.map": "./static/js/7950.1793a548.chunk.js.map",
|
||||
"290.3a78b888.chunk.js.map": "./static/js/290.3a78b888.chunk.js.map",
|
||||
"8961.c7471e8d.chunk.js.map": "./static/js/8961.c7471e8d.chunk.js.map",
|
||||
"3967.eefb50e4.chunk.js.map": "./static/js/3967.eefb50e4.chunk.js.map",
|
||||
"4084.dd80c1b6.chunk.css.map": "./static/css/4084.dd80c1b6.chunk.css.map",
|
||||
"4084.57e7784d.chunk.js.map": "./static/js/4084.57e7784d.chunk.js.map",
|
||||
"8394.fa043a82.chunk.js.map": "./static/js/8394.fa043a82.chunk.js.map",
|
||||
"7664.b099b462.chunk.js.map": "./static/js/7664.b099b462.chunk.js.map",
|
||||
"1140.044ef809.chunk.js.map": "./static/js/1140.044ef809.chunk.js.map",
|
||||
"5961.7a71f2c5.chunk.js.map": "./static/js/5961.7a71f2c5.chunk.js.map",
|
||||
"2401.dcfa0659.chunk.js.map": "./static/js/2401.dcfa0659.chunk.js.map",
|
||||
"7498.adcacaca.chunk.js.map": "./static/js/7498.adcacaca.chunk.js.map",
|
||||
"9421.a6974f61.chunk.js.map": "./static/js/9421.a6974f61.chunk.js.map",
|
||||
"4860.3bea7736.chunk.js.map": "./static/js/4860.3bea7736.chunk.js.map",
|
||||
"5245.04e84402.chunk.js.map": "./static/js/5245.04e84402.chunk.js.map",
|
||||
"6549.bc76401b.chunk.js.map": "./static/js/6549.bc76401b.chunk.js.map",
|
||||
"8724.dd80c1b6.chunk.css.map": "./static/css/8724.dd80c1b6.chunk.css.map",
|
||||
"8724.2fda7628.chunk.js.map": "./static/js/8724.2fda7628.chunk.js.map",
|
||||
"2182.e1389a8d.chunk.js.map": "./static/js/2182.e1389a8d.chunk.js.map",
|
||||
"7764.7133a78a.chunk.js.map": "./static/js/7764.7133a78a.chunk.js.map",
|
||||
"4220.8d9a9028.chunk.js.map": "./static/js/4220.8d9a9028.chunk.js.map",
|
||||
"1719.a1c5fbc9.chunk.js.map": "./static/js/1719.a1c5fbc9.chunk.js.map",
|
||||
"3320.cf0913be.chunk.js.map": "./static/js/3320.cf0913be.chunk.js.map",
|
||||
"6645.1d65ce48.chunk.js.map": "./static/js/6645.1d65ce48.chunk.js.map",
|
||||
"9923.3911a310.chunk.js.map": "./static/js/9923.3911a310.chunk.js.map",
|
||||
"9586.f3d3466d.chunk.js.map": "./static/js/9586.f3d3466d.chunk.js.map",
|
||||
"9125.a86e3119.chunk.js.map": "./static/js/9125.a86e3119.chunk.js.map",
|
||||
"5781.33738b7f.chunk.js.map": "./static/js/5781.33738b7f.chunk.js.map",
|
||||
"7261.916fdbf6.chunk.js.map": "./static/js/7261.916fdbf6.chunk.js.map",
|
||||
"8306.047e9e54.chunk.js.map": "./static/js/8306.047e9e54.chunk.js.map",
|
||||
"6436.690eb2b9.chunk.js.map": "./static/js/6436.690eb2b9.chunk.js.map",
|
||||
"8343.67a940b1.chunk.js.map": "./static/js/8343.67a940b1.chunk.js.map",
|
||||
"2841.9d475dfe.chunk.js.map": "./static/js/2841.9d475dfe.chunk.js.map",
|
||||
"6167.d5f52864.chunk.js.map": "./static/js/6167.d5f52864.chunk.js.map",
|
||||
"7346.47702cc8.chunk.js.map": "./static/js/7346.47702cc8.chunk.js.map",
|
||||
"5144.19c094a4.chunk.js.map": "./static/js/5144.19c094a4.chunk.js.map",
|
||||
"5125.58c2feff.chunk.js.map": "./static/js/5125.58c2feff.chunk.js.map",
|
||||
"528.d01b02af.chunk.js.map": "./static/js/528.d01b02af.chunk.js.map",
|
||||
"7187.171b28f4.chunk.js.map": "./static/js/7187.171b28f4.chunk.js.map",
|
||||
"6173.925ab9b7.chunk.js.map": "./static/js/6173.925ab9b7.chunk.js.map",
|
||||
"953.677ddb95.chunk.js.map": "./static/js/953.677ddb95.chunk.js.map",
|
||||
"9193.feaac1ba.chunk.js.map": "./static/js/9193.feaac1ba.chunk.js.map",
|
||||
"7451.dabaf18f.chunk.js.map": "./static/js/7451.dabaf18f.chunk.js.map",
|
||||
"9924.020057ee.chunk.js.map": "./static/js/9924.020057ee.chunk.js.map",
|
||||
"9645.dd80c1b6.chunk.css.map": "./static/css/9645.dd80c1b6.chunk.css.map",
|
||||
"9645.71cc858a.chunk.js.map": "./static/js/9645.71cc858a.chunk.js.map",
|
||||
"5710.7386de50.chunk.js.map": "./static/js/5710.7386de50.chunk.js.map",
|
||||
"4121.0e3d5ae5.chunk.js.map": "./static/js/4121.0e3d5ae5.chunk.js.map",
|
||||
"3421.666af5cb.chunk.js.map": "./static/js/3421.666af5cb.chunk.js.map",
|
||||
"2892.f87668de.chunk.js.map": "./static/js/2892.f87668de.chunk.js.map",
|
||||
"7926.c65ecfc3.chunk.js.map": "./static/js/7926.c65ecfc3.chunk.js.map",
|
||||
"6145.9665a7b2.chunk.js.map": "./static/js/6145.9665a7b2.chunk.js.map",
|
||||
"3816.dd80c1b6.chunk.css.map": "./static/css/3816.dd80c1b6.chunk.css.map",
|
||||
"3816.c0b2fb6b.chunk.js.map": "./static/js/3816.c0b2fb6b.chunk.js.map",
|
||||
"2966.0b278e3b.chunk.js.map": "./static/js/2966.0b278e3b.chunk.js.map",
|
||||
"4177.381caad6.chunk.js.map": "./static/js/4177.381caad6.chunk.js.map",
|
||||
"9679.c1fd0ae5.chunk.js.map": "./static/js/9679.c1fd0ae5.chunk.js.map",
|
||||
"8333.d2ede110.chunk.js.map": "./static/js/8333.d2ede110.chunk.js.map",
|
||||
"1711.dfdfce0a.chunk.js.map": "./static/js/1711.dfdfce0a.chunk.js.map",
|
||||
"9.caa73b0e.chunk.js.map": "./static/js/9.caa73b0e.chunk.js.map",
|
||||
"4487.8cae9359.chunk.js.map": "./static/js/4487.8cae9359.chunk.js.map",
|
||||
"6866.a519feef.chunk.js.map": "./static/js/6866.a519feef.chunk.js.map",
|
||||
"8564.16b674dd.chunk.js.map": "./static/js/8564.16b674dd.chunk.js.map",
|
||||
"1666.9098f0d4.chunk.js.map": "./static/js/1666.9098f0d4.chunk.js.map",
|
||||
"7007.d9ef3b97.chunk.js.map": "./static/js/7007.d9ef3b97.chunk.js.map",
|
||||
"14.25ecb28d.chunk.js.map": "./static/js/14.25ecb28d.chunk.js.map",
|
||||
"3152.d03e4df4.chunk.js.map": "./static/js/3152.d03e4df4.chunk.js.map",
|
||||
"2066.16320a68.chunk.js.map": "./static/js/2066.16320a68.chunk.js.map",
|
||||
"5444.e8727da9.chunk.js.map": "./static/js/5444.e8727da9.chunk.js.map",
|
||||
"3690.536fb187.chunk.js.map": "./static/js/3690.536fb187.chunk.js.map",
|
||||
"875.130c3ed4.chunk.js.map": "./static/js/875.130c3ed4.chunk.js.map",
|
||||
"5399.6bc650ac.chunk.js.map": "./static/js/5399.6bc650ac.chunk.js.map",
|
||||
"606.28fdb5bc.chunk.js.map": "./static/js/606.28fdb5bc.chunk.js.map",
|
||||
"9769.a2bfb4d7.chunk.js.map": "./static/js/9769.a2bfb4d7.chunk.js.map",
|
||||
"6117.0fcd3d09.chunk.js.map": "./static/js/6117.0fcd3d09.chunk.js.map",
|
||||
"8954.00599ff1.chunk.js.map": "./static/js/8954.00599ff1.chunk.js.map",
|
||||
"2309.49be65c5.chunk.js.map": "./static/js/2309.49be65c5.chunk.js.map",
|
||||
"7248.1e0c4e19.chunk.js.map": "./static/js/7248.1e0c4e19.chunk.js.map",
|
||||
"3360.453f0701.chunk.js.map": "./static/js/3360.453f0701.chunk.js.map",
|
||||
"4322.ddc888e0.chunk.js.map": "./static/js/4322.ddc888e0.chunk.js.map",
|
||||
"9056.41f0e489.chunk.js.map": "./static/js/9056.41f0e489.chunk.js.map",
|
||||
"4837.98af4cfe.chunk.js.map": "./static/js/4837.98af4cfe.chunk.js.map",
|
||||
"3356.05b42758.chunk.js.map": "./static/js/3356.05b42758.chunk.js.map",
|
||||
"3020.3b2e782c.chunk.js.map": "./static/js/3020.3b2e782c.chunk.js.map",
|
||||
"2320.ad204ae5.chunk.js.map": "./static/js/2320.ad204ae5.chunk.js.map",
|
||||
"195.58f4f3fe.chunk.js.map": "./static/js/195.58f4f3fe.chunk.js.map",
|
||||
"8420.ac8efcdd.chunk.js.map": "./static/js/8420.ac8efcdd.chunk.js.map",
|
||||
"728.92b72106.chunk.js.map": "./static/js/728.92b72106.chunk.js.map",
|
||||
"187.c9da1b03.chunk.js.map": "./static/js/187.c9da1b03.chunk.js.map",
|
||||
"849.1c67c5fb.chunk.js.map": "./static/js/849.1c67c5fb.chunk.js.map",
|
||||
"7869.d312e0cb.chunk.js.map": "./static/js/7869.d312e0cb.chunk.js.map",
|
||||
"7939.d60313ae.chunk.js.map": "./static/js/7939.d60313ae.chunk.js.map",
|
||||
"3538.60e98cef.chunk.js.map": "./static/js/3538.60e98cef.chunk.js.map",
|
||||
"5676.7a115ec7.chunk.js.map": "./static/js/5676.7a115ec7.chunk.js.map",
|
||||
"1757.5d1b8ae4.chunk.js.map": "./static/js/1757.5d1b8ae4.chunk.js.map",
|
||||
"7663.e9d514d1.chunk.js.map": "./static/js/7663.e9d514d1.chunk.js.map",
|
||||
"3383.ab285f5a.chunk.js.map": "./static/js/3383.ab285f5a.chunk.js.map",
|
||||
"3045.cfe6cbf4.chunk.js.map": "./static/js/3045.cfe6cbf4.chunk.js.map",
|
||||
"6554.53f930ae.chunk.js.map": "./static/js/6554.53f930ae.chunk.js.map",
|
||||
"9831.1b5a6bb6.chunk.js.map": "./static/js/9831.1b5a6bb6.chunk.js.map",
|
||||
"9382.581734f3.chunk.js.map": "./static/js/9382.581734f3.chunk.js.map",
|
||||
"8174.6e95ea0c.chunk.js.map": "./static/js/8174.6e95ea0c.chunk.js.map",
|
||||
"1116.6c0eed8e.chunk.js.map": "./static/js/1116.6c0eed8e.chunk.js.map",
|
||||
"6430.e747de7c.chunk.js.map": "./static/js/6430.e747de7c.chunk.js.map",
|
||||
"4966.c825dc1c.chunk.js.map": "./static/js/4966.c825dc1c.chunk.js.map",
|
||||
"2363.5fc6aebe.chunk.js.map": "./static/js/2363.5fc6aebe.chunk.js.map",
|
||||
"2464.5dc72a90.chunk.js.map": "./static/js/2464.5dc72a90.chunk.js.map",
|
||||
"7520.087167a1.chunk.js.map": "./static/js/7520.087167a1.chunk.js.map"
|
||||
"main.5a7c25ee.js.map": "./static/js/main.5a7c25ee.js.map",
|
||||
"2483.511e6a32.chunk.js.map": "./static/js/2483.511e6a32.chunk.js.map",
|
||||
"6914.e9919921.chunk.js.map": "./static/js/6914.e9919921.chunk.js.map",
|
||||
"4209.7c3855ef.chunk.js.map": "./static/js/4209.7c3855ef.chunk.js.map",
|
||||
"1829.202650e3.chunk.js.map": "./static/js/1829.202650e3.chunk.js.map",
|
||||
"6041.a11c2e9a.chunk.js.map": "./static/js/6041.a11c2e9a.chunk.js.map",
|
||||
"5088.921b2534.chunk.js.map": "./static/js/5088.921b2534.chunk.js.map",
|
||||
"5140.8f5521e6.chunk.js.map": "./static/js/5140.8f5521e6.chunk.js.map",
|
||||
"1434.2cbee404.chunk.js.map": "./static/js/1434.2cbee404.chunk.js.map",
|
||||
"3176.640e537b.chunk.js.map": "./static/js/3176.640e537b.chunk.js.map",
|
||||
"6137.ac2c3fb7.chunk.js.map": "./static/js/6137.ac2c3fb7.chunk.js.map",
|
||||
"7045.e30cf01e.chunk.js.map": "./static/js/7045.e30cf01e.chunk.js.map",
|
||||
"9635.083b4e05.chunk.js.map": "./static/js/9635.083b4e05.chunk.js.map",
|
||||
"2338.8b9b592f.chunk.js.map": "./static/js/2338.8b9b592f.chunk.js.map",
|
||||
"4335.71899795.chunk.js.map": "./static/js/4335.71899795.chunk.js.map",
|
||||
"321.eedfb3a5.chunk.js.map": "./static/js/321.eedfb3a5.chunk.js.map",
|
||||
"6763.1da82d5c.chunk.js.map": "./static/js/6763.1da82d5c.chunk.js.map",
|
||||
"3543.24923c9d.chunk.js.map": "./static/js/3543.24923c9d.chunk.js.map",
|
||||
"4061.8bd849a7.chunk.js.map": "./static/js/4061.8bd849a7.chunk.js.map",
|
||||
"2249.39222819.chunk.js.map": "./static/js/2249.39222819.chunk.js.map",
|
||||
"9611.30185102.chunk.js.map": "./static/js/9611.30185102.chunk.js.map",
|
||||
"2637.79b0ea29.chunk.js.map": "./static/js/2637.79b0ea29.chunk.js.map",
|
||||
"380.f0806840.chunk.css.map": "./static/css/380.f0806840.chunk.css.map",
|
||||
"380.1b0b26c2.chunk.js.map": "./static/js/380.1b0b26c2.chunk.js.map",
|
||||
"5926.c044ad6b.chunk.js.map": "./static/js/5926.c044ad6b.chunk.js.map",
|
||||
"701.06a6587d.chunk.js.map": "./static/js/701.06a6587d.chunk.js.map",
|
||||
"7821.f798ffe1.chunk.js.map": "./static/js/7821.f798ffe1.chunk.js.map",
|
||||
"2625.eff40583.chunk.js.map": "./static/js/2625.eff40583.chunk.js.map",
|
||||
"9033.f0806840.chunk.css.map": "./static/css/9033.f0806840.chunk.css.map",
|
||||
"9033.d40f5fa2.chunk.js.map": "./static/js/9033.d40f5fa2.chunk.js.map",
|
||||
"9299.f0806840.chunk.css.map": "./static/css/9299.f0806840.chunk.css.map",
|
||||
"9299.5442941e.chunk.js.map": "./static/js/9299.5442941e.chunk.js.map",
|
||||
"191.92f7d06b.chunk.js.map": "./static/js/191.92f7d06b.chunk.js.map",
|
||||
"7585.2a9cb3d4.chunk.js.map": "./static/js/7585.2a9cb3d4.chunk.js.map",
|
||||
"1836.761ade1e.chunk.js.map": "./static/js/1836.761ade1e.chunk.js.map",
|
||||
"4653.957113df.chunk.js.map": "./static/js/4653.957113df.chunk.js.map",
|
||||
"255.7603092b.chunk.js.map": "./static/js/255.7603092b.chunk.js.map",
|
||||
"4394.2fa16d38.chunk.js.map": "./static/js/4394.2fa16d38.chunk.js.map",
|
||||
"4781.ca99434f.chunk.js.map": "./static/js/4781.ca99434f.chunk.js.map",
|
||||
"9478.c2c2c220.chunk.js.map": "./static/js/9478.c2c2c220.chunk.js.map",
|
||||
"7164.e4aebe46.chunk.js.map": "./static/js/7164.e4aebe46.chunk.js.map",
|
||||
"4414.80189a53.chunk.js.map": "./static/js/4414.80189a53.chunk.js.map",
|
||||
"7798.9bd6994f.chunk.js.map": "./static/js/7798.9bd6994f.chunk.js.map",
|
||||
"8833.d4d792a2.chunk.js.map": "./static/js/8833.d4d792a2.chunk.js.map",
|
||||
"471.3ac500ed.chunk.js.map": "./static/js/471.3ac500ed.chunk.js.map",
|
||||
"483.3fa229ad.chunk.js.map": "./static/js/483.3fa229ad.chunk.js.map",
|
||||
"9467.d4860f23.chunk.js.map": "./static/js/9467.d4860f23.chunk.js.map",
|
||||
"6895.af17fed5.chunk.js.map": "./static/js/6895.af17fed5.chunk.js.map",
|
||||
"6233.589f83fe.chunk.js.map": "./static/js/6233.589f83fe.chunk.js.map",
|
||||
"5588.1a32c1c3.chunk.js.map": "./static/js/5588.1a32c1c3.chunk.js.map",
|
||||
"4874.80bf31e6.chunk.js.map": "./static/js/4874.80bf31e6.chunk.js.map",
|
||||
"1955.f0806840.chunk.css.map": "./static/css/1955.f0806840.chunk.css.map",
|
||||
"1955.95db0000.chunk.js.map": "./static/js/1955.95db0000.chunk.js.map",
|
||||
"2653.d0c6bbf1.chunk.js.map": "./static/js/2653.d0c6bbf1.chunk.js.map",
|
||||
"3956.74bfef51.chunk.js.map": "./static/js/3956.74bfef51.chunk.js.map",
|
||||
"7015.bf4c7dc4.chunk.js.map": "./static/js/7015.bf4c7dc4.chunk.js.map",
|
||||
"7524.c226828c.chunk.js.map": "./static/js/7524.c226828c.chunk.js.map",
|
||||
"8771.b2727bdd.chunk.js.map": "./static/js/8771.b2727bdd.chunk.js.map",
|
||||
"9076.bfebbb14.chunk.js.map": "./static/js/9076.bfebbb14.chunk.js.map",
|
||||
"9221.505f4336.chunk.js.map": "./static/js/9221.505f4336.chunk.js.map",
|
||||
"8896.e9be20fb.chunk.js.map": "./static/js/8896.e9be20fb.chunk.js.map",
|
||||
"7413.a6fe6f9f.chunk.js.map": "./static/js/7413.a6fe6f9f.chunk.js.map",
|
||||
"9134.9336f36c.chunk.js.map": "./static/js/9134.9336f36c.chunk.js.map",
|
||||
"8138.f0806840.chunk.css.map": "./static/css/8138.f0806840.chunk.css.map",
|
||||
"8138.4c6a5b7f.chunk.js.map": "./static/js/8138.4c6a5b7f.chunk.js.map",
|
||||
"8183.8c64a361.chunk.js.map": "./static/js/8183.8c64a361.chunk.js.map",
|
||||
"9145.1af8c238.chunk.js.map": "./static/js/9145.1af8c238.chunk.js.map",
|
||||
"8822.6030f20d.chunk.js.map": "./static/js/8822.6030f20d.chunk.js.map",
|
||||
"7331.106a6938.chunk.js.map": "./static/js/7331.106a6938.chunk.js.map",
|
||||
"9605.e2f1ac95.chunk.js.map": "./static/js/9605.e2f1ac95.chunk.js.map",
|
||||
"426.0124a3b9.chunk.js.map": "./static/js/426.0124a3b9.chunk.js.map",
|
||||
"2878.174d0b14.chunk.js.map": "./static/js/2878.174d0b14.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.0178dcf1.chunk.js.map": "./static/js/3518.0178dcf1.chunk.js.map",
|
||||
"2684.3e7eb9b1.chunk.js.map": "./static/js/2684.3e7eb9b1.chunk.js.map",
|
||||
"6683.18e77b71.chunk.js.map": "./static/js/6683.18e77b71.chunk.js.map",
|
||||
"8350.501e9b49.chunk.js.map": "./static/js/8350.501e9b49.chunk.js.map",
|
||||
"2676.47150957.chunk.js.map": "./static/js/2676.47150957.chunk.js.map",
|
||||
"9449.035d0f2d.chunk.js.map": "./static/js/9449.035d0f2d.chunk.js.map",
|
||||
"7659.5504cc60.chunk.js.map": "./static/js/7659.5504cc60.chunk.js.map",
|
||||
"9968.f0284b3d.chunk.js.map": "./static/js/9968.f0284b3d.chunk.js.map",
|
||||
"2180.f0842e9e.chunk.js.map": "./static/js/2180.f0842e9e.chunk.js.map",
|
||||
"8253.964026c0.chunk.js.map": "./static/js/8253.964026c0.chunk.js.map",
|
||||
"3328.04821285.chunk.js.map": "./static/js/3328.04821285.chunk.js.map",
|
||||
"1440.146b37eb.chunk.js.map": "./static/js/1440.146b37eb.chunk.js.map",
|
||||
"9002.8057e34f.chunk.js.map": "./static/js/9002.8057e34f.chunk.js.map",
|
||||
"51.76f011ea.chunk.js.map": "./static/js/51.76f011ea.chunk.js.map",
|
||||
"711.121af87a.chunk.js.map": "./static/js/711.121af87a.chunk.js.map",
|
||||
"6901.5bbc1914.chunk.js.map": "./static/js/6901.5bbc1914.chunk.js.map",
|
||||
"3678.568378f8.chunk.js.map": "./static/js/3678.568378f8.chunk.js.map",
|
||||
"3320.f0806840.chunk.css.map": "./static/css/3320.f0806840.chunk.css.map",
|
||||
"3320.b01c2bc8.chunk.js.map": "./static/js/3320.b01c2bc8.chunk.js.map",
|
||||
"312.256db0f7.chunk.js.map": "./static/js/312.256db0f7.chunk.js.map",
|
||||
"2112.6991f0b0.chunk.js.map": "./static/js/2112.6991f0b0.chunk.js.map",
|
||||
"4619.c6ef5989.chunk.js.map": "./static/js/4619.c6ef5989.chunk.js.map",
|
||||
"8990.4fcc1b0f.chunk.js.map": "./static/js/8990.4fcc1b0f.chunk.js.map",
|
||||
"8455.f9b61de1.chunk.js.map": "./static/js/8455.f9b61de1.chunk.js.map",
|
||||
"3631.f0806840.chunk.css.map": "./static/css/3631.f0806840.chunk.css.map",
|
||||
"3631.a3bc3d9b.chunk.js.map": "./static/js/3631.a3bc3d9b.chunk.js.map",
|
||||
"1604.c6070715.chunk.js.map": "./static/js/1604.c6070715.chunk.js.map",
|
||||
"8391.cf78366d.chunk.js.map": "./static/js/8391.cf78366d.chunk.js.map",
|
||||
"402.3ec8985e.chunk.js.map": "./static/js/402.3ec8985e.chunk.js.map",
|
||||
"1705.b90dd0eb.chunk.js.map": "./static/js/1705.b90dd0eb.chunk.js.map",
|
||||
"1581.3e4f9436.chunk.js.map": "./static/js/1581.3e4f9436.chunk.js.map",
|
||||
"455.855a38c2.chunk.js.map": "./static/js/455.855a38c2.chunk.js.map",
|
||||
"2661.ed2f4fc2.chunk.js.map": "./static/js/2661.ed2f4fc2.chunk.js.map",
|
||||
"889.73054a10.chunk.js.map": "./static/js/889.73054a10.chunk.js.map",
|
||||
"9088.2ed52eb5.chunk.js.map": "./static/js/9088.2ed52eb5.chunk.js.map",
|
||||
"247.64d57eaf.chunk.js.map": "./static/js/247.64d57eaf.chunk.js.map",
|
||||
"2763.02f8a4d8.chunk.js.map": "./static/js/2763.02f8a4d8.chunk.js.map",
|
||||
"3772.8f7b248e.chunk.js.map": "./static/js/3772.8f7b248e.chunk.js.map",
|
||||
"5171.2cf876b1.chunk.js.map": "./static/js/5171.2cf876b1.chunk.js.map",
|
||||
"2442.c325186c.chunk.js.map": "./static/js/2442.c325186c.chunk.js.map",
|
||||
"1520.5385d6f6.chunk.js.map": "./static/js/1520.5385d6f6.chunk.js.map",
|
||||
"2426.bc0cfae1.chunk.js.map": "./static/js/2426.bc0cfae1.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",
|
||||
"3801.a06455a2.chunk.js.map": "./static/js/3801.a06455a2.chunk.js.map",
|
||||
"1918.ce3ab2e2.chunk.js.map": "./static/js/1918.ce3ab2e2.chunk.js.map",
|
||||
"6431.5f2e5e6e.chunk.js.map": "./static/js/6431.5f2e5e6e.chunk.js.map",
|
||||
"7757.3650a6cc.chunk.js.map": "./static/js/7757.3650a6cc.chunk.js.map",
|
||||
"6523.f3c7724a.chunk.js.map": "./static/js/6523.f3c7724a.chunk.js.map",
|
||||
"8760.e06a6adc.chunk.js.map": "./static/js/8760.e06a6adc.chunk.js.map",
|
||||
"5315.f76aa5f9.chunk.js.map": "./static/js/5315.f76aa5f9.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",
|
||||
"8354.e837d480.chunk.js.map": "./static/js/8354.e837d480.chunk.js.map",
|
||||
"9437.1a158c7b.chunk.js.map": "./static/js/9437.1a158c7b.chunk.js.map",
|
||||
"6172.098bf62e.chunk.js.map": "./static/js/6172.098bf62e.chunk.js.map",
|
||||
"3909.cdbddaab.chunk.js.map": "./static/js/3909.cdbddaab.chunk.js.map",
|
||||
"7315.f1bb4245.chunk.js.map": "./static/js/7315.f1bb4245.chunk.js.map",
|
||||
"5317.c7a235b3.chunk.js.map": "./static/js/5317.c7a235b3.chunk.js.map",
|
||||
"2723.c7e2034f.chunk.js.map": "./static/js/2723.c7e2034f.chunk.js.map",
|
||||
"2076.e7bf07b8.chunk.js.map": "./static/js/2076.e7bf07b8.chunk.js.map",
|
||||
"1326.19aa2326.chunk.js.map": "./static/js/1326.19aa2326.chunk.js.map",
|
||||
"7142.957288ed.chunk.js.map": "./static/js/7142.957288ed.chunk.js.map",
|
||||
"7931.9fe0101a.chunk.js.map": "./static/js/7931.9fe0101a.chunk.js.map",
|
||||
"9362.63d03757.chunk.js.map": "./static/js/9362.63d03757.chunk.js.map",
|
||||
"2879.69834509.chunk.js.map": "./static/js/2879.69834509.chunk.js.map",
|
||||
"8735.52726eac.chunk.js.map": "./static/js/8735.52726eac.chunk.js.map",
|
||||
"8915.be25a5c1.chunk.js.map": "./static/js/8915.be25a5c1.chunk.js.map",
|
||||
"3096.63d4ac67.chunk.js.map": "./static/js/3096.63d4ac67.chunk.js.map",
|
||||
"2983.26ce456f.chunk.js.map": "./static/js/2983.26ce456f.chunk.js.map",
|
||||
"770.c5b57a95.chunk.js.map": "./static/js/770.c5b57a95.chunk.js.map",
|
||||
"5662.0998d919.chunk.js.map": "./static/js/5662.0998d919.chunk.js.map",
|
||||
"5165.0fcf4d2d.chunk.js.map": "./static/js/5165.0fcf4d2d.chunk.js.map",
|
||||
"6496.0cee9f03.chunk.js.map": "./static/js/6496.0cee9f03.chunk.js.map",
|
||||
"1687.72fad20d.chunk.js.map": "./static/js/1687.72fad20d.chunk.js.map"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/css/main.90d417ae.css",
|
||||
"static/js/main.69273a1d.js"
|
||||
"static/js/main.5a7c25ee.js"
|
||||
]
|
||||
}
|
||||
@@ -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.69273a1d.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.5a7c25ee.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>
|
||||
@@ -1,2 +1,2 @@
|
||||
.cm-s-dracula.CodeMirror,.cm-s-dracula .CodeMirror-gutters{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=4084.dd80c1b6.chunk.css.map*/
|
||||
.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.f0806840.chunk.css.map*/
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"static/css/4084.dd80c1b6.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/1955.f0806840.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":""}
|
||||
@@ -1,2 +1,2 @@
|
||||
.cm-s-dracula.CodeMirror,.cm-s-dracula .CodeMirror-gutters{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=5822.dd80c1b6.chunk.css.map*/
|
||||
.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=3320.f0806840.chunk.css.map*/
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"static/css/5822.dd80c1b6.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/3320.f0806840.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":""}
|
||||
@@ -1,2 +1,2 @@
|
||||
.cm-s-dracula.CodeMirror,.cm-s-dracula .CodeMirror-gutters{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=3816.dd80c1b6.chunk.css.map*/
|
||||
.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=3631.f0806840.chunk.css.map*/
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"static/css/8724.dd80c1b6.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/3631.f0806840.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":""}
|
||||
@@ -1,2 +1,2 @@
|
||||
.cm-s-dracula.CodeMirror,.cm-s-dracula .CodeMirror-gutters{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=964.dd80c1b6.chunk.css.map*/
|
||||
.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=380.f0806840.chunk.css.map*/
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"static/css/964.dd80c1b6.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/380.f0806840.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":""}
|
||||
@@ -1,2 +1,2 @@
|
||||
.cm-s-dracula.CodeMirror,.cm-s-dracula .CodeMirror-gutters{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=8724.dd80c1b6.chunk.css.map*/
|
||||
.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=8138.f0806840.chunk.css.map*/
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"static/css/3816.dd80c1b6.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/8138.f0806840.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":""}
|
||||
2
portal-ui/build/static/css/9033.f0806840.chunk.css
Normal file
2
portal-ui/build/static/css/9033.f0806840.chunk.css
Normal file
@@ -0,0 +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=9033.f0806840.chunk.css.map*/
|
||||
1
portal-ui/build/static/css/9033.f0806840.chunk.css.map
Normal file
1
portal-ui/build/static/css/9033.f0806840.chunk.css.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"static/css/9033.f0806840.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":""}
|
||||
2
portal-ui/build/static/css/9299.f0806840.chunk.css
Normal file
2
portal-ui/build/static/css/9299.f0806840.chunk.css
Normal file
@@ -0,0 +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=9299.f0806840.chunk.css.map*/
|
||||
1
portal-ui/build/static/css/9299.f0806840.chunk.css.map
Normal file
1
portal-ui/build/static/css/9299.f0806840.chunk.css.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"static/css/9299.f0806840.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":""}
|
||||
@@ -1,2 +0,0 @@
|
||||
.cm-s-dracula.CodeMirror,.cm-s-dracula .CodeMirror-gutters{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=9645.dd80c1b6.chunk.css.map*/
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"static/css/9645.dd80c1b6.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":""}
|
||||
@@ -1,2 +0,0 @@
|
||||
.cm-s-dracula.CodeMirror,.cm-s-dracula .CodeMirror-gutters{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=9807.dd80c1b6.chunk.css.map*/
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"static/css/9807.dd80c1b6.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":""}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,2 +0,0 @@
|
||||
"use strict";(self.webpackChunkportal_ui=self.webpackChunkportal_ui||[]).push([[1140],{39080:function(e,n,t){t.r(n),t.d(n,{default:function(){return Z}});var i=t(18489),r=t(35531),a=t(50390),s=t(38342),l=t.n(s),o=t(86509),c=t(4285),d=t(66946),u=t(51002),m=t(25594),h=t(58217),p=t(65771),x=t(70758),y=t(33034),g=t.n(y),f=t(86362),v=t(72462),j=t(62559),b=(0,c.Z)((function(e){return(0,o.Z)({container:{display:"flex",flexFlow:"column",padding:"20px 0 8px 0"},inputWithCopy:{"& .MuiInputBase-root ":{width:"100%",background:"#FBFAFA","& .MuiInputBase-input":{height:".8rem"},"& .MuiInputAdornment-positionEnd":{marginRight:".5rem","& .MuiButtonBase-root":{height:"2rem"}}},"& .MuiButtonBase-root .min-icon":{width:".8rem",height:".8rem"}},inputLabel:(0,i.Z)((0,i.Z)({},v.YI.inputLabel),{},{fontSize:".8rem"})})}))((function(e){var n=e.label,t=void 0===n?"":n,i=e.value,r=void 0===i?"":i,a=e.classes,s=void 0===a?{}:a;return(0,j.jsxs)("div",{className:s.container,children:[(0,j.jsxs)("div",{className:s.inputLabel,children:[t,":"]}),(0,j.jsx)("div",{className:s.inputWithCopy,children:(0,j.jsx)(h.Z,{value:r,readOnly:!0,endAdornment:(0,j.jsx)(p.Z,{position:"end",children:(0,j.jsx)(g(),{text:r,children:(0,j.jsx)(x.Z,{"aria-label":"copy",tooltip:"Copy",onClick:function(){},onMouseDown:function(){},edge:"end",children:(0,j.jsx)(f.TI,{})})})})})})]})})),w=t(47424),Z=(0,c.Z)((function(e){return(0,o.Z)({warningBlock:{color:"red",fontSize:".85rem",margin:".5rem 0 .5rem 0",display:"flex",alignItems:"center","& svg ":{marginRight:".3rem",height:16,width:16}},credentialTitle:{padding:".8rem 0 0 0",fontWeight:600,fontSize:".9rem"},buttonContainer:{textAlign:"right",marginTop:"1rem"},credentialsPanel:{overflowY:"auto",maxHeight:350},promptTitle:{display:"flex",alignItems:"center"},buttonSpacer:{marginRight:".9rem"},promptIcon:{marginRight:".1rem",display:"flex",alignItems:"center",height:"2rem",width:"2rem"}})}))((function(e){var n=e.classes,t=e.newServiceAccount,s=e.open,o=e.closeModal,c=e.entity;if(!t)return null;var h=l()(t,"console",null),p=l()(t,"idp",!1);return(0,j.jsx)(u.Z,{modalOpen:s,onClose:function(){o()},title:(0,j.jsx)("div",{className:n.promptTitle,children:(0,j.jsxs)("div",{children:["New ",c," Created"]})}),titleIcon:(0,j.jsx)(f.tV,{}),children:(0,j.jsxs)(m.ZP,{container:!0,children:[(0,j.jsxs)(m.ZP,{item:!0,xs:12,className:n.formScrollable,children:["A new ",c," has been created with the following details:",!p&&h&&(0,j.jsx)(a.Fragment,{children:(0,j.jsxs)(m.ZP,{item:!0,xs:12,className:n.credentialsPanel,children:[(0,j.jsx)("div",{className:n.credentialTitle,children:"Console Credentials"}),Array.isArray(h)&&h.map((function(e,n){return(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(b,{label:"Access Key",value:e.accessKey}),(0,j.jsx)(b,{label:"Secret Key",value:e.secretKey})]})})),!Array.isArray(h)&&(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(b,{label:"Access Key",value:h.accessKey}),(0,j.jsx)(b,{label:"Secret Key",value:h.secretKey})]})]})}),p?(0,j.jsx)("div",{className:n.warningBlock,children:"Please Login via the configured external identity provider."}):(0,j.jsxs)("div",{className:n.warningBlock,children:[(0,j.jsx)(w.Z,{}),(0,j.jsx)("span",{children:"Write these down, as this is the only time the secret will be displayed."})]})]}),(0,j.jsxs)(m.ZP,{item:!0,xs:12,className:n.buttonContainer,children:[(0,j.jsx)(d.Z,{id:"done-button",variant:"outlined",className:n.buttonSpacer,onClick:function(){o()},color:"primary",children:"Done"}),!p&&(0,j.jsx)(d.Z,{id:"download-button",onClick:function(){var e={};if(h)if(Array.isArray(h)){var n=h.map((function(e){return{url:e.url,access_key:e.accessKey,secret_key:e.secretKey,api:"s3v4",path:"auto"}}));e={console:(0,r.Z)(n)}}else e={console:[{url:h.url,access_key:h.accessKey,secret_key:h.secretKey,api:"s3v4",path:"auto"}]};!function(e,n){var t=document.createElement("a");t.setAttribute("href","data:text/plain;charset=utf-8,"+encodeURIComponent(n)),t.setAttribute("download",e),t.style.display="none",document.body.appendChild(t),t.click(),document.body.removeChild(t)}("credentials.json",JSON.stringify((0,i.Z)({},e)))},endIcon:(0,j.jsx)(f._8,{}),variant:"contained",color:"primary",children:"Download"})]})]})})}))}}]);
|
||||
//# sourceMappingURL=1140.044ef809.chunk.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -1,2 +0,0 @@
|
||||
"use strict";(self.webpackChunkportal_ui=self.webpackChunkportal_ui||[]).push([[1237],{37882:function(n,e,r){var o=r(18489),t=r(50390),i=r(62559);e.Z=function(n){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;function r(r){return(0,i.jsx)(t.Suspense,{fallback:e,children:(0,i.jsx)(n,(0,o.Z)({},r))})}return r}},25534:function(n,e,r){var o=r(18489),t=(r(50390),r(25594)),i=r(86509),a=r(4285),c=r(72462),l=r(62559);e.Z=(0,a.Z)((function(n){return(0,i.Z)((0,o.Z)({},c.Bw))}))((function(n){var e=n.classes,r=n.className,o=void 0===r?"":r,i=n.children;return(0,l.jsx)("div",{className:e.contentSpacer,children:(0,l.jsx)(t.ZP,{container:!0,children:(0,l.jsx)(t.ZP,{item:!0,xs:12,className:o,children:i})})})}))},31237:function(n,e,r){r.r(e);var o=r(50390),t=r(24442),i=r(70971),a=r(34424),c=r(44149),l=r(36176),u=r(37882),s=r(49495),d=r(62559),f=(0,u.Z)(o.lazy((function(){return Promise.all([r.e(14),r.e(3152),r.e(2066),r.e(3690),r.e(5399),r.e(8174),r.e(3967)]).then(r.bind(r,63967))}))),p=(0,u.Z)(o.lazy((function(){return Promise.all([r.e(14),r.e(3152),r.e(2066),r.e(3690),r.e(5399),r.e(6117),r.e(8954),r.e(8174),r.e(4084)]).then(r.bind(r,5604))}))),m=(0,a.$j)((function(n){return{open:n.system.sidebarOpen}}),{setMenuOpen:c.gG});e.default=(0,i.EN)(m((function(){return(0,d.jsx)(i.F0,{history:t.Z,children:(0,d.jsxs)(i.rs,{children:[(0,d.jsx)(i.AW,{path:s.gA.POLICIES,exact:!0,component:f}),(0,d.jsx)(i.AW,{path:"".concat(s.gA.POLICIES,"/*"),component:p}),(0,d.jsx)(i.AW,{path:"/",component:f}),(0,d.jsx)(i.AW,{component:l.Z})]})})})))},36176:function(n,e,r){r.d(e,{Z:function(){return u}});r(50390);var o=r(56805),t=r(35477),i=r(10567),a=r(62559);function c(){return(0,a.jsxs)(t.Z,{variant:"body2",color:"textSecondary",align:"center",children:["Copyright \xa9 ",(0,a.jsx)(i.Z,{color:"inherit",href:"https://min.io/?ref=con",children:"MinIO"})," ",(new Date).getFullYear(),"."]})}var l=r(25534),u=function(){return(0,a.jsx)(l.Z,{children:(0,a.jsxs)(o.Z,{sx:{display:"flex",alignItems:"center",justifyContent:"center",height:"100%",textAlign:"center",margin:"auto",flexFlow:"column"},children:[(0,a.jsx)(o.Z,{sx:{fontSize:"110%",margin:"0 0 0.25rem",color:"#909090"},children:"404 Error"}),(0,a.jsx)(o.Z,{sx:{fontStyle:"normal",fontSize:"clamp(2rem,calc(2rem + 1.2vw),3rem)",fontWeight:700},children:"Sorry, the page could not be found."}),(0,a.jsx)(o.Z,{mt:5,children:(0,a.jsx)(c,{})})]})})}},10567:function(n,e,r){r.d(e,{Z:function(){return k}});var o=r(23430),t=r(36222),i=r(1048),a=r(32793),c=r(50390),l=r(44977),u=r(50076),s=r(29001),d=r(36128),f=r(91442),p=r(8208),m=r(15573),h=r(42081),x=r(3299),Z=r(35477),v=r(10594);function y(n){return(0,v.Z)("MuiLink",n)}var b=(0,r(43349).Z)("MuiLink",["root","underlineNone","underlineHover","underlineAlways","button","focusVisible"]),g=r(62559),j=["className","color","component","onBlur","onFocus","TypographyClasses","underline","variant"],S={primary:"primary.main",textPrimary:"text.primary",secondary:"secondary.main",textSecondary:"text.secondary",error:"error.main"},w=(0,p.ZP)(Z.Z,{name:"MuiLink",slot:"Root",overridesResolver:function(n,e){var r=n.ownerState;return[e.root,e["underline".concat((0,f.Z)(r.underline))],"button"===r.component&&e.button]}})((function(n){var e=n.theme,r=n.ownerState,o=(0,s.D)(e,"palette.".concat(function(n){return S[n]||n}(r.color)))||r.color;return(0,a.Z)({},"none"===r.underline&&{textDecoration:"none"},"hover"===r.underline&&{textDecoration:"none","&:hover":{textDecoration:"underline"}},"always"===r.underline&&{textDecoration:"underline",textDecorationColor:"inherit"!==o?(0,d.Fq)(o,.4):void 0,"&:hover":{textDecorationColor:"inherit"}},"button"===r.component&&(0,t.Z)({position:"relative",WebkitTapHighlightColor:"transparent",backgroundColor:"transparent",outline:0,border:0,margin:0,borderRadius:0,padding:0,cursor:"pointer",userSelect:"none",verticalAlign:"middle",MozAppearance:"none",WebkitAppearance:"none","&::-moz-focus-inner":{borderStyle:"none"}},"&.".concat(b.focusVisible),{outline:"auto"}))})),k=c.forwardRef((function(n,e){var r=(0,m.Z)({props:n,name:"MuiLink"}),t=r.className,s=r.color,d=void 0===s?"primary":s,p=r.component,Z=void 0===p?"a":p,v=r.onBlur,b=r.onFocus,S=r.TypographyClasses,k=r.underline,C=void 0===k?"always":k,A=r.variant,F=void 0===A?"inherit":A,D=(0,i.Z)(r,j),N=(0,h.Z)(),P=N.isFocusVisibleRef,M=N.onBlur,W=N.onFocus,z=N.ref,I=c.useState(!1),L=(0,o.Z)(I,2),V=L[0],B=L[1],O=(0,x.Z)(e,z),R=(0,a.Z)({},r,{color:d,component:Z,focusVisible:V,underline:C,variant:F}),E=function(n){var e=n.classes,r=n.component,o=n.focusVisible,t=n.underline,i={root:["root","underline".concat((0,f.Z)(t)),"button"===r&&"button",o&&"focusVisible"]};return(0,u.Z)(i,y,e)}(R);return(0,g.jsx)(w,(0,a.Z)({className:(0,l.Z)(E.root,t),classes:S,color:d,component:Z,onBlur:function(n){M(n),!1===P.current&&B(!1),v&&v(n)},onFocus:function(n){W(n),!0===P.current&&B(!0),b&&b(n)},ref:O,ownerState:R,variant:F},D))}))}}]);
|
||||
//# sourceMappingURL=1237.b46ec019.chunk.js.map
|
||||
2
portal-ui/build/static/js/1326.19aa2326.chunk.js
Normal file
2
portal-ui/build/static/js/1326.19aa2326.chunk.js
Normal file
File diff suppressed because one or more lines are too long
1
portal-ui/build/static/js/1326.19aa2326.chunk.js.map
Normal file
1
portal-ui/build/static/js/1326.19aa2326.chunk.js.map
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
portal-ui/build/static/js/1434.2cbee404.chunk.js
Normal file
2
portal-ui/build/static/js/1434.2cbee404.chunk.js
Normal file
File diff suppressed because one or more lines are too long
1
portal-ui/build/static/js/1434.2cbee404.chunk.js.map
Normal file
1
portal-ui/build/static/js/1434.2cbee404.chunk.js.map
Normal file
File diff suppressed because one or more lines are too long
2
portal-ui/build/static/js/1440.146b37eb.chunk.js
Normal file
2
portal-ui/build/static/js/1440.146b37eb.chunk.js
Normal file
File diff suppressed because one or more lines are too long
1
portal-ui/build/static/js/1440.146b37eb.chunk.js.map
Normal file
1
portal-ui/build/static/js/1440.146b37eb.chunk.js.map
Normal file
File diff suppressed because one or more lines are too long
2
portal-ui/build/static/js/1520.5385d6f6.chunk.js
Normal file
2
portal-ui/build/static/js/1520.5385d6f6.chunk.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
portal-ui/build/static/js/1581.3e4f9436.chunk.js
Normal file
2
portal-ui/build/static/js/1581.3e4f9436.chunk.js
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";(self.webpackChunkportal_ui=self.webpackChunkportal_ui||[]).push([[1581],{1581:function(e,a,t){t.r(a);var n=t(29439),s=t(1413),o=t(72791),i=t(60364),l=t(36151),c=t(40986),r=t(11135),d=t(25787),u=t(61889),m=t(45248),f=t(42649),h=t(23814),Z=t(37516),x=t(21435),p=t(56028),j=t(81207),g=t(93656),k=t(56578),v=t(80184),b=(0,i.$j)(null,{setModalErrorSnackMessage:f.zb});a.default=(0,d.Z)((function(e){return(0,r.Z)((0,s.Z)((0,s.Z)({},h.DF),h.ID))}))(b((function(e){var a=e.classes,t=e.open,s=e.enabled,i=e.cfg,r=e.selectedBucket,d=e.closeModalAndRefresh,f=e.setModalErrorSnackMessage,h=(0,o.useState)(!1),b=(0,n.Z)(h,2),M=b[0],S=b[1],C=(0,o.useState)(!1),q=(0,n.Z)(C,2),N=q[0],B=q[1],P=(0,o.useState)("1"),y=(0,n.Z)(P,2),w=y[0],E=y[1],_=(0,o.useState)("TiB"),z=(0,n.Z)(_,2),D=z[0],F=z[1];(0,o.useEffect)((function(){if(s&&(B(!0),i)){E("".concat(i.quota)),F("Gi");for(var e="B",a=i.quota,t=0;t<m.Dl.length&&i.quota%Math.pow(1024,t)===0;t++)a=i.quota/Math.pow(1024,t),e=m.Dl[t];E("".concat(a)),F(e)}}),[s,i]);return(0,v.jsx)(p.Z,{modalOpen:t,onClose:function(){d()},title:"Enable Bucket Quota",titleIcon:(0,v.jsx)(g.Wq,{}),children:(0,v.jsx)("form",{noValidate:!0,autoComplete:"off",onSubmit:function(e){e.preventDefault(),function(){if(!M){var e={enabled:N,amount:parseInt((0,m.Pw)(w,D,!0)),quota_type:"hard"};j.Z.invoke("PUT","/api/v1/buckets/".concat(r,"/quota"),e).then((function(){S(!1),d()})).catch((function(e){S(!1),f(e)}))}}()},children:(0,v.jsxs)(u.ZP,{container:!0,children:[(0,v.jsxs)(u.ZP,{item:!0,xs:12,className:a.formScrollable,children:[(0,v.jsx)(u.ZP,{item:!0,xs:12,className:a.formFieldRow,children:(0,v.jsx)(Z.Z,{value:"bucket_quota",id:"bucket_quota",name:"bucket_quota",checked:N,onChange:function(e){B(e.target.checked)},label:"Enabled"})}),N&&(0,v.jsx)(o.Fragment,{children:(0,v.jsx)(u.ZP,{item:!0,xs:12,className:a.formFieldRow,children:(0,v.jsx)(u.ZP,{container:!0,children:(0,v.jsx)(u.ZP,{item:!0,xs:12,children:(0,v.jsx)(x.Z,{id:"quota_size",name:"quota_size",onChange:function(e){e.target.validity.valid&&E(e.target.value)},pattern:"[0-9]*",label:"Quota",value:w,required:!0,min:"1",overlayObject:(0,v.jsx)(k.Z,{id:"quota_unit",onUnitChange:function(e){F(e)},unitSelected:D,unitsList:(0,m.zQ)(["Ki"]),disabled:!1})})})})})})]}),(0,v.jsxs)(u.ZP,{item:!0,xs:12,className:a.modalButtonBar,children:[(0,v.jsx)(l.Z,{type:"button",variant:"outlined",color:"primary",disabled:M,onClick:function(){d()},children:"Cancel"}),(0,v.jsx)(l.Z,{type:"submit",variant:"contained",color:"primary",disabled:M,children:"Save"})]}),M&&(0,v.jsx)(u.ZP,{item:!0,xs:12,children:(0,v.jsx)(c.Z,{})})]})})})})))},56028:function(e,a,t){var n=t(29439),s=t(1413),o=t(72791),i=t(60364),l=t(13400),c=t(55646),r=t(5574),d=t(65661),u=t(39157),m=t(11135),f=t(25787),h=t(23814),Z=t(42649),x=t(29823),p=t(28057),j=t(80184),g=(0,i.$j)((function(e){return{modalSnackMessage:e.system.modalSnackBar}}),{setModalSnackMessage:Z.MK});a.Z=(0,f.Z)((function(e){return(0,m.Z)((0,s.Z)((0,s.Z)({},h.Qw),{},{content:{padding:25,paddingBottom:0},customDialogSize:{width:"100%",maxWidth:765}},h.sN))}))(g((function(e){var a=e.onClose,t=e.modalOpen,i=e.title,m=e.children,f=e.classes,h=e.wideLimit,Z=void 0===h||h,g=e.modalSnackMessage,k=e.noContentPadding,v=e.setModalSnackMessage,b=e.titleIcon,M=void 0===b?null:b,S=(0,o.useState)(!1),C=(0,n.Z)(S,2),q=C[0],N=C[1];(0,o.useEffect)((function(){v("")}),[v]),(0,o.useEffect)((function(){if(g){if(""===g.message)return void N(!1);"error"!==g.type&&N(!0)}}),[g]);var B=Z?{classes:{paper:f.customDialogSize}}:{maxWidth:"lg",fullWidth:!0},P="";return g&&(P=g.detailedErrorMsg,(""===g.detailedErrorMsg||g.detailedErrorMsg.length<5)&&(P=g.message)),(0,j.jsxs)(r.Z,(0,s.Z)((0,s.Z)({open:t,classes:f},B),{},{scroll:"paper",onClose:function(e,t){"backdropClick"!==t&&a()},className:f.root,children:[(0,j.jsxs)(d.Z,{className:f.title,children:[(0,j.jsxs)("div",{className:f.titleText,children:[M," ",i]}),(0,j.jsx)("div",{className:f.closeContainer,children:(0,j.jsx)(l.Z,{"aria-label":"close",id:"close",className:f.closeButton,onClick:a,disableRipple:!0,size:"small",children:(0,j.jsx)(x.Z,{})})})]}),(0,j.jsx)(p.Z,{isModal:!0}),(0,j.jsx)(c.Z,{open:q,className:f.snackBarModal,onClose:function(){N(!1),v("")},message:P,ContentProps:{className:"".concat(f.snackBar," ").concat(g&&"error"===g.type?f.errorSnackBar:"")},autoHideDuration:g&&"error"===g.type?1e4:5e3}),(0,j.jsx)(u.Z,{className:k?"":f.content,children:m})]}))})))},29823:function(e,a,t){var n=t(95318);a.Z=void 0;var s=n(t(45649)),o=t(80184),i=(0,s.default)((0,o.jsx)("path",{d:"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"}),"Close");a.Z=i}}]);
|
||||
//# sourceMappingURL=1581.3e4f9436.chunk.js.map
|
||||
1
portal-ui/build/static/js/1581.3e4f9436.chunk.js.map
Normal file
1
portal-ui/build/static/js/1581.3e4f9436.chunk.js.map
Normal file
File diff suppressed because one or more lines are too long
2
portal-ui/build/static/js/1604.c6070715.chunk.js
Normal file
2
portal-ui/build/static/js/1604.c6070715.chunk.js
Normal file
File diff suppressed because one or more lines are too long
1
portal-ui/build/static/js/1604.c6070715.chunk.js.map
Normal file
1
portal-ui/build/static/js/1604.c6070715.chunk.js.map
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
portal-ui/build/static/js/1687.72fad20d.chunk.js
Normal file
2
portal-ui/build/static/js/1687.72fad20d.chunk.js
Normal file
File diff suppressed because one or more lines are too long
1
portal-ui/build/static/js/1687.72fad20d.chunk.js.map
Normal file
1
portal-ui/build/static/js/1687.72fad20d.chunk.js.map
Normal file
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user