Compare commits
132 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
151c8117a3 | ||
|
|
9b5c17c2db | ||
|
|
23e01b257e | ||
|
|
ecc8c7a86e | ||
|
|
ee4d7b9b69 | ||
|
|
80c03839a4 | ||
|
|
f394cb69ce | ||
|
|
52137ba9e5 | ||
|
|
942b8101cc | ||
|
|
a0a6b33ecd | ||
|
|
d4c5e1b51c | ||
|
|
96923aed75 | ||
|
|
a04f833e3f | ||
|
|
3b52cc9bd4 | ||
|
|
df2e92e451 | ||
|
|
8836fe043b | ||
|
|
7ce6a58099 | ||
|
|
57d6aca716 | ||
|
|
8d99637455 | ||
|
|
abd66780f4 | ||
|
|
a5175a35ec | ||
|
|
d9f945b5df | ||
|
|
0c55e39e8c | ||
|
|
b5443952da | ||
|
|
b9f0ccfaba | ||
|
|
24742325b7 | ||
|
|
c87ebe447f | ||
|
|
462cf16db9 | ||
|
|
edaa4e8754 | ||
|
|
76c596c574 | ||
|
|
b5554f6dcf | ||
|
|
fc65f1afd1 | ||
|
|
b066b6a920 | ||
|
|
bc0e63aac8 | ||
|
|
343ff575e6 | ||
|
|
08c922dca6 | ||
|
|
4dd6519cc6 | ||
|
|
cdffdae289 | ||
|
|
27e3b82223 | ||
|
|
239b31748a | ||
|
|
b465b74326 | ||
|
|
616f262d09 | ||
|
|
8aa0ec17c5 | ||
|
|
a8c5b53a2c | ||
|
|
e96dbd444e | ||
|
|
939e2acb0b | ||
|
|
a04955dc70 | ||
|
|
ba04a22492 | ||
|
|
a281fe129f | ||
|
|
a655cc8d3b | ||
|
|
63b584c83d | ||
|
|
7dffd5f079 | ||
|
|
044e5702df | ||
|
|
3c3b9546d9 | ||
|
|
5bc0e74b53 | ||
|
|
f0d4dddacd | ||
|
|
f4a3f46bcf | ||
|
|
38472e4cd2 | ||
|
|
9db5d1e4f4 | ||
|
|
4cadaf7d49 | ||
|
|
748486160f | ||
|
|
2c0a0b2bc4 | ||
|
|
7e51d4bebb | ||
|
|
c011e67122 | ||
|
|
394b4c403d | ||
|
|
74030aa067 | ||
|
|
07b8c745e6 | ||
|
|
6767bfa2d2 | ||
|
|
607d94fef4 | ||
|
|
83b060ef94 | ||
|
|
cb14cb94ce | ||
|
|
2b9de49fbe | ||
|
|
290f273bdf | ||
|
|
7b43779fb0 | ||
|
|
924c38faa6 | ||
|
|
e4d5f9610e | ||
|
|
04e9cb0ac8 | ||
|
|
da53daff37 | ||
|
|
8c26eff2c1 | ||
|
|
044c265423 | ||
|
|
0053658d5d | ||
|
|
99cf3b378f | ||
|
|
78293eab62 | ||
|
|
1a84be5782 | ||
|
|
178f82b675 | ||
|
|
ec5fbbcd1e | ||
|
|
78164054d4 | ||
|
|
6d5d11d5b4 | ||
|
|
9e3b93d385 | ||
|
|
d77cf93193 | ||
|
|
2cca3f3722 | ||
|
|
36d96a1791 | ||
|
|
82e34a5df2 | ||
|
|
7b83f4b1dc | ||
|
|
7d9910d1ca | ||
|
|
7a63f6da56 | ||
|
|
0043833f36 | ||
|
|
3ad3bccadb | ||
|
|
39e94c890e | ||
|
|
701039454a | ||
|
|
ec77a03d7c | ||
|
|
8dbad84a58 | ||
|
|
1767a37162 | ||
|
|
622c3a067a | ||
|
|
4389548b64 | ||
|
|
8cb0f1e558 | ||
|
|
faafb77c73 | ||
|
|
0ecd1c73c1 | ||
|
|
88bf40f9a6 | ||
|
|
a025163b34 | ||
|
|
07c80462b7 | ||
|
|
79ac2277d4 | ||
|
|
1c27bee9d0 | ||
|
|
56dc58b0b8 | ||
|
|
4018addd79 | ||
|
|
429dfb4314 | ||
|
|
1d7bb0bb2b | ||
|
|
476eb673bb | ||
|
|
71681b710c | ||
|
|
fb02a7da06 | ||
|
|
5fdc341138 | ||
|
|
15de6caf75 | ||
|
|
77bc2d5006 | ||
|
|
972f5fca9d | ||
|
|
083314ee2d | ||
|
|
078ce0e546 | ||
|
|
9beca2c226 | ||
|
|
451f23ae24 | ||
|
|
300ebfa19f | ||
|
|
1ce2846c95 | ||
|
|
7fb8c11a9d | ||
|
|
e7993c2d1b |
@@ -3,5 +3,5 @@ dist/
|
||||
target/
|
||||
console
|
||||
!console/
|
||||
portal-ui/node_modules/
|
||||
web-app/node_modules/
|
||||
.git/
|
||||
|
||||
275
.github/workflows/jobs.yaml
vendored
275
.github/workflows/jobs.yaml
vendored
@@ -19,11 +19,11 @@ concurrency:
|
||||
jobs:
|
||||
lint-job:
|
||||
name: Checking Lint
|
||||
runs-on: [ubuntu-latest]
|
||||
runs-on: [ ubuntu-latest ]
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
os: [ubuntu-latest]
|
||||
go-version: [ 1.21.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out source code
|
||||
uses: actions/checkout@v3
|
||||
@@ -58,15 +58,15 @@ jobs:
|
||||
# https://github.com/actions/checkout/issues/334
|
||||
sudo apt install -y python3-pip || apt install -y python3-pip
|
||||
pip3 install semgrep
|
||||
semgrep --config semgrep.yaml $(pwd)/portal-ui --error
|
||||
semgrep --config semgrep.yaml $(pwd)/web-app --error
|
||||
|
||||
ui-assets:
|
||||
name: "React Code Has No Warnings & Prettified"
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
os: [ubuntu-latest]
|
||||
go-version: [ 1.21.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
@@ -77,31 +77,31 @@ jobs:
|
||||
with:
|
||||
node-version: ${{ env.NVMRC }}
|
||||
cache: "yarn"
|
||||
cache-dependency-path: portal-ui/yarn.lock
|
||||
cache-dependency-path: web-app/yarn.lock
|
||||
- uses: actions/cache@v3
|
||||
id: assets-cache
|
||||
name: Assets Cache
|
||||
with:
|
||||
path: |
|
||||
./portal-ui/build/
|
||||
./web-app/build/
|
||||
key: ${{ runner.os }}-assets-${{ github.run_id }}
|
||||
- name: Install Dependencies
|
||||
working-directory: ./portal-ui
|
||||
working-directory: ./web-app
|
||||
continue-on-error: false
|
||||
run: |
|
||||
yarn install --frozen-lockfile --immutable
|
||||
- name: Check for Warnings in build output
|
||||
working-directory: ./portal-ui
|
||||
working-directory: ./web-app
|
||||
continue-on-error: false
|
||||
run: |
|
||||
./check-warnings.sh
|
||||
- name: Check if Files are Prettified
|
||||
working-directory: ./portal-ui
|
||||
working-directory: ./web-app
|
||||
continue-on-error: false
|
||||
run: |
|
||||
./check-prettier.sh
|
||||
- name: Check for dead code
|
||||
working-directory: ./portal-ui
|
||||
working-directory: ./web-app
|
||||
continue-on-error: false
|
||||
run: |
|
||||
./check-deadcode.sh
|
||||
@@ -110,8 +110,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
os: [ubuntu-latest]
|
||||
go-version: [ 1.21.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
@@ -130,10 +130,10 @@ jobs:
|
||||
|
||||
latest-minio:
|
||||
name: Build latest MinIO
|
||||
runs-on: [ubuntu-latest]
|
||||
runs-on: [ ubuntu-latest ]
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
go-version: [ 1.21.x ]
|
||||
steps:
|
||||
# To build minio image, we need to clone the repository first
|
||||
- name: Clone github.com/minio/minio
|
||||
@@ -168,8 +168,8 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
os: [ubuntu-latest]
|
||||
go-version: [ 1.21.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
@@ -191,7 +191,7 @@ jobs:
|
||||
name: Assets Cache
|
||||
with:
|
||||
path: |
|
||||
./portal-ui/build/
|
||||
./web-app/build/
|
||||
key: ${{ runner.os }}-assets-${{ github.run_id }}
|
||||
- name: Build on ${{ matrix.os }}
|
||||
env:
|
||||
@@ -204,12 +204,12 @@ jobs:
|
||||
name: Test Subpath with Nginx
|
||||
needs:
|
||||
- compile-binary
|
||||
runs-on: [ubuntu-latest]
|
||||
runs-on: [ ubuntu-latest ]
|
||||
timeout-minutes: 10
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
os: [ubuntu-latest]
|
||||
go-version: [ 1.21.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
@@ -242,7 +242,7 @@ jobs:
|
||||
run: npm install testcafe@3.0.0
|
||||
|
||||
- name: Run TestCafe Tests
|
||||
run: npx testcafe "chrome:headless" portal-ui/tests/subpath-nginx/ -q --skip-js-errors -c 3
|
||||
run: npx testcafe "chrome:headless" web-app/tests/subpath-nginx/ -q --skip-js-errors -c 3
|
||||
|
||||
- name: Clean up docker
|
||||
if: always()
|
||||
@@ -253,12 +253,12 @@ jobs:
|
||||
name: Permissions Tests Part 1
|
||||
needs:
|
||||
- compile-binary
|
||||
runs-on: [ubuntu-latest]
|
||||
runs-on: [ ubuntu-latest ]
|
||||
timeout-minutes: 10
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
os: [ubuntu-latest]
|
||||
go-version: [ 1.21.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
@@ -291,7 +291,7 @@ jobs:
|
||||
run: npm install testcafe@3.0.0
|
||||
|
||||
- name: Run TestCafe Tests
|
||||
run: npx testcafe "chrome:headless" portal-ui/tests/permissions-1/ -q --skip-js-errors -c 3
|
||||
run: npx testcafe "chrome:headless" web-app/tests/permissions-1/ -q --skip-js-errors -c 3
|
||||
|
||||
- name: Clean up users & policies
|
||||
run: |
|
||||
@@ -301,12 +301,12 @@ jobs:
|
||||
name: Permissions Tests Part 2
|
||||
needs:
|
||||
- compile-binary
|
||||
runs-on: [ubuntu-latest]
|
||||
runs-on: [ ubuntu-latest ]
|
||||
timeout-minutes: 10
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
os: [ubuntu-latest]
|
||||
go-version: [ 1.21.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
@@ -338,7 +338,7 @@ jobs:
|
||||
run: npm install testcafe@3.0.0
|
||||
|
||||
- name: Run TestCafe Tests
|
||||
run: npx testcafe "chrome:headless" portal-ui/tests/permissions-2/ -q --skip-js-errors -c 3
|
||||
run: npx testcafe "chrome:headless" web-app/tests/permissions-2/ -q --skip-js-errors -c 3
|
||||
|
||||
- name: Clean up users & policies
|
||||
run: |
|
||||
@@ -348,12 +348,12 @@ jobs:
|
||||
name: Permissions Tests Part 3
|
||||
needs:
|
||||
- compile-binary
|
||||
runs-on: [ubuntu-latest]
|
||||
runs-on: [ ubuntu-latest ]
|
||||
timeout-minutes: 10
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
os: [ubuntu-latest]
|
||||
go-version: [ 1.21.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
@@ -385,7 +385,7 @@ jobs:
|
||||
run: npm install testcafe@3.0.0
|
||||
|
||||
- name: Run TestCafe Tests
|
||||
run: npx testcafe "chrome:headless" portal-ui/tests/permissions-3/ -q --skip-js-errors -c 3
|
||||
run: npx testcafe "chrome:headless" web-app/tests/permissions-3/ -q --skip-js-errors -c 3
|
||||
|
||||
- name: Clean up users & policies
|
||||
run: |
|
||||
@@ -395,12 +395,12 @@ jobs:
|
||||
name: Permissions Tests Part 4
|
||||
needs:
|
||||
- compile-binary
|
||||
runs-on: [ubuntu-latest]
|
||||
runs-on: [ ubuntu-latest ]
|
||||
timeout-minutes: 15
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
os: [ubuntu-latest]
|
||||
go-version: [ 1.21.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
@@ -433,17 +433,17 @@ jobs:
|
||||
|
||||
- name: Run TestCafe Tests
|
||||
timeout-minutes: 10
|
||||
run: npx testcafe "chrome:headless" portal-ui/tests/permissions-4/ --skip-js-errors
|
||||
run: npx testcafe "chrome:headless" web-app/tests/permissions-4/ --skip-js-errors
|
||||
|
||||
all-permissions-5:
|
||||
name: Permissions Tests Part 5
|
||||
needs:
|
||||
- compile-binary
|
||||
runs-on: [ubuntu-latest]
|
||||
runs-on: [ ubuntu-latest ]
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
os: [ubuntu-latest]
|
||||
go-version: [ 1.21.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
@@ -476,17 +476,17 @@ jobs:
|
||||
|
||||
- name: Run TestCafe Tests
|
||||
timeout-minutes: 5
|
||||
run: npx testcafe "chrome:headless" portal-ui/tests/permissions-5/ --skip-js-errors
|
||||
run: npx testcafe "chrome:headless" web-app/tests/permissions-5/ --skip-js-errors
|
||||
|
||||
all-permissions-6:
|
||||
name: Permissions Tests Part 6
|
||||
needs:
|
||||
- compile-binary
|
||||
runs-on: [ubuntu-latest]
|
||||
runs-on: [ ubuntu-latest ]
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
os: [ubuntu-latest]
|
||||
go-version: [ 1.21.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
@@ -519,17 +519,17 @@ jobs:
|
||||
|
||||
- name: Run TestCafe Tests
|
||||
timeout-minutes: 5
|
||||
run: npx testcafe "chrome:headless" portal-ui/tests/permissions-6/ --skip-js-errors
|
||||
run: npx testcafe "chrome:headless" web-app/tests/permissions-6/ --skip-js-errors
|
||||
|
||||
all-permissions-7:
|
||||
name: Permissions Tests Part 7
|
||||
needs:
|
||||
- compile-binary
|
||||
runs-on: [ubuntu-latest]
|
||||
runs-on: [ ubuntu-latest ]
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
os: [ubuntu-latest]
|
||||
go-version: [ 1.21.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
@@ -561,17 +561,17 @@ jobs:
|
||||
|
||||
- name: Run TestCafe Tests
|
||||
timeout-minutes: 5
|
||||
run: npx testcafe "chrome:headless" portal-ui/tests/permissions-7/ --skip-js-errors
|
||||
run: npx testcafe "chrome:headless" web-app/tests/permissions-7/ --skip-js-errors
|
||||
|
||||
all-permissions-8:
|
||||
name: Permissions Tests Part 8
|
||||
needs:
|
||||
- compile-binary
|
||||
runs-on: [ubuntu-latest]
|
||||
runs-on: [ ubuntu-latest ]
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
os: [ubuntu-latest]
|
||||
go-version: [ 1.21.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
@@ -604,63 +604,17 @@ jobs:
|
||||
|
||||
- name: Run TestCafe Tests
|
||||
timeout-minutes: 5
|
||||
run: npx testcafe "chrome:headless" portal-ui/tests/permissions-8/ --skip-js-errors
|
||||
|
||||
all-permissions-9:
|
||||
name: Permissions Tests Part 9
|
||||
needs:
|
||||
- compile-binary
|
||||
runs-on: [ubuntu-latest]
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
os: [ubuntu-latest]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NVMRC }}
|
||||
- name: Install MinIO JS
|
||||
working-directory: ./
|
||||
continue-on-error: false
|
||||
run: |
|
||||
yarn add minio
|
||||
- uses: actions/cache@v3
|
||||
name: Console Binary Cache
|
||||
with:
|
||||
path: |
|
||||
./console
|
||||
key: ${{ runner.os }}-binary-${{ github.run_id }}
|
||||
|
||||
- name: clean-previous-containers-if-any
|
||||
run: |
|
||||
docker stop minio || true;
|
||||
docker container prune -f || true;
|
||||
|
||||
- name: Start Console, front-end app and initialize users/policies
|
||||
run: |
|
||||
(./console server) & (make initialize-permissions)
|
||||
|
||||
- name: Install TestCafe
|
||||
run: npm install testcafe@3.0.0
|
||||
|
||||
- name: Run TestCafe Tests
|
||||
run: npx testcafe "chrome:headless" portal-ui/tests/permissions-9/ --skip-js-errors -c 3
|
||||
|
||||
- name: Clean up users & policies
|
||||
run: |
|
||||
make cleanup-permissions
|
||||
run: npx testcafe "chrome:headless" web-app/tests/permissions-8/ --skip-js-errors
|
||||
|
||||
all-permissions-A:
|
||||
name: Permissions Tests Part A
|
||||
needs:
|
||||
- compile-binary
|
||||
runs-on: [ubuntu-latest]
|
||||
runs-on: [ ubuntu-latest ]
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
os: [ubuntu-latest]
|
||||
go-version: [ 1.21.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
@@ -692,7 +646,7 @@ jobs:
|
||||
run: npm install testcafe@3.0.0
|
||||
|
||||
- name: Run TestCafe Tests
|
||||
run: npx testcafe "chrome:headless" portal-ui/tests/permissions-A/ --skip-js-errors -c 3
|
||||
run: npx testcafe "chrome:headless" web-app/tests/permissions-A/ --skip-js-errors -c 3
|
||||
|
||||
- name: Clean up users & policies
|
||||
run: |
|
||||
@@ -702,11 +656,11 @@ jobs:
|
||||
name: Permissions Tests Part B
|
||||
needs:
|
||||
- compile-binary
|
||||
runs-on: [ubuntu-latest]
|
||||
runs-on: [ ubuntu-latest ]
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
os: [ubuntu-latest]
|
||||
go-version: [ 1.21.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
@@ -738,7 +692,7 @@ jobs:
|
||||
run: npm install testcafe@3.0.0
|
||||
|
||||
- name: Run TestCafe Tests
|
||||
run: npx testcafe "chrome:headless" portal-ui/tests/permissions-B/ --skip-js-errors -c 3
|
||||
run: npx testcafe "chrome:headless" web-app/tests/permissions-B/ --skip-js-errors -c 3
|
||||
|
||||
- name: Clean up users & policies
|
||||
run: |
|
||||
@@ -754,8 +708,8 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
os: [ubuntu-latest]
|
||||
go-version: [ 1.21.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
@@ -781,8 +735,8 @@ jobs:
|
||||
path: |
|
||||
./pkg/coverage/
|
||||
key: ${{ runner.os }}-coverage-pkg-2-${{ github.run_id }}
|
||||
test-restapi-on-go:
|
||||
name: Test Restapi on Go ${{ matrix.go-version }} and ${{ matrix.os }}
|
||||
test-api-on-go:
|
||||
name: Test API on Go ${{ matrix.go-version }} and ${{ matrix.os }}
|
||||
needs:
|
||||
- lint-job
|
||||
- ui-assets
|
||||
@@ -791,8 +745,8 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
os: [ubuntu-latest]
|
||||
go-version: [ 1.21.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
@@ -812,12 +766,12 @@ jobs:
|
||||
make test
|
||||
|
||||
- uses: actions/cache@v3
|
||||
id: coverage-cache-restapi
|
||||
name: Coverage Cache RestAPI
|
||||
id: coverage-cache-api
|
||||
name: Coverage Cache API
|
||||
with:
|
||||
path: |
|
||||
./restapi/coverage/
|
||||
key: ${{ runner.os }}-coverage-restapi-2-${{ github.run_id }}
|
||||
./api/coverage/
|
||||
key: ${{ runner.os }}-coverage-api-2-${{ github.run_id }}
|
||||
b-integration-tests:
|
||||
name: Integration Tests with Latest Distributed MinIO
|
||||
needs:
|
||||
@@ -830,7 +784,7 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
go-version: [ 1.21.x ]
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
@@ -902,10 +856,10 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install modules
|
||||
working-directory: ./portal-ui
|
||||
working-directory: ./web-app
|
||||
run: yarn
|
||||
- name: Run tests
|
||||
working-directory: ./portal-ui
|
||||
working-directory: ./web-app
|
||||
run: yarn test
|
||||
replication:
|
||||
name: Site Replication Test
|
||||
@@ -915,11 +869,11 @@ jobs:
|
||||
- reuse-golang-dependencies
|
||||
- semgrep-static-code-analysis
|
||||
- latest-minio
|
||||
runs-on: [ubuntu-latest]
|
||||
runs-on: [ ubuntu-latest ]
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
go-version: [ 1.21.x ]
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
@@ -994,7 +948,7 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
go-version: [ 1.21.x ]
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
@@ -1058,15 +1012,15 @@ jobs:
|
||||
name: "Coverage Limit Check"
|
||||
needs:
|
||||
- b-integration-tests
|
||||
- test-restapi-on-go
|
||||
- test-api-on-go
|
||||
- test-pkg-on-go
|
||||
- sso-integration
|
||||
- replication
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
os: [ubuntu-latest]
|
||||
go-version: [ 1.21.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
@@ -1107,12 +1061,12 @@ jobs:
|
||||
key: ${{ runner.os }}-replication-coverage-2-${{ github.run_id }}
|
||||
|
||||
- uses: actions/cache@v3
|
||||
id: coverage-cache-restapi
|
||||
name: Coverage Cache RestAPI
|
||||
id: coverage-cache-api
|
||||
name: Coverage Cache API
|
||||
with:
|
||||
path: |
|
||||
./restapi/coverage/
|
||||
key: ${{ runner.os }}-coverage-restapi-2-${{ github.run_id }}
|
||||
./api/coverage/
|
||||
key: ${{ runner.os }}-coverage-api-2-${{ github.run_id }}
|
||||
|
||||
- uses: actions/cache@v3
|
||||
id: coverage-cache-pkg
|
||||
@@ -1139,7 +1093,7 @@ jobs:
|
||||
echo "go build gocoverage.go"
|
||||
go build gocovmerge.go
|
||||
echo "put together the outs for final coverage resolution"
|
||||
./gocovmerge ../integration/coverage/system.out ../replication/coverage/replication.out ../sso-integration/coverage/sso-system.out ../restapi/coverage/coverage.out ../pkg/coverage/coverage-pkg.out > all.out
|
||||
./gocovmerge ../integration/coverage/system.out ../replication/coverage/replication.out ../sso-integration/coverage/sso-system.out ../api/coverage/coverage.out ../pkg/coverage/coverage-pkg.out > all.out
|
||||
echo "Download mc for Ubuntu"
|
||||
wget -q https://dl.min.io/client/mc/release/linux-amd64/mc
|
||||
echo "Change the permissions to execute mc command"
|
||||
@@ -1162,6 +1116,33 @@ jobs:
|
||||
go tool cover -html=all.out -o coverage.html
|
||||
./mc cp coverage.html play/builds/${{ github.repository }}/${{ github.event.number }}/${{ github.run_id }}/ || true
|
||||
./mc cp coverage.html play/builds/${{ github.repository }}/${{ github.event.number }}/latest/ || true
|
||||
# save all other coverage
|
||||
go tool cover -html=../integration/coverage/system.out -o system.html
|
||||
./mc cp system.html play/builds/${{ github.repository }}/${{ github.event.number }}/${{ github.run_id }}/ || true
|
||||
./mc cp system.html play/builds/${{ github.repository }}/${{ github.event.number }}/latest/ || true
|
||||
./mc cp ../integration/coverage/system.out play/builds/${{ github.repository }}/${{ github.event.number }}/${{ github.run_id }}/ || true
|
||||
./mc cp ../integration/coverage/system.out play/builds/${{ github.repository }}/${{ github.event.number }}/latest/ || true
|
||||
go tool cover -html=../replication/coverage/replication.out -o replication.html
|
||||
./mc cp replication.html play/builds/${{ github.repository }}/${{ github.event.number }}/${{ github.run_id }}/ || true
|
||||
./mc cp replication.html play/builds/${{ github.repository }}/${{ github.event.number }}/latest/ || true
|
||||
./mc cp ../replication/coverage/replication.out play/builds/${{ github.repository }}/${{ github.event.number }}/${{ github.run_id }}/ || true
|
||||
./mc cp ../replication/coverage/replication.out play/builds/${{ github.repository }}/${{ github.event.number }}/latest/ || true
|
||||
go tool cover -html=../sso-integration/coverage/sso-system.out -o sso-system.html
|
||||
./mc cp sso-system.html play/builds/${{ github.repository }}/${{ github.event.number }}/${{ github.run_id }}/ || true
|
||||
./mc cp sso-system.html play/builds/${{ github.repository }}/${{ github.event.number }}/latest/ || true
|
||||
./mc cp ../sso-integration/coverage/sso-system.out play/builds/${{ github.repository }}/${{ github.event.number }}/${{ github.run_id }}/ || true
|
||||
./mc cp ../sso-integration/coverage/sso-system.out play/builds/${{ github.repository }}/${{ github.event.number }}/latest/ || true
|
||||
go tool cover -html=../api/coverage/coverage.out -o coverage.html
|
||||
./mc cp coverage.html play/builds/${{ github.repository }}/${{ github.event.number }}/${{ github.run_id }}/ || true
|
||||
./mc cp coverage.html play/builds/${{ github.repository }}/${{ github.event.number }}/latest/ || true
|
||||
./mc cp ../api/coverage/coverage.out play/builds/${{ github.repository }}/${{ github.event.number }}/${{ github.run_id }}/ || true
|
||||
./mc cp ../api/coverage/coverage.out play/builds/${{ github.repository }}/${{ github.event.number }}/latest/ || true
|
||||
go tool cover -html=../pkg/coverage/coverage-pkg.out -o coverage-pkg.html
|
||||
./mc cp coverage-pkg.html play/builds/${{ github.repository }}/${{ github.event.number }}/${{ github.run_id }}/ || true
|
||||
./mc cp coverage-pkg.html play/builds/${{ github.repository }}/${{ github.event.number }}/latest/ || true
|
||||
./mc cp ../pkg/coverage/coverage-pkg.out play/builds/${{ github.repository }}/${{ github.event.number }}/${{ github.run_id }}/ || true
|
||||
./mc cp ../pkg/coverage/coverage-pkg.out play/builds/${{ github.repository }}/${{ github.event.number }}/latest/ || true
|
||||
./mc anonymous set public play/builds
|
||||
else
|
||||
echo "Play is down, please report it on hack channel, no coverage is going to be uploaded!!!"
|
||||
fi
|
||||
@@ -1169,7 +1150,7 @@ jobs:
|
||||
go tool cover -func=all.out | grep total > tmp2
|
||||
result=`cat tmp2 | awk 'END {print $3}'`
|
||||
result=${result%\%}
|
||||
threshold=71.4
|
||||
threshold=65.0
|
||||
echo "Result:"
|
||||
echo "$result%"
|
||||
if (( $(echo "$result >= $threshold" |bc -l) )); then
|
||||
@@ -1184,8 +1165,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
os: [ubuntu-latest]
|
||||
go-version: [ 1.21.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
@@ -1196,21 +1177,21 @@ jobs:
|
||||
with:
|
||||
node-version: ${{ env.NVMRC }}
|
||||
cache: "yarn"
|
||||
cache-dependency-path: portal-ui/yarn.lock
|
||||
cache-dependency-path: web-app/yarn.lock
|
||||
- uses: actions/cache@v3
|
||||
id: assets-cache-istanbul-coverage
|
||||
name: Assets Cache Istanbul Coverage
|
||||
with:
|
||||
path: |
|
||||
./portal-ui/build/
|
||||
./web-app/build/
|
||||
key: ${{ runner.os }}-assets-istanbul-coverage-${{ github.run_id }}
|
||||
- name: Install Dependencies
|
||||
working-directory: ./portal-ui
|
||||
working-directory: ./web-app
|
||||
continue-on-error: false
|
||||
run: |
|
||||
yarn install --frozen-lockfile --immutable
|
||||
- name: Check for Warnings in build output
|
||||
working-directory: ./portal-ui
|
||||
working-directory: ./web-app
|
||||
continue-on-error: false
|
||||
run: |
|
||||
./check-warnings-istanbul-coverage.sh
|
||||
@@ -1225,8 +1206,8 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
os: [ubuntu-latest]
|
||||
go-version: [ 1.21.x ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
@@ -1248,7 +1229,7 @@ jobs:
|
||||
name: Assets Cache Istanbul Coverage
|
||||
with:
|
||||
path: |
|
||||
./portal-ui/build/
|
||||
./web-app/build/
|
||||
key: ${{ runner.os }}-assets-istanbul-coverage-${{ github.run_id }}
|
||||
- name: Build on ${{ matrix.os }}
|
||||
env:
|
||||
@@ -1266,12 +1247,12 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 18
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
echo "Install dependencies"
|
||||
cd $GITHUB_WORKSPACE/portal-ui
|
||||
cd $GITHUB_WORKSPACE/web-app
|
||||
yarn add -D playwright
|
||||
yarn add -D babel-plugin-istanbul
|
||||
yarn add -D nyc
|
||||
@@ -1299,7 +1280,7 @@ jobs:
|
||||
- name: Run Playwright tests
|
||||
run: |
|
||||
echo "Run tests under playwright folder only"
|
||||
cd $GITHUB_WORKSPACE/portal-ui
|
||||
cd $GITHUB_WORKSPACE/web-app
|
||||
yarn remove playwright
|
||||
yarn add --dev @playwright/test
|
||||
echo "npx playwright test"
|
||||
|
||||
10
.github/workflows/vulncheck.yaml
vendored
10
.github/workflows/vulncheck.yaml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.21.1
|
||||
go-version: 1.21.7
|
||||
check-latest: true
|
||||
- name: Get official govulncheck
|
||||
run: go install golang.org/x/vuln/cmd/govulncheck@latest
|
||||
@@ -36,8 +36,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.1]
|
||||
os: [ubuntu-latest]
|
||||
go-version: [ 1.21.7 ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
@@ -45,9 +45,9 @@ jobs:
|
||||
with:
|
||||
node-version: ${{ env.NVMRC }}
|
||||
cache: "yarn"
|
||||
cache-dependency-path: portal-ui/yarn.lock
|
||||
cache-dependency-path: web-app/yarn.lock
|
||||
- name: Checks for known security issues with the installed packages
|
||||
working-directory: ./portal-ui
|
||||
working-directory: ./web-app
|
||||
continue-on-error: false
|
||||
run: |
|
||||
yarn audit --groups dependencies
|
||||
|
||||
10
.gitignore
vendored
10
.gitignore
vendored
@@ -1,12 +1,12 @@
|
||||
# Playwright Data
|
||||
portal-ui/storage/
|
||||
portal-ui/playwright/.auth/admin.json
|
||||
web-app/storage/
|
||||
web-app/playwright/.auth/admin.json
|
||||
|
||||
# Report from Playwright
|
||||
portal-ui/playwright-report/
|
||||
web-app/playwright-report/
|
||||
|
||||
# Coverage from Playwright
|
||||
portal-ui/.nyc_output/
|
||||
web-app/.nyc_output/
|
||||
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
@@ -37,7 +37,7 @@ dist/
|
||||
|
||||
# Ignore node_modules
|
||||
|
||||
portal-ui/node_modules/
|
||||
web-app/node_modules/
|
||||
|
||||
# Ignore tls cert and key
|
||||
private.key
|
||||
|
||||
@@ -46,4 +46,4 @@ run:
|
||||
skip-dirs:
|
||||
- pkg/clientgen
|
||||
- pkg/apis/networking.gke.io
|
||||
- restapi/operations
|
||||
- api/operations
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
# Common large paths
|
||||
node_modules/
|
||||
portal-ui/node_modules/
|
||||
web-app/node_modules/
|
||||
build/
|
||||
dist/
|
||||
.idea/
|
||||
|
||||
103
CHANGELOG.md
103
CHANGELOG.md
@@ -2,6 +2,108 @@
|
||||
|
||||
# Changelog
|
||||
|
||||
## Release v0.46.0
|
||||
|
||||
Features:
|
||||
|
||||
- Added latest help content to forms
|
||||
|
||||
Bug Fix:
|
||||
|
||||
- Disabled Create User button in certain policy cases
|
||||
- Fixed an issue with Logout request
|
||||
- Upgraded project dependencies
|
||||
|
||||
## Release v0.45.0
|
||||
|
||||
Deprecated:
|
||||
|
||||
- Deprecated Heal / Drives page
|
||||
|
||||
Features:
|
||||
|
||||
- Updated tines on menus & pages
|
||||
|
||||
Bug Fix:
|
||||
|
||||
- Upgraded project dependencies
|
||||
|
||||
## Release v0.44.0
|
||||
|
||||
Bug Fix:
|
||||
|
||||
- Upgraded project dependencies
|
||||
- Fixed events icons not loading in subpaths
|
||||
|
||||
## Release v0.43.1
|
||||
|
||||
Bug Fix:
|
||||
|
||||
- Update Share Object UI to reflect maximum expiration time in UI
|
||||
|
||||
## Release v0.43.0
|
||||
|
||||
Features:
|
||||
|
||||
- Updated PDF preview method
|
||||
|
||||
Bug Fix:
|
||||
|
||||
- Fixed vulnerabilities
|
||||
- Prevented non-necessary metadata calls in object browser
|
||||
|
||||
## Release v0.42.2
|
||||
|
||||
Bug Fix:
|
||||
|
||||
- Hidden Prometheus metrics if URL is empty
|
||||
|
||||
## Release v0.42.1
|
||||
|
||||
Bug Fix:
|
||||
|
||||
- Reset go version to 1.19
|
||||
|
||||
## Release v0.42.0
|
||||
|
||||
Features:
|
||||
|
||||
- Introducing Dark Mode
|
||||
|
||||
Bug Fix:
|
||||
|
||||
- Fixed vulnerabilities
|
||||
- Changes on Upload and Delete object urls
|
||||
- Fixed blocking subpath creation if not enough permissions
|
||||
- Removed share object option at prefix level
|
||||
- Updated allowed actions for a deleted object
|
||||
|
||||
## Release v0.41.0
|
||||
|
||||
Features:
|
||||
|
||||
- Updated pages to use mds components
|
||||
- support for resolving IPv4/IPv6
|
||||
|
||||
Bug Fix:
|
||||
|
||||
- Remove cache for ClientIP
|
||||
- Fixed override environment variables display in settings page
|
||||
- Fixed daylight savings time support in share modal
|
||||
|
||||
## Release v0.40.0
|
||||
|
||||
Features:
|
||||
|
||||
- Updated OpenID page
|
||||
- Added New bucket event types support
|
||||
|
||||
Bug Fix:
|
||||
|
||||
- Fixed crash in access keys page
|
||||
- Fixed AuditLog filters issue
|
||||
- Fixed multiple issues with Object Browser
|
||||
|
||||
## Release v0.39.0
|
||||
|
||||
Features:
|
||||
@@ -9,7 +111,6 @@ Features:
|
||||
- Migrated metrics page to mds
|
||||
- Migrated Register page to mds
|
||||
|
||||
|
||||
Bug Fix:
|
||||
|
||||
- Fixed LDAP configuration page issues
|
||||
|
||||
@@ -4,56 +4,80 @@ This is a REST portal server created using [go-swagger](https://github.com/go-sw
|
||||
|
||||
The API handlers are created using a YAML definition located in `swagger.YAML`.
|
||||
|
||||
To add new api, the YAML file needs to be updated with all the desired apis using the [Swagger Basic Structure](https://swagger.io/docs/specification/2-0/basic-structure/), this includes paths, parameters, definitions, tags, etc.
|
||||
To add new api, the YAML file needs to be updated with all the desired apis using
|
||||
the [Swagger Basic Structure](https://swagger.io/docs/specification/2-0/basic-structure/), this includes paths,
|
||||
parameters, definitions, tags, etc.
|
||||
|
||||
## Generate server from YAML
|
||||
|
||||
Once the YAML file is ready we can autogenerate the code needed for the new api by just running:
|
||||
|
||||
Validate it:
|
||||
|
||||
```
|
||||
swagger validate ./swagger.yml
|
||||
```
|
||||
|
||||
Update server code:
|
||||
|
||||
```
|
||||
make swagger-gen
|
||||
```
|
||||
|
||||
This will update all the necessary code.
|
||||
|
||||
`./restapi/configure_console.go` is a file that contains the handlers to be used by the application, here is the only place where we need to update our code to support the new apis. This file is not affected when running the swagger generator and it is safe to edit.
|
||||
`./api/configure_console.go` is a file that contains the handlers to be used by the application, here is the only place
|
||||
where we need to update our code to support the new apis. This file is not affected when running the swagger generator
|
||||
and it is safe to edit.
|
||||
|
||||
## Unit Tests
|
||||
`./restapi/handlers_test.go` needs to be updated with the proper tests for the new api.
|
||||
|
||||
`./api/handlers_test.go` needs to be updated with the proper tests for the new api.
|
||||
|
||||
To run tests:
|
||||
|
||||
```
|
||||
go test ./restapi
|
||||
go test ./api
|
||||
```
|
||||
|
||||
## Commit changes
|
||||
After verification, commit your changes. This is a [great post](https://chris.beams.io/posts/git-commit/) on how to write useful commit messages
|
||||
|
||||
After verification, commit your changes. This is a [great post](https://chris.beams.io/posts/git-commit/) on how to
|
||||
write useful commit messages
|
||||
|
||||
```
|
||||
$ git commit -am 'Add some feature'
|
||||
```
|
||||
|
||||
### Push to the branch
|
||||
|
||||
Push your locally committed changes to the remote origin (your fork)
|
||||
|
||||
```
|
||||
$ git push origin my-new-feature
|
||||
```
|
||||
|
||||
### Create a Pull Request
|
||||
Pull requests can be created via GitHub. Refer to [this document](https://help.github.com/articles/creating-a-pull-request/) for detailed steps on how to create a pull request. After a Pull Request gets peer reviewed and approved, it will be merged.
|
||||
|
||||
Pull requests can be created via GitHub. Refer
|
||||
to [this document](https://help.github.com/articles/creating-a-pull-request/) for detailed steps on how to create a pull
|
||||
request. After a Pull Request gets peer reviewed and approved, it will be merged.
|
||||
|
||||
## FAQs
|
||||
|
||||
### How does ``console`` manages dependencies?
|
||||
|
||||
``MinIO`` uses `go mod` to manage its dependencies.
|
||||
|
||||
- Run `go get foo/bar` in the source folder to add the dependency to `go.mod` file.
|
||||
|
||||
To remove a dependency
|
||||
|
||||
- Edit your code and remove the import reference.
|
||||
- Run `go mod tidy` in the source folder to remove dependency from `go.mod` file.
|
||||
|
||||
### What are the coding guidelines for console?
|
||||
``console`` is fully conformant with Golang style. Refer: [Effective Go](https://github.com/golang/go/wiki/CodeReviewComments) article from Golang project. If you observe offending code, please feel free to send a pull request or ping us on [Slack](https://slack.min.io).
|
||||
|
||||
``console`` is fully conformant with Golang style.
|
||||
Refer: [Effective Go](https://github.com/golang/go/wiki/CodeReviewComments) article from Golang project. If you observe
|
||||
offending code, please feel free to send a pull request or ping us on [Slack](https://slack.min.io).
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
# Developing MinIO Console
|
||||
|
||||
The MinIO Console requires the [MinIO Server](https://github.com/minio/minio). For development purposes, you also need to run both the MinIO Console web app and the MinIO Console server.
|
||||
The MinIO Console requires the [MinIO Server](https://github.com/minio/minio). For development purposes, you also need
|
||||
to run both the MinIO Console web app and the MinIO Console server.
|
||||
|
||||
## Running MinIO Console server
|
||||
|
||||
Build the server in the main folder by running:
|
||||
|
||||
```
|
||||
make
|
||||
```
|
||||
> Note: If it's the first time running the server, you might need to run `go mod tidy` to ensure you have all modules required.
|
||||
To start the server run:
|
||||
|
||||
> Note: If it's the first time running the server, you might need to run `go mod tidy` to ensure you have all modules
|
||||
> required.
|
||||
> To start the server run:
|
||||
|
||||
```
|
||||
CONSOLE_ACCESS_KEY=<your-access-key>
|
||||
CONSOLE_SECRET_KEY=<your-secret-key>
|
||||
@@ -19,8 +24,8 @@ CONSOLE_DEV_MODE=on
|
||||
```
|
||||
|
||||
## Running MinIO Console web app
|
||||
Refer to `/portal-ui` [instructions](/portal-ui/README.md) to run the web app locally.
|
||||
|
||||
Refer to `/web-app` [instructions](/web-app/README.md) to run the web app locally.
|
||||
|
||||
# Building with MinIO
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@ FROM node:$NODE_VERSION as uilayer
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY ./portal-ui/package.json ./
|
||||
COPY ./portal-ui/yarn.lock ./
|
||||
COPY ./web-app/package.json ./
|
||||
COPY ./web-app/yarn.lock ./
|
||||
RUN yarn install
|
||||
|
||||
COPY ./portal-ui .
|
||||
COPY ./web-app .
|
||||
|
||||
RUN make build-static
|
||||
|
||||
@@ -29,7 +29,7 @@ WORKDIR /go/src/github.com/minio/console/
|
||||
|
||||
ENV CGO_ENABLED=0
|
||||
|
||||
COPY --from=uilayer /app/build /go/src/github.com/minio/console/portal-ui/build
|
||||
COPY --from=uilayer /app/build /go/src/github.com/minio/console/web-app/build
|
||||
RUN go build --tags=kqueue,operator -ldflags "-w -s" -a -o console ./cmd/console
|
||||
|
||||
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.7
|
||||
|
||||
@@ -3,11 +3,11 @@ FROM node:$NODE_VERSION as uilayer
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY ./portal-ui/package.json ./
|
||||
COPY ./portal-ui/yarn.lock ./
|
||||
COPY ./web-app/package.json ./
|
||||
COPY ./web-app/yarn.lock ./
|
||||
RUN yarn install
|
||||
|
||||
COPY ./portal-ui .
|
||||
COPY ./web-app .
|
||||
|
||||
RUN yarn install && make build-static
|
||||
|
||||
|
||||
@@ -1,17 +1,10 @@
|
||||
FROM --platform=linux/amd64 registry.access.redhat.com/ubi8/ubi-minimal:8.7 as build
|
||||
FROM registry.access.redhat.com/ubi9/ubi-minimal:9.2 as build
|
||||
|
||||
RUN microdnf update --nodocs && microdnf install ca-certificates --nodocs
|
||||
RUN curl -s -q https://raw.githubusercontent.com/minio/kes/master/LICENSE -o LICENSE
|
||||
RUN curl -s -q https://raw.githubusercontent.com/minio/kes/master/CREDITS -o CREDITS
|
||||
|
||||
FROM registry.access.redhat.com/ubi8/ubi-micro:8.7
|
||||
FROM registry.access.redhat.com/ubi9/ubi-micro:9.2
|
||||
|
||||
# On RHEL the certificate bundle is located at:
|
||||
# - /etc/pki/tls/certs/ca-bundle.crt (RHEL 6)
|
||||
# - /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem (RHEL 7)
|
||||
COPY --from=build /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem /etc/pki/ca-trust/extracted/pem/
|
||||
COPY --from=build LICENSE /LICENSE
|
||||
COPY --from=build CREDITS /CREDITS
|
||||
ARG TAG
|
||||
|
||||
LABEL name="MinIO" \
|
||||
vendor="MinIO Inc <dev@min.io>" \
|
||||
@@ -21,7 +14,14 @@ LABEL name="MinIO" \
|
||||
summary="A graphical user interface for MinIO" \
|
||||
description="MinIO object storage is fundamentally different. Designed for performance and the S3 API, it is 100% open-source. MinIO is ideal for large, private cloud environments with stringent security requirements and delivers mission-critical availability across a diverse range of workloads."
|
||||
|
||||
EXPOSE 9090
|
||||
# On RHEL the certificate bundle is located at:
|
||||
# - /etc/pki/tls/certs/ca-bundle.crt (RHEL 6)
|
||||
# - /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem (RHEL 7)
|
||||
COPY --from=build /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem /etc/pki/ca-trust/extracted/pem/
|
||||
COPY LICENSE /LICENSE
|
||||
COPY CREDITS /CREDITS
|
||||
COPY console /console
|
||||
|
||||
EXPOSE 9090
|
||||
|
||||
ENTRYPOINT ["/console"]
|
||||
|
||||
49
Makefile
49
Makefile
@@ -48,18 +48,19 @@ apply-gofmt:
|
||||
clean-swagger:
|
||||
@echo "cleaning"
|
||||
@rm -rf models
|
||||
@rm -rf restapi/operations
|
||||
@rm -rf api/operations
|
||||
|
||||
swagger-console:
|
||||
@echo "Generating swagger server code from yaml"
|
||||
@swagger generate server -A console --main-package=management --server-package=restapi --exclude-main -P models.Principal -f ./swagger.yml -r NOTICE
|
||||
@swagger generate server -A console --main-package=management --server-package=api --exclude-main -P models.Principal -f ./swagger.yml -r NOTICE
|
||||
@echo "Generating typescript api"
|
||||
@npx swagger-typescript-api -p ./swagger.yml -o ./portal-ui/src/api -n consoleApi.ts
|
||||
@npx swagger-typescript-api -p ./swagger.yml -o ./web-app/src/api -n consoleApi.ts
|
||||
@git restore api/server.go
|
||||
|
||||
|
||||
assets:
|
||||
@(if [ -f "${NVM_DIR}/nvm.sh" ]; then \. "${NVM_DIR}/nvm.sh" && nvm install && nvm use && npm install -g yarn ; fi &&\
|
||||
cd portal-ui; yarn install --prefer-offline; make build-static; yarn prettier --write . --loglevel warn; cd ..)
|
||||
cd web-app; yarn install --prefer-offline; make build-static; yarn prettier --write . --loglevel warn; cd ..)
|
||||
|
||||
test-integration:
|
||||
@(docker stop pgsqlcontainer || true)
|
||||
@@ -77,7 +78,7 @@ test-integration:
|
||||
@echo "Postgres"
|
||||
@(docker run --net=mynet123 --ip=173.18.0.4 --name pgsqlcontainer --rm -p 5432:5432 -e POSTGRES_PASSWORD=password -d postgres && sleep 5)
|
||||
@echo "execute test and get coverage for test-integration:"
|
||||
@(cd integration && go test -coverpkg=../restapi -c -tags testrunmain . && mkdir -p coverage && ./integration.test -test.v -test.run "^Test*" -test.coverprofile=coverage/system.out)
|
||||
@(cd integration && go test -coverpkg=../api -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 stop minio2)
|
||||
@@ -125,7 +126,7 @@ test-replication:
|
||||
$(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)
|
||||
@(cd replication && go test -coverpkg=../api -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)
|
||||
@@ -179,45 +180,45 @@ test-sso-integration:
|
||||
@echo "add python module"
|
||||
@(pip3 install bs4)
|
||||
@echo "Executing the test:"
|
||||
@(cd sso-integration && go test -coverpkg=../restapi -c -tags testrunmain . && mkdir -p coverage && ./sso-integration.test -test.v -test.run "^Test*" -test.coverprofile=coverage/sso-system.out)
|
||||
@(cd sso-integration && go test -coverpkg=../api -c -tags testrunmain . && mkdir -p coverage && ./sso-integration.test -test.v -test.run "^Test*" -test.coverprofile=coverage/sso-system.out)
|
||||
|
||||
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 "portal-ui/tests/permissions-1/")
|
||||
@(env bash $(PWD)/web-app/tests/scripts/permissions.sh "web-app/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/")
|
||||
@(env bash $(PWD)/web-app/tests/scripts/permissions.sh "web-app/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/")
|
||||
@(env bash $(PWD)/web-app/tests/scripts/permissions.sh "web-app/tests/permissions-3/")
|
||||
@(docker stop minio)
|
||||
|
||||
test-permissions-4:
|
||||
@(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-4/")
|
||||
@(env bash $(PWD)/web-app/tests/scripts/permissions.sh "web-app/tests/permissions-4/")
|
||||
@(docker stop minio)
|
||||
|
||||
test-permissions-5:
|
||||
@(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-5/")
|
||||
@(env bash $(PWD)/web-app/tests/scripts/permissions.sh "web-app/tests/permissions-5/")
|
||||
@(docker stop minio)
|
||||
|
||||
test-permissions-6:
|
||||
@(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-6/")
|
||||
@(env bash $(PWD)/web-app/tests/scripts/permissions.sh "web-app/tests/permissions-6/")
|
||||
@(docker stop minio)
|
||||
|
||||
test-permissions-7:
|
||||
@(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-7/")
|
||||
@(env bash $(PWD)/web-app/tests/scripts/permissions.sh "web-app/tests/permissions-7/")
|
||||
@(docker stop minio)
|
||||
|
||||
test-apply-permissions:
|
||||
@(env bash $(PWD)/portal-ui/tests/scripts/initialize-env.sh)
|
||||
@(env bash $(PWD)/web-app/tests/scripts/initialize-env.sh)
|
||||
|
||||
test-start-docker-minio:
|
||||
@(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})
|
||||
@@ -226,7 +227,7 @@ initialize-permissions: test-start-docker-minio test-apply-permissions
|
||||
@echo "Done initializing permissions test"
|
||||
|
||||
cleanup-permissions:
|
||||
@(env bash $(PWD)/portal-ui/tests/scripts/cleanup-env.sh)
|
||||
@(env bash $(PWD)/web-app/tests/scripts/cleanup-env.sh)
|
||||
@(docker stop minio)
|
||||
|
||||
initialize-docker-network:
|
||||
@@ -245,7 +246,7 @@ test-start-docker-nginx-w-subpath:
|
||||
--network host \
|
||||
-d --rm \
|
||||
--add-host=host.docker.internal:host-gateway \
|
||||
-v ./portal-ui/tests/subpath-nginx/nginx.conf:/etc/nginx/nginx.conf \
|
||||
-v ./web-app/tests/subpath-nginx/nginx.conf:/etc/nginx/nginx.conf \
|
||||
--name test-nginx nginx)
|
||||
|
||||
test-initialize-minio-nginx: test-start-docker-minio-w-redirect-url test-start-docker-nginx-w-subpath
|
||||
@@ -253,17 +254,23 @@ test-initialize-minio-nginx: test-start-docker-minio-w-redirect-url test-start-d
|
||||
cleanup-minio-nginx:
|
||||
@(docker stop minio test-nginx & docker network rm test-network)
|
||||
|
||||
# https://stackoverflow.com/questions/19200235/golang-tests-in-sub-directory
|
||||
# Note: go test ./... will run tests on the current folder and all subfolders.
|
||||
# This is needed because tests can be in the folder or sub-folder(s), let's include them all please!.
|
||||
test:
|
||||
@echo "execute test and get coverage"
|
||||
@(cd restapi && mkdir coverage && GO111MODULE=on go test -test.v -coverprofile=coverage/coverage.out)
|
||||
@(cd api && mkdir -p coverage && GO111MODULE=on go test ./... -test.v -coverprofile=coverage/coverage.out)
|
||||
|
||||
|
||||
# https://stackoverflow.com/questions/19200235/golang-tests-in-sub-directory
|
||||
# Note: go test ./... will run tests on the current folder and all subfolders.
|
||||
# This is since tests in pkg folder are in subfolders and were not executed.
|
||||
test-pkg:
|
||||
@echo "execute test and get coverage"
|
||||
@(cd pkg && mkdir coverage && GO111MODULE=on go test -test.v -coverprofile=coverage/coverage-pkg.out)
|
||||
@(cd pkg && mkdir -p 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)
|
||||
@(GO111MODULE=on go test -v -coverprofile=coverage.out github.com/minio/console/api/... && go tool cover -html=coverage.out && open coverage.html)
|
||||
|
||||
clean:
|
||||
@echo "Cleaning up all the generated files"
|
||||
@@ -278,4 +285,4 @@ release: swagger-gen
|
||||
@echo "Generating Release: $(RELEASE)"
|
||||
@make assets
|
||||
@git add -u .
|
||||
@git add portal-ui/build/
|
||||
@git add web-app/build/
|
||||
|
||||
49
README.md
49
README.md
@@ -12,53 +12,30 @@ A graphical user interface for [MinIO](https://github.com/minio/minio)
|
||||
**Table of Contents**
|
||||
|
||||
- [MinIO Console](#minio-console)
|
||||
- [Install](#install)
|
||||
- [Binary Releases](#binary-releases)
|
||||
- [Docker](#docker)
|
||||
- [Build from source](#build-from-source)
|
||||
- [Setup](#setup)
|
||||
- [1. Create a user `console` using `mc`](#1-create-a-user-console-using-mc)
|
||||
- [2. Create a policy for `console` with admin access to all resources (for testing)](#2-create-a-policy-for-console-with-admin-access-to-all-resources-for-testing)
|
||||
- [3. Set the policy for the new `console` user](#3-set-the-policy-for-the-new-console-user)
|
||||
- [Start Console service:](#start-console-service)
|
||||
- [Start Console service with TLS:](#start-console-service-with-tls)
|
||||
- [Connect Console to a Minio using TLS and a self-signed certificate](#connect-console-to-a-minio-using-tls-and-a-self-signed-certificate)
|
||||
- [Install](#install)
|
||||
- [Build from source](#build-from-source)
|
||||
- [Setup](#setup)
|
||||
- [1. Create a user `console` using `mc`](#1-create-a-user-console-using-mc)
|
||||
- [2. Create a policy for `console` with admin access to all resources (for testing)](#2-create-a-policy-for-console-with-admin-access-to-all-resources-for-testing)
|
||||
- [3. Set the policy for the new `console` user](#3-set-the-policy-for-the-new-console-user)
|
||||
- [Start Console service:](#start-console-service)
|
||||
- [Start Console service with TLS:](#start-console-service-with-tls)
|
||||
- [Connect Console to a Minio using TLS and a self-signed certificate](#connect-console-to-a-minio-using-tls-and-a-self-signed-certificate)
|
||||
- [Contribute to console Project](#contribute-to-console-project)
|
||||
|
||||
<!-- markdown-toc end -->
|
||||
|
||||
## Install
|
||||
|
||||
### Binary Releases
|
||||
MinIO Console is a library that provides a management and browser UI overlay for the MinIO Server.
|
||||
The standalone binary installation path has been removed.
|
||||
|
||||
| OS | ARCH | Binary |
|
||||
|:-------:|:-------:|:----------------------------------------------------------------------------------------------------:|
|
||||
| Linux | amd64 | [linux-amd64](https://github.com/minio/console/releases/latest/download/console-linux-amd64) |
|
||||
| Linux | arm64 | [linux-arm64](https://github.com/minio/console/releases/latest/download/console-linux-arm64) |
|
||||
| Linux | ppc64le | [linux-ppc64le](https://github.com/minio/console/releases/latest/download/console-linux-ppc64le) |
|
||||
| Linux | s390x | [linux-s390x](https://github.com/minio/console/releases/latest/download/console-linux-s390x) |
|
||||
| Apple | amd64 | [darwin-amd64](https://github.com/minio/console/releases/latest/download/console-darwin-amd64) |
|
||||
| Windows | amd64 | [windows-amd64](https://github.com/minio/console/releases/latest/download/console-windows-amd64.exe) |
|
||||
|
||||
You can also verify the binary with [minisign](https://jedisct1.github.io/minisign/) by downloading the
|
||||
corresponding [`.minisig`](https://github.com/minio/console/releases/latest) signature file. Then run:
|
||||
|
||||
```
|
||||
minisign -Vm console-<OS>-<ARCH> -P RWTx5Zr1tiHQLwG9keckT0c45M3AGeHD6IvimQHpyRywVWGbP1aVSGav
|
||||
```
|
||||
|
||||
### Docker
|
||||
|
||||
Pull the latest release via:
|
||||
|
||||
```
|
||||
docker pull minio/console
|
||||
```
|
||||
In case a Console standalone binary is needed, it can be generated by building this package from source as follows:
|
||||
|
||||
### Build from source
|
||||
|
||||
> You will need a working Go environment. Therefore, please follow [How to install Go](https://golang.org/doc/install).
|
||||
> Minimum version required is go1.19
|
||||
> Minimum version required is go1.21
|
||||
|
||||
```
|
||||
go install github.com/minio/console/cmd/console@latest
|
||||
|
||||
@@ -14,16 +14,16 @@
|
||||
// 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 restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
systemApi "github.com/minio/console/restapi/operations/system"
|
||||
systemApi "github.com/minio/console/api/operations/system"
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/minio/console/api/operations"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
)
|
||||
|
||||
func registerAdminArnsHandlers(api *operations.ConsoleAPI) {
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -25,11 +25,11 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/minio/console/api/operations/system"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations/system"
|
||||
|
||||
"github.com/go-openapi/loads"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
"github.com/minio/console/api/operations"
|
||||
"github.com/minio/madmin-go/v3"
|
||||
|
||||
asrt "github.com/stretchr/testify/assert"
|
||||
@@ -39,7 +39,7 @@ func TestArnsList(t *testing.T) {
|
||||
assert := asrt.New(t)
|
||||
adminClient := AdminClientMock{}
|
||||
// Test-1 : getArns() returns proper arn list
|
||||
MinioServerInfoMock = func(ctx context.Context) (madmin.InfoMessage, error) {
|
||||
MinioServerInfoMock = func(_ context.Context) (madmin.InfoMessage, error) {
|
||||
return madmin.InfoMessage{
|
||||
SQSARN: []string{"uno"},
|
||||
}, nil
|
||||
@@ -54,7 +54,7 @@ func TestArnsList(t *testing.T) {
|
||||
assert.Nil(err, "Error should have been nil")
|
||||
|
||||
// Test-2 : getArns(ctx) fails for whatever reason
|
||||
MinioServerInfoMock = func(ctx context.Context) (madmin.InfoMessage, error) {
|
||||
MinioServerInfoMock = func(_ context.Context) (madmin.InfoMessage, error) {
|
||||
return madmin.InfoMessage{}, errors.New("some reason")
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -80,7 +80,7 @@ var (
|
||||
minioSetUserStatusMock func(accessKey string, status madmin.AccountStatus) error
|
||||
|
||||
minioAccountInfoMock func(ctx context.Context) (madmin.AccountInfo, error)
|
||||
minioAddServiceAccountMock func(ctx context.Context, policy *iampolicy.Policy, user string, accessKey string, secretKey string) (madmin.Credentials, error)
|
||||
minioAddServiceAccountMock func(ctx context.Context, policy *iampolicy.Policy, user string, accessKey string, secretKey string, description string, name string, expiry *time.Time, status string) (madmin.Credentials, error)
|
||||
minioListServiceAccountsMock func(ctx context.Context, user string) (madmin.ListServiceAccountsResp, error)
|
||||
minioDeleteServiceAccountMock func(ctx context.Context, serviceAccount string) error
|
||||
minioInfoServiceAccountMock func(ctx context.Context, serviceAccount string) (madmin.InfoServiceAccountResp, error)
|
||||
@@ -317,11 +317,11 @@ func (ac AdminClientMock) getSiteReplicationInfo(ctx context.Context) (*madmin.S
|
||||
return getSiteReplicationInfo(ctx)
|
||||
}
|
||||
|
||||
func (ac AdminClientMock) addSiteReplicationInfo(ctx context.Context, sites []madmin.PeerSite) (*madmin.ReplicateAddStatus, error) {
|
||||
func (ac AdminClientMock) addSiteReplicationInfo(ctx context.Context, sites []madmin.PeerSite, _ madmin.SRAddOptions) (*madmin.ReplicateAddStatus, error) {
|
||||
return addSiteReplicationInfo(ctx, sites)
|
||||
}
|
||||
|
||||
func (ac AdminClientMock) editSiteReplicationInfo(ctx context.Context, site madmin.PeerInfo) (*madmin.ReplicateEditStatus, error) {
|
||||
func (ac AdminClientMock) editSiteReplicationInfo(ctx context.Context, site madmin.PeerInfo, _ madmin.SREditOptions) (*madmin.ReplicateEditStatus, error) {
|
||||
return editSiteReplicationInfo(ctx, site)
|
||||
}
|
||||
|
||||
@@ -377,8 +377,8 @@ func (ac AdminClientMock) AccountInfo(ctx context.Context) (madmin.AccountInfo,
|
||||
return minioAccountInfoMock(ctx)
|
||||
}
|
||||
|
||||
func (ac AdminClientMock) addServiceAccount(ctx context.Context, policy *iampolicy.Policy, user string, accessKey string, secretKey string) (madmin.Credentials, error) {
|
||||
return minioAddServiceAccountMock(ctx, policy, user, accessKey, secretKey)
|
||||
func (ac AdminClientMock) addServiceAccount(ctx context.Context, policy *iampolicy.Policy, user string, accessKey string, secretKey string, description string, name string, expiry *time.Time, status string) (madmin.Credentials, error) {
|
||||
return minioAddServiceAccountMock(ctx, policy, user, accessKey, secretKey, description, name, expiry, status)
|
||||
}
|
||||
|
||||
func (ac AdminClientMock) listServiceAccounts(ctx context.Context, user string) (madmin.ListServiceAccountsResp, error) {
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -24,11 +24,11 @@ import (
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/minio/console/api/operations"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
madmin "github.com/minio/madmin-go/v3"
|
||||
|
||||
cfgApi "github.com/minio/console/restapi/operations/configuration"
|
||||
cfgApi "github.com/minio/console/api/operations/configuration"
|
||||
)
|
||||
|
||||
func registerConfigHandlers(api *operations.ConsoleAPI) {
|
||||
@@ -269,7 +269,6 @@ func resetConfigResponse(session *models.Principal, params cfgApi.ResetConfigPar
|
||||
adminClient := AdminClient{Client: mAdmin}
|
||||
|
||||
err = resetConfig(ctx, adminClient, ¶ms.Name)
|
||||
|
||||
if err != nil {
|
||||
return nil, ErrorWithContext(ctx, err)
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -63,7 +63,7 @@ func TestListConfig(t *testing.T) {
|
||||
}
|
||||
expectedKeysDesc := mockConfigList.KeysHelp
|
||||
// mock function response from listConfig()
|
||||
minioHelpConfigKVMock = func(subSys, key string, envOnly bool) (madmin.Help, error) {
|
||||
minioHelpConfigKVMock = func(_, _ string, _ bool) (madmin.Help, error) {
|
||||
return mockConfigList, nil
|
||||
}
|
||||
configList, err := listConfig(adminClient)
|
||||
@@ -80,7 +80,7 @@ func TestListConfig(t *testing.T) {
|
||||
|
||||
// Test-2 : listConfig() Return error and see that the error is handled correctly and returned
|
||||
// mock function response from listConfig()
|
||||
minioHelpConfigKVMock = func(subSys, key string, envOnly bool) (madmin.Help, error) {
|
||||
minioHelpConfigKVMock = func(_, _ string, _ bool) (madmin.Help, error) {
|
||||
return madmin.Help{}, errors.New("error")
|
||||
}
|
||||
_, err = listConfig(adminClient)
|
||||
@@ -94,7 +94,7 @@ func TestSetConfig(t *testing.T) {
|
||||
adminClient := AdminClientMock{}
|
||||
function := "setConfig()"
|
||||
// mock function response from setConfig()
|
||||
minioSetConfigKVMock = func(kv string) (restart bool, err error) {
|
||||
minioSetConfigKVMock = func(_ string) (restart bool, err error) {
|
||||
return false, nil
|
||||
}
|
||||
configName := "notify_postgres"
|
||||
@@ -119,7 +119,7 @@ func TestSetConfig(t *testing.T) {
|
||||
assert.Equal(restart, false)
|
||||
|
||||
// Test-2 : setConfig() returns error, handle properly
|
||||
minioSetConfigKVMock = func(kv string) (restart bool, err error) {
|
||||
minioSetConfigKVMock = func(_ string) (restart bool, err error) {
|
||||
return false, errors.New("error")
|
||||
}
|
||||
restart, err = setConfig(ctx, adminClient, &configName, kvs)
|
||||
@@ -129,7 +129,7 @@ func TestSetConfig(t *testing.T) {
|
||||
assert.Equal(restart, false)
|
||||
|
||||
// Test-4 : setConfig() set config, need restart
|
||||
minioSetConfigKVMock = func(kv string) (restart bool, err error) {
|
||||
minioSetConfigKVMock = func(_ string) (restart bool, err error) {
|
||||
return true, nil
|
||||
}
|
||||
restart, err = setConfig(ctx, adminClient, &configName, kvs)
|
||||
@@ -144,7 +144,7 @@ func TestDelConfig(t *testing.T) {
|
||||
adminClient := AdminClientMock{}
|
||||
function := "resetConfig()"
|
||||
// mock function response from setConfig()
|
||||
minioDelConfigKVMock = func(name string) (err error) {
|
||||
minioDelConfigKVMock = func(_ string) (err error) {
|
||||
return nil
|
||||
}
|
||||
configName := "region"
|
||||
@@ -158,7 +158,7 @@ func TestDelConfig(t *testing.T) {
|
||||
}
|
||||
|
||||
// Test-2 : resetConfig() returns error, handle properly
|
||||
minioDelConfigKVMock = func(name string) (err error) {
|
||||
minioDelConfigKVMock = func(_ string) (err error) {
|
||||
return errors.New("error")
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
if got := buildConfig(tt.args.configName, tt.args.kvs); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("buildConfig() = %s, want %s", *got, *tt.want)
|
||||
}
|
||||
@@ -260,7 +260,7 @@ func Test_setConfigWithARN(t *testing.T) {
|
||||
},
|
||||
arn: "1",
|
||||
},
|
||||
mockSetConfig: func(kv string) (restart bool, err error) {
|
||||
mockSetConfig: func(_ string) (restart bool, err error) {
|
||||
return false, nil
|
||||
},
|
||||
wantErr: false,
|
||||
@@ -280,7 +280,7 @@ func Test_setConfigWithARN(t *testing.T) {
|
||||
},
|
||||
arn: "1",
|
||||
},
|
||||
mockSetConfig: func(kv string) (restart bool, err error) {
|
||||
mockSetConfig: func(_ string) (restart bool, err error) {
|
||||
return true, nil
|
||||
},
|
||||
wantErr: false,
|
||||
@@ -300,7 +300,7 @@ func Test_setConfigWithARN(t *testing.T) {
|
||||
},
|
||||
arn: "",
|
||||
},
|
||||
mockSetConfig: func(kv string) (restart bool, err error) {
|
||||
mockSetConfig: func(_ string) (restart bool, err error) {
|
||||
return false, nil
|
||||
},
|
||||
wantErr: false,
|
||||
@@ -320,7 +320,7 @@ func Test_setConfigWithARN(t *testing.T) {
|
||||
},
|
||||
arn: "",
|
||||
},
|
||||
mockSetConfig: func(kv string) (restart bool, err error) {
|
||||
mockSetConfig: func(_ string) (restart bool, err error) {
|
||||
return false, errors.New("error")
|
||||
},
|
||||
wantErr: true,
|
||||
@@ -328,7 +328,7 @@ func Test_setConfigWithARN(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
// mock function response from setConfig()
|
||||
minioSetConfigKVMock = tt.mockSetConfig
|
||||
restart, err := setConfigWithARNAccountID(tt.args.ctx, tt.args.client, tt.args.configName, tt.args.kvs, tt.args.arn)
|
||||
@@ -361,7 +361,7 @@ func Test_getConfig(t *testing.T) {
|
||||
},
|
||||
mock: func() {
|
||||
// mock function response from getConfig()
|
||||
minioGetConfigKVMock = func(key string) ([]byte, error) {
|
||||
minioGetConfigKVMock = func(_ string) ([]byte, error) {
|
||||
return []byte(`notify_postgres:_ connection_string="host=localhost dbname=minio_events user=postgres password=password port=5432 sslmode=disable" table=bucketevents`), nil
|
||||
}
|
||||
|
||||
@@ -407,7 +407,7 @@ func Test_getConfig(t *testing.T) {
|
||||
KeysHelp: configListMock,
|
||||
}
|
||||
// mock function response from listConfig()
|
||||
minioHelpConfigKVMock = func(subSys, key string, envOnly bool) (madmin.Help, error) {
|
||||
minioHelpConfigKVMock = func(_, _ string, _ bool) (madmin.Help, error) {
|
||||
return mockConfigList, nil
|
||||
}
|
||||
},
|
||||
@@ -435,7 +435,7 @@ func Test_getConfig(t *testing.T) {
|
||||
},
|
||||
mock: func() {
|
||||
// mock function response from getConfig()
|
||||
minioGetConfigKVMock = func(key string) ([]byte, error) {
|
||||
minioGetConfigKVMock = func(_ string) ([]byte, error) {
|
||||
return []byte(`notify_postgres:_`), nil
|
||||
}
|
||||
|
||||
@@ -481,7 +481,7 @@ func Test_getConfig(t *testing.T) {
|
||||
KeysHelp: configListMock,
|
||||
}
|
||||
// mock function response from listConfig()
|
||||
minioHelpConfigKVMock = func(subSys, key string, envOnly bool) (madmin.Help, error) {
|
||||
minioHelpConfigKVMock = func(_, _ string, _ bool) (madmin.Help, error) {
|
||||
return mockConfigList, nil
|
||||
}
|
||||
},
|
||||
@@ -496,7 +496,7 @@ func Test_getConfig(t *testing.T) {
|
||||
},
|
||||
mock: func() {
|
||||
// mock function response from getConfig()
|
||||
minioGetConfigKVMock = func(key string) ([]byte, error) {
|
||||
minioGetConfigKVMock = func(_ string) ([]byte, error) {
|
||||
x := make(map[string]string)
|
||||
x["x"] = "x"
|
||||
j, _ := json.Marshal(x)
|
||||
@@ -545,7 +545,7 @@ func Test_getConfig(t *testing.T) {
|
||||
KeysHelp: configListMock,
|
||||
}
|
||||
// mock function response from listConfig()
|
||||
minioHelpConfigKVMock = func(subSys, key string, envOnly bool) (madmin.Help, error) {
|
||||
minioHelpConfigKVMock = func(_, _ string, _ bool) (madmin.Help, error) {
|
||||
return mockConfigList, nil
|
||||
}
|
||||
},
|
||||
@@ -560,13 +560,13 @@ func Test_getConfig(t *testing.T) {
|
||||
},
|
||||
mock: func() {
|
||||
// mock function response from getConfig()
|
||||
minioGetConfigKVMock = func(key string) ([]byte, error) {
|
||||
minioGetConfigKVMock = func(_ string) ([]byte, error) {
|
||||
return nil, errors.New("invalid config")
|
||||
}
|
||||
|
||||
mockConfigList := madmin.Help{}
|
||||
// mock function response from listConfig()
|
||||
minioHelpConfigKVMock = func(subSys, key string, envOnly bool) (madmin.Help, error) {
|
||||
minioHelpConfigKVMock = func(_, _ string, _ bool) (madmin.Help, error) {
|
||||
return mockConfigList, nil
|
||||
}
|
||||
},
|
||||
@@ -581,11 +581,11 @@ func Test_getConfig(t *testing.T) {
|
||||
},
|
||||
mock: func() {
|
||||
// mock function response from getConfig()
|
||||
minioGetConfigKVMock = func(key string) ([]byte, error) {
|
||||
minioGetConfigKVMock = func(_ string) ([]byte, error) {
|
||||
return nil, errors.New("invalid config")
|
||||
}
|
||||
// mock function response from listConfig()
|
||||
minioHelpConfigKVMock = func(subSys, key string, envOnly bool) (madmin.Help, error) {
|
||||
minioHelpConfigKVMock = func(_, _ string, _ bool) (madmin.Help, error) {
|
||||
return madmin.Help{}, errors.New("no help")
|
||||
}
|
||||
},
|
||||
@@ -595,7 +595,7 @@ func Test_getConfig(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt.mock()
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
got, err := getConfig(context.Background(), tt.args.client, tt.args.name)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("getConfig() error = %v, wantErr %v", err, tt.wantErr)
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -40,7 +40,7 @@ func TestAdminConsoleLog(t *testing.T) {
|
||||
|
||||
// Test-1: Serve Console with no errors until Console finishes sending
|
||||
// define mock function behavior for minio server Console
|
||||
minioGetLogsMock = func(ctx context.Context, node string, lineCnt int, logKind string) <-chan madmin.LogInfo {
|
||||
minioGetLogsMock = func(_ context.Context, _ string, _ int, _ string) <-chan madmin.LogInfo {
|
||||
ch := make(chan madmin.LogInfo)
|
||||
// Only success, start a routine to start reading line by line.
|
||||
go func(ch chan<- madmin.LogInfo) {
|
||||
@@ -58,7 +58,7 @@ func TestAdminConsoleLog(t *testing.T) {
|
||||
}
|
||||
writesCount := 1
|
||||
// mock connection WriteMessage() no error
|
||||
connWriteMessageMock = func(messageType int, data []byte) error {
|
||||
connWriteMessageMock = func(_ int, data []byte) error {
|
||||
// emulate that receiver gets the message written
|
||||
var t madmin.LogInfo
|
||||
_ = json.Unmarshal(data, &t)
|
||||
@@ -82,7 +82,7 @@ func TestAdminConsoleLog(t *testing.T) {
|
||||
}
|
||||
|
||||
// Test-2: if error happens while writing, return error
|
||||
connWriteMessageMock = func(messageType int, data []byte) error {
|
||||
connWriteMessageMock = func(_ int, _ []byte) error {
|
||||
return fmt.Errorf("error on write")
|
||||
}
|
||||
if err := startConsoleLog(ctx, mockWSConn, adminClient, LogRequest{node: "", logType: "all"}); assert.Error(err) {
|
||||
@@ -91,7 +91,7 @@ func TestAdminConsoleLog(t *testing.T) {
|
||||
|
||||
// Test-3: error happens on GetLogs Minio, Console should stop
|
||||
// and error shall be returned.
|
||||
minioGetLogsMock = func(ctx context.Context, node string, lineCnt int, logKind string) <-chan madmin.LogInfo {
|
||||
minioGetLogsMock = func(_ context.Context, _ string, _ int, _ string) <-chan madmin.LogInfo {
|
||||
ch := make(chan madmin.LogInfo)
|
||||
// Only success, start a routine to start reading line by line.
|
||||
go func(ch chan<- madmin.LogInfo) {
|
||||
@@ -108,7 +108,7 @@ func TestAdminConsoleLog(t *testing.T) {
|
||||
}(ch)
|
||||
return ch
|
||||
}
|
||||
connWriteMessageMock = func(messageType int, data []byte) error {
|
||||
connWriteMessageMock = func(_ int, _ []byte) error {
|
||||
return nil
|
||||
}
|
||||
if err := startConsoleLog(ctx, mockWSConn, adminClient, LogRequest{node: "", logType: "all"}); assert.Error(err) {
|
||||
@@ -14,18 +14,18 @@
|
||||
// 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 restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/minio/console/api/operations"
|
||||
"github.com/minio/console/pkg/utils"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
"github.com/minio/madmin-go/v3"
|
||||
|
||||
groupApi "github.com/minio/console/restapi/operations/group"
|
||||
groupApi "github.com/minio/console/api/operations/group"
|
||||
|
||||
"github.com/minio/console/models"
|
||||
)
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -130,7 +130,7 @@ func TestGroupInfo(t *testing.T) {
|
||||
Status: "enabled",
|
||||
}
|
||||
// mock function response from updateGroupMembers()
|
||||
minioGetGroupDescriptionMock = func(group string) (*madmin.GroupDesc, error) {
|
||||
minioGetGroupDescriptionMock = func(_ string) (*madmin.GroupDesc, error) {
|
||||
return mockResponse, nil
|
||||
}
|
||||
function := "groupInfo()"
|
||||
@@ -144,7 +144,7 @@ func TestGroupInfo(t *testing.T) {
|
||||
assert.Equal("enabled", info.Status)
|
||||
|
||||
// Test-2 : groupInfo() Return error and see that the error is handled correctly and returned
|
||||
minioGetGroupDescriptionMock = func(group string) (*madmin.GroupDesc, error) {
|
||||
minioGetGroupDescriptionMock = func(_ string) (*madmin.GroupDesc, error) {
|
||||
return nil, errors.New("error")
|
||||
}
|
||||
_, err = groupInfo(ctx, adminClient, groupName)
|
||||
@@ -226,7 +226,7 @@ func TestUpdateGroup(t *testing.T) {
|
||||
// the function twice but the second time returned an error
|
||||
is2ndRunGroupInfo := false
|
||||
// mock function response from updateGroupMembers()
|
||||
minioGetGroupDescriptionMock = func(group string) (*madmin.GroupDesc, error) {
|
||||
minioGetGroupDescriptionMock = func(_ string) (*madmin.GroupDesc, error) {
|
||||
if is2ndRunGroupInfo {
|
||||
return mockResponseAfterUpdate, nil
|
||||
}
|
||||
@@ -236,7 +236,7 @@ func TestUpdateGroup(t *testing.T) {
|
||||
minioUpdateGroupMembersMock = func(madmin.GroupAddRemove) error {
|
||||
return nil
|
||||
}
|
||||
minioSetGroupStatusMock = func(group string, status madmin.GroupStatus) error {
|
||||
minioSetGroupStatusMock = func(_ string, _ madmin.GroupStatus) error {
|
||||
return nil
|
||||
}
|
||||
groupUpdated, err := groupUpdate(ctx, adminClient, groupName, expectedGroupUpdate)
|
||||
@@ -258,7 +258,7 @@ func TestSetGroupStatus(t *testing.T) {
|
||||
defer cancel()
|
||||
// Test-1: setGroupStatus() update valid disabled status
|
||||
expectedStatus := "disabled"
|
||||
minioSetGroupStatusMock = func(group string, status madmin.GroupStatus) error {
|
||||
minioSetGroupStatusMock = func(_ string, _ madmin.GroupStatus) error {
|
||||
return nil
|
||||
}
|
||||
if err := setGroupStatus(ctx, adminClient, groupName, expectedStatus); err != nil {
|
||||
@@ -266,7 +266,7 @@ func TestSetGroupStatus(t *testing.T) {
|
||||
}
|
||||
// Test-2: setGroupStatus() update valid enabled status
|
||||
expectedStatus = "enabled"
|
||||
minioSetGroupStatusMock = func(group string, status madmin.GroupStatus) error {
|
||||
minioSetGroupStatusMock = func(_ string, _ madmin.GroupStatus) error {
|
||||
return nil
|
||||
}
|
||||
if err := setGroupStatus(ctx, adminClient, groupName, expectedStatus); err != nil {
|
||||
@@ -274,7 +274,7 @@ func TestSetGroupStatus(t *testing.T) {
|
||||
}
|
||||
// Test-3: setGroupStatus() update invalid status, should send error
|
||||
expectedStatus = "invalid"
|
||||
minioSetGroupStatusMock = func(group string, status madmin.GroupStatus) error {
|
||||
minioSetGroupStatusMock = func(_ string, _ madmin.GroupStatus) error {
|
||||
return nil
|
||||
}
|
||||
if err := setGroupStatus(ctx, adminClient, groupName, expectedStatus); assert.Error(err) {
|
||||
@@ -282,7 +282,7 @@ func TestSetGroupStatus(t *testing.T) {
|
||||
}
|
||||
// Test-4: setGroupStatus() handler error correctly
|
||||
expectedStatus = "enabled"
|
||||
minioSetGroupStatusMock = func(group string, status madmin.GroupStatus) error {
|
||||
minioSetGroupStatusMock = func(_ string, _ madmin.GroupStatus) error {
|
||||
return errors.New("error")
|
||||
}
|
||||
if err := setGroupStatus(ctx, adminClient, groupName, expectedStatus); assert.Error(err) {
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -51,7 +51,7 @@ func Test_serverHealthInfo(t *testing.T) {
|
||||
args: args{
|
||||
deadline: deadlineDuration,
|
||||
mockMessages: []madmin.HealthInfo{{}, {}},
|
||||
wsWriteMock: func(messageType int, data []byte) error {
|
||||
wsWriteMock: func(_ int, data []byte) error {
|
||||
// mock connection WriteMessage() no error
|
||||
// emulate that receiver gets the message written
|
||||
var t madmin.HealthInfo
|
||||
@@ -67,7 +67,7 @@ func Test_serverHealthInfo(t *testing.T) {
|
||||
args: args{
|
||||
deadline: deadlineDuration,
|
||||
mockMessages: []madmin.HealthInfo{{}},
|
||||
wsWriteMock: func(messageType int, data []byte) error {
|
||||
wsWriteMock: func(_ int, data []byte) error {
|
||||
// mock connection WriteMessage() no error
|
||||
// emulate that receiver gets the message written
|
||||
var t madmin.HealthInfo
|
||||
@@ -83,7 +83,7 @@ func Test_serverHealthInfo(t *testing.T) {
|
||||
args: args{
|
||||
deadline: deadlineDuration,
|
||||
mockMessages: []madmin.HealthInfo{{}},
|
||||
wsWriteMock: func(messageType int, data []byte) error {
|
||||
wsWriteMock: func(_ int, data []byte) error {
|
||||
// mock connection WriteMessage() no error
|
||||
// emulate that receiver gets the message written
|
||||
var t madmin.HealthInfo
|
||||
@@ -102,7 +102,7 @@ func Test_serverHealthInfo(t *testing.T) {
|
||||
Error: "error on healthInfo",
|
||||
},
|
||||
},
|
||||
wsWriteMock: func(messageType int, data []byte) error {
|
||||
wsWriteMock: func(_ int, data []byte) error {
|
||||
// mock connection WriteMessage() no error
|
||||
// emulate that receiver gets the message written
|
||||
var t madmin.HealthInfo
|
||||
@@ -115,12 +115,12 @@ func Test_serverHealthInfo(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.test, func(t *testing.T) {
|
||||
t.Run(tt.test, func(_ *testing.T) {
|
||||
// make testReceiver channel
|
||||
testReceiver = make(chan madmin.HealthInfo, len(tt.args.mockMessages))
|
||||
// mock function same for all tests, changes mockMessages
|
||||
minioServerHealthInfoMock = func(ctx context.Context, healthDataTypes []madmin.HealthDataType,
|
||||
deadline time.Duration,
|
||||
minioServerHealthInfoMock = func(_ context.Context, _ []madmin.HealthDataType,
|
||||
_ time.Duration,
|
||||
) (interface{}, string, error) {
|
||||
info := tt.args.mockMessages[0]
|
||||
return info, madmin.HealthInfoVersion, nil
|
||||
@@ -15,7 +15,7 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -23,9 +23,9 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/minio/console/api/operations"
|
||||
"github.com/minio/console/api/operations/idp"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
"github.com/minio/console/restapi/operations/idp"
|
||||
"github.com/minio/madmin-go/v3"
|
||||
)
|
||||
|
||||
@@ -198,6 +198,7 @@ func getIDPConfiguration(ctx context.Context, idpType, name string, client Minio
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &models.IdpServerConfiguration{
|
||||
Name: config.Name,
|
||||
Type: config.Type,
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -27,9 +27,9 @@ import (
|
||||
|
||||
"github.com/minio/madmin-go/v3"
|
||||
|
||||
"github.com/minio/console/api/operations"
|
||||
"github.com/minio/console/api/operations/idp"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
"github.com/minio/console/restapi/operations/idp"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
@@ -46,7 +46,7 @@ type IDPTestSuite struct {
|
||||
func (suite *IDPTestSuite) SetupSuite() {
|
||||
suite.assert = assert.New(suite.T())
|
||||
suite.adminClient = AdminClientMock{}
|
||||
minioServiceRestartMock = func(ctx context.Context) error {
|
||||
minioServiceRestartMock = func(_ context.Context) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -270,7 +270,7 @@ func TestGetEntitiesResult(t *testing.T) {
|
||||
GroupMappings: groupsMap,
|
||||
UserMappings: usersMap,
|
||||
}
|
||||
minioGetLDAPPolicyEntitiesMock = func(ctx context.Context, query madmin.PolicyEntitiesQuery) (madmin.PolicyEntitiesResult, error) {
|
||||
minioGetLDAPPolicyEntitiesMock = func(_ context.Context, _ madmin.PolicyEntitiesQuery) (madmin.PolicyEntitiesResult, error) {
|
||||
return mockResponse, nil
|
||||
}
|
||||
|
||||
@@ -308,7 +308,7 @@ func TestGetEntitiesResult(t *testing.T) {
|
||||
}
|
||||
|
||||
// Test-2: getEntitiesResult error is returned from getLDAPPolicyEntities()
|
||||
minioGetLDAPPolicyEntitiesMock = func(ctx context.Context, query madmin.PolicyEntitiesQuery) (madmin.PolicyEntitiesResult, error) {
|
||||
minioGetLDAPPolicyEntitiesMock = func(_ context.Context, _ madmin.PolicyEntitiesQuery) (madmin.PolicyEntitiesResult, error) {
|
||||
return madmin.PolicyEntitiesResult{}, errors.New("error")
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -31,9 +31,9 @@ import (
|
||||
"github.com/minio/console/pkg/utils"
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/minio/console/api/operations"
|
||||
systemApi "github.com/minio/console/api/operations/system"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
systemApi "github.com/minio/console/restapi/operations/system"
|
||||
)
|
||||
|
||||
func registerAdminInfoHandlers(api *operations.ConsoleAPI) {
|
||||
@@ -46,7 +46,7 @@ func registerAdminInfoHandlers(api *operations.ConsoleAPI) {
|
||||
return systemApi.NewAdminInfoOK().WithPayload(infoResp)
|
||||
})
|
||||
// return single widget results
|
||||
api.SystemDashboardWidgetDetailsHandler = systemApi.DashboardWidgetDetailsHandlerFunc(func(params systemApi.DashboardWidgetDetailsParams, session *models.Principal) middleware.Responder {
|
||||
api.SystemDashboardWidgetDetailsHandler = systemApi.DashboardWidgetDetailsHandlerFunc(func(params systemApi.DashboardWidgetDetailsParams, _ *models.Principal) middleware.Responder {
|
||||
infoResp, err := getAdminInfoWidgetResponse(params)
|
||||
if err != nil {
|
||||
return systemApi.NewDashboardWidgetDetailsDefault(err.Code).WithPayload(err.APIError)
|
||||
@@ -881,7 +881,10 @@ func getAdminInfoResponse(session *models.Principal, params systemApi.AdminInfoP
|
||||
prometheusURL := ""
|
||||
|
||||
if !*params.DefaultOnly {
|
||||
prometheusURL = getPrometheusURL()
|
||||
promURL := getPrometheusURL()
|
||||
if promURL != "" {
|
||||
prometheusURL = promURL
|
||||
}
|
||||
}
|
||||
|
||||
mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session)
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -25,9 +25,9 @@ import (
|
||||
|
||||
"github.com/minio/console/pkg/utils"
|
||||
|
||||
"github.com/minio/console/api/operations"
|
||||
systemApi "github.com/minio/console/api/operations/system"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
systemApi "github.com/minio/console/restapi/operations/system"
|
||||
"github.com/minio/madmin-go/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
@@ -46,7 +46,7 @@ type AdminInfoTestSuite struct {
|
||||
func (suite *AdminInfoTestSuite) SetupSuite() {
|
||||
suite.assert = assert.New(suite.T())
|
||||
suite.adminClient = AdminClientMock{}
|
||||
MinioServerInfoMock = func(ctx context.Context) (madmin.InfoMessage, error) {
|
||||
MinioServerInfoMock = func(_ context.Context) (madmin.InfoMessage, error) {
|
||||
return madmin.InfoMessage{
|
||||
Servers: []madmin.ServerProperties{{
|
||||
Disks: []madmin.Disk{{}},
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
@@ -26,9 +26,9 @@ import (
|
||||
|
||||
"github.com/go-openapi/runtime"
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/minio/console/api/operations"
|
||||
inspectApi "github.com/minio/console/api/operations/inspect"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
inspectApi "github.com/minio/console/restapi/operations/inspect"
|
||||
"github.com/minio/madmin-go/v3"
|
||||
"github.com/secure-io/sio-go"
|
||||
)
|
||||
@@ -120,7 +120,7 @@ func processInspectResponse(params *inspectApi.InspectParams, k []byte, r io.Rea
|
||||
|
||||
_, err := io.Copy(w, r)
|
||||
if err != nil {
|
||||
LogError("Unable to write all the data: %v", err)
|
||||
LogError("unable to write all the data: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -23,9 +23,9 @@ import (
|
||||
"sort"
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/minio/console/api/operations"
|
||||
kmsAPI "github.com/minio/console/api/operations/k_m_s"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
kmsAPI "github.com/minio/console/restapi/operations/k_m_s"
|
||||
"github.com/minio/madmin-go/v3"
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -23,9 +23,9 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/minio/console/api/operations"
|
||||
kmsAPI "github.com/minio/console/api/operations/k_m_s"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
kmsAPI "github.com/minio/console/restapi/operations/k_m_s"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
@@ -14,15 +14,15 @@
|
||||
// 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 restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/minio/console/api/operations"
|
||||
systemApi "github.com/minio/console/api/operations/system"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
systemApi "github.com/minio/console/restapi/operations/system"
|
||||
)
|
||||
|
||||
func registerNodesHandler(api *operations.ConsoleAPI) {
|
||||
@@ -14,16 +14,16 @@
|
||||
// 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 restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/minio/console/api/operations"
|
||||
configurationApi "github.com/minio/console/api/operations/configuration"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
configurationApi "github.com/minio/console/restapi/operations/configuration"
|
||||
)
|
||||
|
||||
func registerAdminNotificationEndpointsHandlers(api *operations.ConsoleAPI) {
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -24,8 +24,8 @@ import (
|
||||
|
||||
"github.com/go-openapi/swag"
|
||||
|
||||
cfgApi "github.com/minio/console/api/operations/configuration"
|
||||
"github.com/minio/console/models"
|
||||
cfgApi "github.com/minio/console/restapi/operations/configuration"
|
||||
)
|
||||
|
||||
func Test_addNotificationEndpoint(t *testing.T) {
|
||||
@@ -61,7 +61,7 @@ func Test_addNotificationEndpoint(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
mockSetConfig: func(kv string) (restart bool, err error) {
|
||||
mockSetConfig: func(_ string) (restart bool, err error) {
|
||||
return false, nil
|
||||
},
|
||||
want: &models.SetNotificationEndpointResponse{
|
||||
@@ -94,7 +94,7 @@ func Test_addNotificationEndpoint(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
mockSetConfig: func(kv string) (restart bool, err error) {
|
||||
mockSetConfig: func(_ string) (restart bool, err error) {
|
||||
return false, errors.New("error")
|
||||
},
|
||||
want: nil,
|
||||
@@ -118,7 +118,7 @@ func Test_addNotificationEndpoint(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
mockSetConfig: func(kv string) (restart bool, err error) {
|
||||
mockSetConfig: func(_ string) (restart bool, err error) {
|
||||
return false, nil
|
||||
},
|
||||
want: &models.SetNotificationEndpointResponse{
|
||||
@@ -149,7 +149,7 @@ func Test_addNotificationEndpoint(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
mockSetConfig: func(kv string) (restart bool, err error) {
|
||||
mockSetConfig: func(_ string) (restart bool, err error) {
|
||||
return false, nil
|
||||
},
|
||||
want: &models.SetNotificationEndpointResponse{
|
||||
@@ -178,7 +178,7 @@ func Test_addNotificationEndpoint(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
mockSetConfig: func(kv string) (restart bool, err error) {
|
||||
mockSetConfig: func(_ string) (restart bool, err error) {
|
||||
return false, nil
|
||||
},
|
||||
want: &models.SetNotificationEndpointResponse{
|
||||
@@ -208,7 +208,7 @@ func Test_addNotificationEndpoint(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
mockSetConfig: func(kv string) (restart bool, err error) {
|
||||
mockSetConfig: func(_ string) (restart bool, err error) {
|
||||
return false, nil
|
||||
},
|
||||
want: &models.SetNotificationEndpointResponse{
|
||||
@@ -240,7 +240,7 @@ func Test_addNotificationEndpoint(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
mockSetConfig: func(kv string) (restart bool, err error) {
|
||||
mockSetConfig: func(_ string) (restart bool, err error) {
|
||||
return false, nil
|
||||
},
|
||||
want: &models.SetNotificationEndpointResponse{
|
||||
@@ -273,7 +273,7 @@ func Test_addNotificationEndpoint(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
mockSetConfig: func(kv string) (restart bool, err error) {
|
||||
mockSetConfig: func(_ string) (restart bool, err error) {
|
||||
return false, nil
|
||||
},
|
||||
want: &models.SetNotificationEndpointResponse{
|
||||
@@ -305,7 +305,7 @@ func Test_addNotificationEndpoint(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
mockSetConfig: func(kv string) (restart bool, err error) {
|
||||
mockSetConfig: func(_ string) (restart bool, err error) {
|
||||
return false, nil
|
||||
},
|
||||
want: &models.SetNotificationEndpointResponse{
|
||||
@@ -335,7 +335,7 @@ func Test_addNotificationEndpoint(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
mockSetConfig: func(kv string) (restart bool, err error) {
|
||||
mockSetConfig: func(_ string) (restart bool, err error) {
|
||||
return false, nil
|
||||
},
|
||||
want: &models.SetNotificationEndpointResponse{
|
||||
@@ -365,7 +365,7 @@ func Test_addNotificationEndpoint(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
mockSetConfig: func(kv string) (restart bool, err error) {
|
||||
mockSetConfig: func(_ string) (restart bool, err error) {
|
||||
return false, nil
|
||||
},
|
||||
want: &models.SetNotificationEndpointResponse{
|
||||
@@ -397,7 +397,7 @@ func Test_addNotificationEndpoint(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
mockSetConfig: func(kv string) (restart bool, err error) {
|
||||
mockSetConfig: func(_ string) (restart bool, err error) {
|
||||
return false, errors.New("invalid config")
|
||||
},
|
||||
want: nil,
|
||||
@@ -421,7 +421,7 @@ func Test_addNotificationEndpoint(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
mockSetConfig: func(kv string) (restart bool, err error) {
|
||||
mockSetConfig: func(_ string) (restart bool, err error) {
|
||||
return true, nil
|
||||
},
|
||||
want: &models.SetNotificationEndpointResponse{
|
||||
@@ -438,7 +438,7 @@ func Test_addNotificationEndpoint(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
// mock function response from setConfig()
|
||||
minioSetConfigKVMock = tt.mockSetConfig
|
||||
got, err := addNotificationEndpoint(tt.args.ctx, tt.args.client, tt.args.params)
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -41,7 +41,7 @@ type ObjectsRequest struct {
|
||||
|
||||
type WSResponse struct {
|
||||
RequestID int64 `json:"request_id,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
Error *CodedAPIError `json:"error,omitempty"`
|
||||
RequestEnd bool `json:"request_end,omitempty"`
|
||||
Prefix string `json:"prefix,omitempty"`
|
||||
BucketName string `json:"bucketName,omitempty"`
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -97,11 +97,11 @@ func TestWSRewindObjects(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
mcListMock = func(ctx context.Context, opts mc.ListOptions) <-chan *mc.ClientContent {
|
||||
mcListMock = func(_ context.Context, _ mc.ListOptions) <-chan *mc.ClientContent {
|
||||
ch := make(chan *mc.ClientContent)
|
||||
go func() {
|
||||
defer close(ch)
|
||||
@@ -206,11 +206,11 @@ func TestWSListObjects(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
minioListObjectsMock = func(ctx context.Context, bucket string, opts minio.ListObjectsOptions) <-chan minio.ObjectInfo {
|
||||
minioListObjectsMock = func(_ context.Context, _ string, _ minio.ListObjectsOptions) <-chan minio.ObjectInfo {
|
||||
ch := make(chan minio.ObjectInfo)
|
||||
go func() {
|
||||
defer close(ch)
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -24,17 +24,17 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
bucketApi "github.com/minio/console/api/operations/bucket"
|
||||
policyApi "github.com/minio/console/api/operations/policy"
|
||||
"github.com/minio/console/pkg/utils"
|
||||
bucketApi "github.com/minio/console/restapi/operations/bucket"
|
||||
policyApi "github.com/minio/console/restapi/operations/policy"
|
||||
s3 "github.com/minio/minio-go/v7"
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/minio/console/api/operations"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
iampolicy "github.com/minio/pkg/v2/policy"
|
||||
|
||||
policies "github.com/minio/console/restapi/policy"
|
||||
policies "github.com/minio/console/api/policy"
|
||||
)
|
||||
|
||||
func registersPoliciesHandler(api *operations.ConsoleAPI) {
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -83,7 +83,7 @@ func TestRemovePolicy(t *testing.T) {
|
||||
adminClient := AdminClientMock{}
|
||||
// Test-1 : removePolicy() remove an existing policy
|
||||
policyToRemove := "console-policy"
|
||||
minioRemovePolicyMock = func(name string) error {
|
||||
minioRemovePolicyMock = func(_ string) error {
|
||||
return nil
|
||||
}
|
||||
function := "removePolicy()"
|
||||
@@ -91,7 +91,7 @@ func TestRemovePolicy(t *testing.T) {
|
||||
t.Errorf("Failed on %s:, error occurred: %s", function, err.Error())
|
||||
}
|
||||
// Test-2 : removePolicy() Return error and see that the error is handled correctly and returned
|
||||
minioRemovePolicyMock = func(name string) error {
|
||||
minioRemovePolicyMock = func(_ string) error {
|
||||
return errors.New("error")
|
||||
}
|
||||
if err := removePolicy(ctx, adminClient, policyToRemove); funcAssert.Error(err) {
|
||||
@@ -106,10 +106,10 @@ func TestAddPolicy(t *testing.T) {
|
||||
adminClient := AdminClientMock{}
|
||||
policyName := "new-policy"
|
||||
policyDefinition := "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":[\"s3:GetBucketLocation\",\"s3:GetObject\",\"s3:ListAllMyBuckets\"],\"Resource\":[\"arn:aws:s3:::*\"]}]}"
|
||||
minioAddPolicyMock = func(name string, policy *iampolicy.Policy) error {
|
||||
minioAddPolicyMock = func(_ string, _ *iampolicy.Policy) error {
|
||||
return nil
|
||||
}
|
||||
minioGetPolicyMock = func(name string) (*iampolicy.Policy, error) {
|
||||
minioGetPolicyMock = func(_ string) (*iampolicy.Policy, error) {
|
||||
policy := "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":[\"s3:GetBucketLocation\",\"s3:GetObject\",\"s3:ListAllMyBuckets\"],\"Resource\":[\"arn:aws:s3:::*\"]}]}"
|
||||
iamp, err := iampolicy.ParseConfig(bytes.NewReader([]byte(policy)))
|
||||
if err != nil {
|
||||
@@ -138,17 +138,17 @@ func TestAddPolicy(t *testing.T) {
|
||||
funcAssert.Equal(expectedPolicy, actualPolicy)
|
||||
}
|
||||
// Test-2 : addPolicy() got an error while adding policy
|
||||
minioAddPolicyMock = func(name string, policy *iampolicy.Policy) error {
|
||||
minioAddPolicyMock = func(_ string, _ *iampolicy.Policy) error {
|
||||
return errors.New("error")
|
||||
}
|
||||
if _, err := addPolicy(ctx, adminClient, policyName, policyDefinition); funcAssert.Error(err) {
|
||||
funcAssert.Equal("error", err.Error())
|
||||
}
|
||||
// Test-3 : addPolicy() got an error while retrieving policy
|
||||
minioAddPolicyMock = func(name string, policy *iampolicy.Policy) error {
|
||||
minioAddPolicyMock = func(_ string, _ *iampolicy.Policy) error {
|
||||
return nil
|
||||
}
|
||||
minioGetPolicyMock = func(name string) (*iampolicy.Policy, error) {
|
||||
minioGetPolicyMock = func(_ string) (*iampolicy.Policy, error) {
|
||||
return nil, errors.New("error")
|
||||
}
|
||||
if _, err := addPolicy(ctx, adminClient, policyName, policyDefinition); funcAssert.Error(err) {
|
||||
@@ -164,7 +164,7 @@ func TestSetPolicy(t *testing.T) {
|
||||
policyName := "readOnly"
|
||||
entityName := "alevsk"
|
||||
entityObject := models.PolicyEntityUser
|
||||
minioSetPolicyMock = func(policyName, entityName string, isGroup bool) error {
|
||||
minioSetPolicyMock = func(_, _ string, _ bool) error {
|
||||
return nil
|
||||
}
|
||||
// Test-1 : SetPolicy() set policy to user
|
||||
@@ -181,7 +181,7 @@ func TestSetPolicy(t *testing.T) {
|
||||
}
|
||||
// Test-3 : SetPolicy() set policy to user and get error
|
||||
entityObject = models.PolicyEntityUser
|
||||
minioSetPolicyMock = func(policyName, entityName string, isGroup bool) error {
|
||||
minioSetPolicyMock = func(_, _ string, _ bool) error {
|
||||
return errors.New("error")
|
||||
}
|
||||
if err := SetPolicy(ctx, adminClient, policyName, entityName, entityObject); funcAssert.Error(err) {
|
||||
@@ -189,7 +189,7 @@ func TestSetPolicy(t *testing.T) {
|
||||
}
|
||||
// Test-4 : SetPolicy() set policy to group and get error
|
||||
entityObject = models.PolicyEntityGroup
|
||||
minioSetPolicyMock = func(policyName, entityName string, isGroup bool) error {
|
||||
minioSetPolicyMock = func(_, _ string, _ bool) error {
|
||||
return errors.New("error")
|
||||
}
|
||||
if err := SetPolicy(ctx, adminClient, policyName, entityName, entityObject); funcAssert.Error(err) {
|
||||
@@ -219,7 +219,7 @@ func Test_SetPolicyMultiple(t *testing.T) {
|
||||
policyName: "readonly",
|
||||
users: []models.IamEntity{"user1", "user2"},
|
||||
groups: []models.IamEntity{"group1", "group2"},
|
||||
setPolicyFunc: func(policyName, entityName string, isGroup bool) error {
|
||||
setPolicyFunc: func(_, _ string, _ bool) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
@@ -231,7 +231,7 @@ func Test_SetPolicyMultiple(t *testing.T) {
|
||||
policyName: "readonly",
|
||||
users: []models.IamEntity{"user1", "user2"},
|
||||
groups: []models.IamEntity{"group1", "group2"},
|
||||
setPolicyFunc: func(policyName, entityName string, isGroup bool) error {
|
||||
setPolicyFunc: func(_, _ string, _ bool) error {
|
||||
return errors.New("error set")
|
||||
},
|
||||
},
|
||||
@@ -244,7 +244,7 @@ func Test_SetPolicyMultiple(t *testing.T) {
|
||||
policyName: "readonly",
|
||||
users: []models.IamEntity{},
|
||||
groups: []models.IamEntity{},
|
||||
setPolicyFunc: func(policyName, entityName string, isGroup bool) error {
|
||||
setPolicyFunc: func(_, _ string, _ bool) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
@@ -252,7 +252,7 @@ func Test_SetPolicyMultiple(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
minioSetPolicyMock = tt.args.setPolicyFunc
|
||||
got := setPolicyMultipleEntities(ctx, adminClient, tt.args.policyName, tt.args.users, tt.args.groups)
|
||||
if !reflect.DeepEqual(got, tt.errorExpected) {
|
||||
@@ -373,7 +373,7 @@ func Test_policyMatchesBucket(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
if got := policyMatchesBucket(tt.args.ctx, tt.args.policy, tt.args.bucket); got != tt.want {
|
||||
t.Errorf("policyMatchesBucket() = %v, want %v", got, tt.want)
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -52,7 +52,7 @@ func TestStartProfiling(t *testing.T) {
|
||||
|
||||
// Test-1 : startProfiling() Get response from MinIO server with one profiling object without errors
|
||||
// mock function response from startProfiling()
|
||||
minioStartProfiling = func(profiler madmin.ProfilerType) ([]madmin.StartProfilingResult, error) {
|
||||
minioStartProfiling = func(_ madmin.ProfilerType) ([]madmin.StartProfilingResult, error) {
|
||||
return []madmin.StartProfilingResult{
|
||||
{
|
||||
NodeName: "http://127.0.0.1:9000/",
|
||||
@@ -71,7 +71,7 @@ func TestStartProfiling(t *testing.T) {
|
||||
return &ClosingBuffer{bytes.NewBufferString("In memory string eaeae")}, nil
|
||||
}
|
||||
// mock function response from mockConn.writeMessage()
|
||||
connWriteMessageMock = func(messageType int, p []byte) error {
|
||||
connWriteMessageMock = func(_ int, _ []byte) error {
|
||||
return nil
|
||||
}
|
||||
err := startProfiling(ctx, mockWSConn, adminClient, testOptions)
|
||||
@@ -82,7 +82,7 @@ func TestStartProfiling(t *testing.T) {
|
||||
|
||||
// Test-2 : startProfiling() Correctly handles errors returned by MinIO
|
||||
// mock function response from startProfiling()
|
||||
minioStartProfiling = func(profiler madmin.ProfilerType) ([]madmin.StartProfilingResult, error) {
|
||||
minioStartProfiling = func(_ madmin.ProfilerType) ([]madmin.StartProfilingResult, error) {
|
||||
return nil, errors.New("error")
|
||||
}
|
||||
err = startProfiling(ctx, mockWSConn, adminClient, testOptions)
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -27,9 +27,9 @@ import (
|
||||
"github.com/minio/console/pkg/utils"
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/minio/console/api/operations"
|
||||
release "github.com/minio/console/api/operations/release"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
release "github.com/minio/console/restapi/operations/release"
|
||||
"github.com/minio/pkg/v2/env"
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -24,9 +24,9 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/minio/console/api/operations"
|
||||
release "github.com/minio/console/api/operations/release"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
release "github.com/minio/console/restapi/operations/release"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -30,9 +30,9 @@ import (
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/minio/console/api/operations"
|
||||
bucketApi "github.com/minio/console/api/operations/bucket"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
bucketApi "github.com/minio/console/restapi/operations/bucket"
|
||||
"github.com/minio/minio-go/v7/pkg/replication"
|
||||
)
|
||||
|
||||
@@ -90,7 +90,7 @@ func registerAdminBucketRemoteHandlers(api *operations.ConsoleAPI) {
|
||||
})
|
||||
|
||||
// list external buckets
|
||||
api.BucketListExternalBucketsHandler = bucketApi.ListExternalBucketsHandlerFunc(func(params bucketApi.ListExternalBucketsParams, session *models.Principal) middleware.Responder {
|
||||
api.BucketListExternalBucketsHandler = bucketApi.ListExternalBucketsHandlerFunc(func(params bucketApi.ListExternalBucketsParams, _ *models.Principal) middleware.Responder {
|
||||
response, err := listExternalBucketsResponse(params)
|
||||
if err != nil {
|
||||
return bucketApi.NewListExternalBucketsDefault(err.Code).WithPayload(err.APIError)
|
||||
@@ -796,7 +796,6 @@ func updateBucketReplicationResponse(session *models.Principal, params bucketApi
|
||||
params.Body.Tags,
|
||||
params.Body.Priority,
|
||||
params.Body.StorageClass)
|
||||
|
||||
if err != nil {
|
||||
return ErrorWithContext(ctx, err)
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -27,9 +27,9 @@ import (
|
||||
"github.com/minio/console/pkg/utils"
|
||||
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/minio/console/api/operations"
|
||||
bucketApi "github.com/minio/console/api/operations/bucket"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
bucketApi "github.com/minio/console/restapi/operations/bucket"
|
||||
"github.com/minio/madmin-go/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
@@ -299,7 +299,7 @@ func (suite *RemoteBucketsTestSuite) initListExternalBucketsRequest() (params bu
|
||||
|
||||
func (suite *RemoteBucketsTestSuite) TestListExternalBucketsWithError() {
|
||||
ctx := context.Background()
|
||||
minioAccountInfoMock = func(ctx context.Context) (madmin.AccountInfo, error) {
|
||||
minioAccountInfoMock = func(_ context.Context) (madmin.AccountInfo, error) {
|
||||
return madmin.AccountInfo{}, errors.New("error")
|
||||
}
|
||||
res, err := listExternalBuckets(ctx, &suite.adminClient)
|
||||
@@ -309,7 +309,7 @@ func (suite *RemoteBucketsTestSuite) TestListExternalBucketsWithError() {
|
||||
|
||||
func (suite *RemoteBucketsTestSuite) TestListExternalBucketsWithoutError() {
|
||||
ctx := context.Background()
|
||||
minioAccountInfoMock = func(ctx context.Context) (madmin.AccountInfo, error) {
|
||||
minioAccountInfoMock = func(_ context.Context) (madmin.AccountInfo, error) {
|
||||
return madmin.AccountInfo{
|
||||
Buckets: []madmin.BucketAccessInfo{},
|
||||
}, nil
|
||||
@@ -14,15 +14,15 @@
|
||||
// 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 restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/minio/console/api/operations"
|
||||
siteRepApi "github.com/minio/console/api/operations/site_replication"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
siteRepApi "github.com/minio/console/restapi/operations/site_replication"
|
||||
"github.com/minio/madmin-go/v3"
|
||||
)
|
||||
|
||||
@@ -14,17 +14,17 @@
|
||||
// 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 restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/minio/console/api/operations"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
|
||||
svcApi "github.com/minio/console/restapi/operations/service"
|
||||
svcApi "github.com/minio/console/api/operations/service"
|
||||
)
|
||||
|
||||
func registerServiceHandlers(api *operations.ConsoleAPI) {
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -32,10 +32,10 @@ func TestServiceRestart(t *testing.T) {
|
||||
function := "serviceRestart()"
|
||||
// Test-1 : serviceRestart() restart services no errors
|
||||
// mock function response from listGroups()
|
||||
minioServiceRestartMock = func(ctx context.Context) error {
|
||||
minioServiceRestartMock = func(_ context.Context) error {
|
||||
return nil
|
||||
}
|
||||
MinioServerInfoMock = func(ctx context.Context) (madmin.InfoMessage, error) {
|
||||
MinioServerInfoMock = func(_ context.Context) (madmin.InfoMessage, error) {
|
||||
return madmin.InfoMessage{}, nil
|
||||
}
|
||||
if err := serviceRestart(ctx, adminClient); err != nil {
|
||||
@@ -44,10 +44,10 @@ func TestServiceRestart(t *testing.T) {
|
||||
|
||||
// Test-2 : serviceRestart() returns errors on client.serviceRestart call
|
||||
// and see that the errors is handled correctly and returned
|
||||
minioServiceRestartMock = func(ctx context.Context) error {
|
||||
minioServiceRestartMock = func(_ context.Context) error {
|
||||
return errors.New("error")
|
||||
}
|
||||
MinioServerInfoMock = func(ctx context.Context) (madmin.InfoMessage, error) {
|
||||
MinioServerInfoMock = func(_ context.Context) (madmin.InfoMessage, error) {
|
||||
return madmin.InfoMessage{}, nil
|
||||
}
|
||||
if err := serviceRestart(ctx, adminClient); assert.Error(err) {
|
||||
@@ -56,10 +56,10 @@ func TestServiceRestart(t *testing.T) {
|
||||
|
||||
// Test-3 : serviceRestart() returns errors on client.serverInfo() call
|
||||
// and see that the errors is handled correctly and returned
|
||||
minioServiceRestartMock = func(ctx context.Context) error {
|
||||
minioServiceRestartMock = func(_ context.Context) error {
|
||||
return nil
|
||||
}
|
||||
MinioServerInfoMock = func(ctx context.Context) (madmin.InfoMessage, error) {
|
||||
MinioServerInfoMock = func(_ context.Context) (madmin.InfoMessage, error) {
|
||||
return madmin.InfoMessage{}, errors.New("error on server info")
|
||||
}
|
||||
if err := serviceRestart(ctx, adminClient); assert.Error(err) {
|
||||
@@ -14,15 +14,16 @@
|
||||
// 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 restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/runtime"
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/minio/console/api/operations"
|
||||
siteRepApi "github.com/minio/console/api/operations/site_replication"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
siteRepApi "github.com/minio/console/restapi/operations/site_replication"
|
||||
"github.com/minio/madmin-go/v3"
|
||||
)
|
||||
|
||||
@@ -162,7 +163,13 @@ func addSiteReplication(ctx context.Context, client MinioAdmin, params *siteRepA
|
||||
rSites = append(rSites, *pInfo)
|
||||
}
|
||||
}
|
||||
cc, err := client.addSiteReplicationInfo(ctx, rSites)
|
||||
qs := runtime.Values(params.HTTPRequest.URL.Query())
|
||||
_, qhkReplicateILMExpiry, _ := qs.GetOK("replicate-ilm-expiry")
|
||||
var opts madmin.SRAddOptions
|
||||
if qhkReplicateILMExpiry {
|
||||
opts.ReplicateILMExpiry = true
|
||||
}
|
||||
cc, err := client.addSiteReplicationInfo(ctx, rSites, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -183,7 +190,17 @@ func editSiteReplication(ctx context.Context, client MinioAdmin, params *siteRep
|
||||
Name: params.Body.Name, // does not get updated.
|
||||
DeploymentID: params.Body.DeploymentID, // readonly
|
||||
}
|
||||
eRes, err := client.editSiteReplicationInfo(ctx, *peerSiteInfo)
|
||||
qs := runtime.Values(params.HTTPRequest.URL.Query())
|
||||
_, qhkDisableILMExpiryReplication, _ := qs.GetOK("disable-ilm-expiry-replication")
|
||||
_, qhkEnableILMExpiryReplication, _ := qs.GetOK("enable-ilm-expiry-replication")
|
||||
var opts madmin.SREditOptions
|
||||
if qhkDisableILMExpiryReplication {
|
||||
opts.DisableILMExpiryReplication = true
|
||||
}
|
||||
if qhkEnableILMExpiryReplication {
|
||||
opts.EnableILMExpiryReplication = true
|
||||
}
|
||||
eRes, err := client.editSiteReplicationInfo(ctx, *peerSiteInfo, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
// These tests are for AdminAPI Tag based on swagger-console.yml
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -72,7 +72,7 @@ func TestGetSiteReplicationInfo(t *testing.T) {
|
||||
ServiceAccountAccessKey: "test-key",
|
||||
}
|
||||
|
||||
getSiteReplicationInfo = func(ctx context.Context) (info *madmin.SiteReplicationInfo, err error) {
|
||||
getSiteReplicationInfo = func(_ context.Context) (info *madmin.SiteReplicationInfo, err error) {
|
||||
return &retValueMock, nil
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ func TestAddSiteReplicationInfo(t *testing.T) {
|
||||
InitialSyncErrorMessage: "",
|
||||
}
|
||||
|
||||
addSiteReplicationInfo = func(ctx context.Context, sites []madmin.PeerSite) (res *madmin.ReplicateAddStatus, err error) {
|
||||
addSiteReplicationInfo = func(_ context.Context, _ []madmin.PeerSite) (res *madmin.ReplicateAddStatus, err error) {
|
||||
return retValueMock, nil
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ func TestAddSiteReplicationInfo(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
srInfo, err := adminClient.addSiteReplicationInfo(ctx, sites)
|
||||
srInfo, err := adminClient.addSiteReplicationInfo(ctx, sites, madmin.SRAddOptions{})
|
||||
assert.Nil(err)
|
||||
assert.Equal(expValueMock, srInfo, fmt.Sprintf("Failed on %s: length of lists is not the same", function))
|
||||
}
|
||||
@@ -149,7 +149,7 @@ func TestEditSiteReplicationInfo(t *testing.T) {
|
||||
ErrDetail: "",
|
||||
}
|
||||
|
||||
editSiteReplicationInfo = func(ctx context.Context, site madmin.PeerInfo) (res *madmin.ReplicateEditStatus, err error) {
|
||||
editSiteReplicationInfo = func(_ context.Context, _ madmin.PeerInfo) (res *madmin.ReplicateEditStatus, err error) {
|
||||
return retValueMock, nil
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ func TestEditSiteReplicationInfo(t *testing.T) {
|
||||
DeploymentID: "12345",
|
||||
}
|
||||
|
||||
srInfo, err := adminClient.editSiteReplicationInfo(ctx, site)
|
||||
srInfo, err := adminClient.editSiteReplicationInfo(ctx, site, madmin.SREditOptions{})
|
||||
assert.Nil(err)
|
||||
assert.Equal(expValueMock, srInfo, fmt.Sprintf("Failed on %s: length of lists is not the same", function))
|
||||
}
|
||||
@@ -183,7 +183,7 @@ func TestDeleteSiteReplicationInfo(t *testing.T) {
|
||||
ErrDetail: "",
|
||||
}
|
||||
|
||||
deleteSiteReplicationInfoMock = func(ctx context.Context, removeReq madmin.SRRemoveReq) (res *madmin.ReplicateRemoveStatus, err error) {
|
||||
deleteSiteReplicationInfoMock = func(_ context.Context, _ madmin.SRRemoveReq) (res *madmin.ReplicateRemoveStatus, err error) {
|
||||
return retValueMock, nil
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ func TestSiteReplicationStatus(t *testing.T) {
|
||||
GroupStats: nil,
|
||||
}
|
||||
|
||||
getSiteReplicationStatus = func(ctx context.Context, params madmin.SRStatusOptions) (info *madmin.SRStatusInfo, err error) {
|
||||
getSiteReplicationStatus = func(_ context.Context, _ madmin.SRStatusOptions) (info *madmin.SRStatusInfo, err error) {
|
||||
return &retValueMock, nil
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -15,7 +15,7 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -30,10 +30,10 @@ import (
|
||||
xhttp "github.com/minio/console/pkg/http"
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/minio/console/api/operations"
|
||||
subnetApi "github.com/minio/console/api/operations/subnet"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/pkg/subnet"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
subnetApi "github.com/minio/console/restapi/operations/subnet"
|
||||
"github.com/minio/madmin-go/v3"
|
||||
)
|
||||
|
||||
@@ -356,7 +356,7 @@ func GetSubnetInfoResponse(session *models.Principal, params subnetApi.SubnetInf
|
||||
return nil, ErrorWithContext(ctx, ErrSubnetLicenseNotFound)
|
||||
}
|
||||
|
||||
licenseInfo, err := subnet.ParseLicense(client, seededLicense)
|
||||
licenseInfo, err := getLicenseInfo(*client.Client, seededLicense)
|
||||
if err != nil {
|
||||
return nil, ErrorWithContext(ctx, err)
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -24,9 +24,9 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/minio/console/api/operations"
|
||||
subnetApi "github.com/minio/console/api/operations/subnet"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
subnetApi "github.com/minio/console/restapi/operations/subnet"
|
||||
"github.com/minio/madmin-go/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
@@ -44,10 +44,10 @@ type AdminSubnetTestSuite struct {
|
||||
func (suite *AdminSubnetTestSuite) SetupSuite() {
|
||||
suite.assert = assert.New(suite.T())
|
||||
suite.adminClient = AdminClientMock{}
|
||||
minioGetConfigKVMock = func(key string) ([]byte, error) {
|
||||
minioGetConfigKVMock = func(_ string) ([]byte, error) {
|
||||
return []byte("subnet license=mock api_key=mock proxy=http://mock.com"), nil
|
||||
}
|
||||
MinioServerInfoMock = func(ctx context.Context) (madmin.InfoMessage, error) {
|
||||
MinioServerInfoMock = func(_ context.Context) (madmin.InfoMessage, error) {
|
||||
return madmin.InfoMessage{Servers: []madmin.ServerProperties{{}}}, nil
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -23,9 +23,9 @@ import (
|
||||
|
||||
"github.com/dustin/go-humanize"
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/minio/console/api/operations"
|
||||
tieringApi "github.com/minio/console/api/operations/tiering"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
tieringApi "github.com/minio/console/restapi/operations/tiering"
|
||||
"github.com/minio/madmin-go/v3"
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -22,8 +22,8 @@ import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
tieringApi "github.com/minio/console/api/operations/tiering"
|
||||
"github.com/minio/console/models"
|
||||
tieringApi "github.com/minio/console/restapi/operations/tiering"
|
||||
"github.com/minio/madmin-go/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
@@ -89,11 +89,11 @@ func TestGetTiers(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
minioListTiersMock = func(ctx context.Context) ([]*madmin.TierConfig, error) {
|
||||
minioListTiersMock = func(_ context.Context) ([]*madmin.TierConfig, error) {
|
||||
return returnListMock, nil
|
||||
}
|
||||
|
||||
minioTierStatsMock = func(ctx context.Context) ([]madmin.TierInfo, error) {
|
||||
minioTierStatsMock = func(_ context.Context) ([]madmin.TierInfo, error) {
|
||||
return returnStatsMock, nil
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ func TestGetTiers(t *testing.T) {
|
||||
// Test-2 : getBucketLifecycle() list is empty
|
||||
returnListMockT2 := []*madmin.TierConfig{}
|
||||
|
||||
minioListTiersMock = func(ctx context.Context) ([]*madmin.TierConfig, error) {
|
||||
minioListTiersMock = func(_ context.Context) ([]*madmin.TierConfig, error) {
|
||||
return returnListMockT2, nil
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ func TestAddTier(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
// Test-1: addTier() add new Tier
|
||||
minioAddTiersMock = func(ctx context.Context, tier *madmin.TierConfig) error {
|
||||
minioAddTiersMock = func(_ context.Context, _ *madmin.TierConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ func TestAddTier(t *testing.T) {
|
||||
assert.Equal(nil, err, fmt.Sprintf("Failed on %s: Error returned", function))
|
||||
|
||||
// Test-2: addTier() error adding Tier
|
||||
minioAddTiersMock = func(ctx context.Context, tier *madmin.TierConfig) error {
|
||||
minioAddTiersMock = func(_ context.Context, _ *madmin.TierConfig) error {
|
||||
return errors.New("error setting new tier")
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ func TestUpdateTierCreds(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
// Test-1: editTierCredentials() update Tier configuration
|
||||
minioEditTiersMock = func(ctx context.Context, tierName string, creds madmin.TierCreds) error {
|
||||
minioEditTiersMock = func(_ context.Context, _ string, _ madmin.TierCreds) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ func TestUpdateTierCreds(t *testing.T) {
|
||||
assert.Equal(nil, err, fmt.Sprintf("Failed on %s: Error returned", function))
|
||||
|
||||
// Test-2: editTierCredentials() update Tier configuration failure
|
||||
minioEditTiersMock = func(ctx context.Context, tierName string, creds madmin.TierCreds) error {
|
||||
minioEditTiersMock = func(_ context.Context, _ string, _ madmin.TierCreds) error {
|
||||
return errors.New("error message")
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -41,7 +41,7 @@ func TestAdminTrace(t *testing.T) {
|
||||
|
||||
// Test-1: Serve Trace with no errors until trace finishes sending
|
||||
// define mock function behavior for minio server Trace
|
||||
minioServiceTraceMock = func(ctx context.Context, threshold int64, s3, internal, storage, os, errTrace bool) <-chan madmin.ServiceTraceInfo {
|
||||
minioServiceTraceMock = func(_ context.Context, _ int64, _, _, _, _, _ bool) <-chan madmin.ServiceTraceInfo {
|
||||
ch := make(chan madmin.ServiceTraceInfo)
|
||||
// Only success, start a routine to start reading line by line.
|
||||
go func(ch chan<- madmin.ServiceTraceInfo) {
|
||||
@@ -59,7 +59,7 @@ func TestAdminTrace(t *testing.T) {
|
||||
}
|
||||
writesCount := 1
|
||||
// mock connection WriteMessage() no error
|
||||
connWriteMessageMock = func(messageType int, data []byte) error {
|
||||
connWriteMessageMock = func(_ int, data []byte) error {
|
||||
// emulate that receiver gets the message written
|
||||
var t shortTraceMsg
|
||||
_ = json.Unmarshal(data, &t)
|
||||
@@ -84,7 +84,7 @@ func TestAdminTrace(t *testing.T) {
|
||||
}
|
||||
|
||||
// Test-2: if error happens while writing, return error
|
||||
connWriteMessageMock = func(messageType int, data []byte) error {
|
||||
connWriteMessageMock = func(_ int, _ []byte) error {
|
||||
return fmt.Errorf("error on write")
|
||||
}
|
||||
if err := startTraceInfo(ctx, mockWSConn, adminClient, TraceRequest{}); assert.Error(err) {
|
||||
@@ -93,7 +93,7 @@ func TestAdminTrace(t *testing.T) {
|
||||
|
||||
// Test-3: error happens on serviceTrace Minio, trace should stop
|
||||
// and error shall be returned.
|
||||
minioServiceTraceMock = func(ctx context.Context, threshold int64, s3, internal, storage, os, errTrace bool) <-chan madmin.ServiceTraceInfo {
|
||||
minioServiceTraceMock = func(_ context.Context, _ int64, _, _, _, _, _ bool) <-chan madmin.ServiceTraceInfo {
|
||||
ch := make(chan madmin.ServiceTraceInfo)
|
||||
// Only success, start a routine to start reading line by line.
|
||||
go func(ch chan<- madmin.ServiceTraceInfo) {
|
||||
@@ -110,7 +110,7 @@ func TestAdminTrace(t *testing.T) {
|
||||
}(ch)
|
||||
return ch
|
||||
}
|
||||
connWriteMessageMock = func(messageType int, data []byte) error {
|
||||
connWriteMessageMock = func(_ int, _ []byte) error {
|
||||
return nil
|
||||
}
|
||||
if err := startTraceInfo(ctx, mockWSConn, adminClient, TraceRequest{}); assert.Error(err) {
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -26,11 +26,11 @@ import (
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/minio/console/api/operations"
|
||||
accountApi "github.com/minio/console/api/operations/account"
|
||||
bucketApi "github.com/minio/console/api/operations/bucket"
|
||||
userApi "github.com/minio/console/api/operations/user"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
accountApi "github.com/minio/console/restapi/operations/account"
|
||||
bucketApi "github.com/minio/console/restapi/operations/bucket"
|
||||
userApi "github.com/minio/console/restapi/operations/user"
|
||||
"github.com/minio/madmin-go/v3"
|
||||
iampolicy "github.com/minio/pkg/v2/policy"
|
||||
)
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -102,15 +102,15 @@ func TestAddUser(t *testing.T) {
|
||||
}
|
||||
|
||||
// mock function response from addUser() return no error
|
||||
minioAddUserMock = func(accessKey, secretKey string) error {
|
||||
minioAddUserMock = func(_, _ string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
minioGetUserInfoMock = func(accessKey string) (madmin.UserInfo, error) {
|
||||
minioGetUserInfoMock = func(_ string) (madmin.UserInfo, error) {
|
||||
return *mockResponse, nil
|
||||
}
|
||||
|
||||
minioUpdateGroupMembersMock = func(remove madmin.GroupAddRemove) error {
|
||||
minioUpdateGroupMembersMock = func(_ madmin.GroupAddRemove) error {
|
||||
return nil
|
||||
}
|
||||
// Test-1: Add a user
|
||||
@@ -135,7 +135,7 @@ func TestAddUser(t *testing.T) {
|
||||
accessKey = "AB"
|
||||
secretKey = "ABCDEFGHIABCDEFGHI"
|
||||
// mock function response from addUser() return no error
|
||||
minioAddUserMock = func(accessKey, secretKey string) error {
|
||||
minioAddUserMock = func(_, _ string) error {
|
||||
return errors.New("error")
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ func TestAddUser(t *testing.T) {
|
||||
}
|
||||
|
||||
// Test-4: add groups function returns an error
|
||||
minioUpdateGroupMembersMock = func(remove madmin.GroupAddRemove) error {
|
||||
minioUpdateGroupMembersMock = func(_ madmin.GroupAddRemove) error {
|
||||
return errors.New("error")
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ func TestRemoveUser(t *testing.T) {
|
||||
|
||||
// Test-1: removeUser() delete a user
|
||||
// mock function response from removeUser(accessKey)
|
||||
minioRemoveUserMock = func(accessKey string) error {
|
||||
minioRemoveUserMock = func(_ string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ func TestRemoveUser(t *testing.T) {
|
||||
|
||||
// Test-2: removeUser() make sure errors are handled correctly when error on DeleteUser()
|
||||
// mock function response from removeUser(accessKey)
|
||||
minioRemoveUserMock = func(accessKey string) error {
|
||||
minioRemoveUserMock = func(_ string) error {
|
||||
return errors.New("error")
|
||||
}
|
||||
|
||||
@@ -220,11 +220,11 @@ func TestUserGroups(t *testing.T) {
|
||||
// Test-1: updateUserGroups() updates the groups for a user
|
||||
// mock function response from updateUserGroups(accessKey, groupsToAssign)
|
||||
|
||||
minioGetUserInfoMock = func(accessKey string) (madmin.UserInfo, error) {
|
||||
minioGetUserInfoMock = func(_ string) (madmin.UserInfo, error) {
|
||||
return *mockResponse, nil
|
||||
}
|
||||
|
||||
minioUpdateGroupMembersMock = func(remove madmin.GroupAddRemove) error {
|
||||
minioUpdateGroupMembersMock = func(_ madmin.GroupAddRemove) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ func TestUserGroups(t *testing.T) {
|
||||
// Test-2: updateUserGroups() make sure errors are handled correctly when error on UpdateGroupMembersMock()
|
||||
// mock function response from removeUser(accessKey)
|
||||
|
||||
minioUpdateGroupMembersMock = func(remove madmin.GroupAddRemove) error {
|
||||
minioUpdateGroupMembersMock = func(_ madmin.GroupAddRemove) error {
|
||||
return errors.New("error")
|
||||
}
|
||||
|
||||
@@ -244,11 +244,11 @@ func TestUserGroups(t *testing.T) {
|
||||
}
|
||||
|
||||
// Test-3: updateUserGroups() make sure we return the correct error when getUserInfo returns error
|
||||
minioGetUserInfoMock = func(accessKey string) (madmin.UserInfo, error) {
|
||||
minioGetUserInfoMock = func(_ string) (madmin.UserInfo, error) {
|
||||
return *mockEmptyResponse, errors.New("error getting user ")
|
||||
}
|
||||
|
||||
minioUpdateGroupMembersMock = func(remove madmin.GroupAddRemove) error {
|
||||
minioUpdateGroupMembersMock = func(_ madmin.GroupAddRemove) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -279,7 +279,7 @@ func TestGetUserInfo(t *testing.T) {
|
||||
}
|
||||
|
||||
// mock function response from getUserInfo()
|
||||
minioGetUserInfoMock = func(username string) (madmin.UserInfo, error) {
|
||||
minioGetUserInfoMock = func(_ string) (madmin.UserInfo, error) {
|
||||
return *mockResponse, nil
|
||||
}
|
||||
function := "getUserInfo()"
|
||||
@@ -294,7 +294,7 @@ func TestGetUserInfo(t *testing.T) {
|
||||
assert.Equal(mockResponse.Status, info.Status)
|
||||
|
||||
// Test-2 : getUserInfo() Return error and see that the error is handled correctly and returned
|
||||
minioGetUserInfoMock = func(username string) (madmin.UserInfo, error) {
|
||||
minioGetUserInfoMock = func(_ string) (madmin.UserInfo, error) {
|
||||
return *emptyMockResponse, errors.New("error")
|
||||
}
|
||||
_, err = getUserInfo(ctx, adminClient, userName)
|
||||
@@ -313,7 +313,7 @@ func TestSetUserStatus(t *testing.T) {
|
||||
|
||||
// Test-1: setUserStatus() update valid disabled status
|
||||
expectedStatus := "disabled"
|
||||
minioSetUserStatusMock = func(accessKey string, status madmin.AccountStatus) error {
|
||||
minioSetUserStatusMock = func(_ string, _ madmin.AccountStatus) error {
|
||||
return nil
|
||||
}
|
||||
if err := setUserStatus(ctx, adminClient, userName, expectedStatus); err != nil {
|
||||
@@ -321,7 +321,7 @@ func TestSetUserStatus(t *testing.T) {
|
||||
}
|
||||
// Test-2: setUserStatus() update valid enabled status
|
||||
expectedStatus = "enabled"
|
||||
minioSetUserStatusMock = func(accessKey string, status madmin.AccountStatus) error {
|
||||
minioSetUserStatusMock = func(_ string, _ madmin.AccountStatus) error {
|
||||
return nil
|
||||
}
|
||||
if err := setUserStatus(ctx, adminClient, userName, expectedStatus); err != nil {
|
||||
@@ -329,7 +329,7 @@ func TestSetUserStatus(t *testing.T) {
|
||||
}
|
||||
// Test-3: setUserStatus() update invalid status, should send error
|
||||
expectedStatus = "invalid"
|
||||
minioSetUserStatusMock = func(accessKey string, status madmin.AccountStatus) error {
|
||||
minioSetUserStatusMock = func(_ string, _ madmin.AccountStatus) error {
|
||||
return nil
|
||||
}
|
||||
if err := setUserStatus(ctx, adminClient, userName, expectedStatus); assert.Error(err) {
|
||||
@@ -337,7 +337,7 @@ func TestSetUserStatus(t *testing.T) {
|
||||
}
|
||||
// Test-4: setUserStatus() handler error correctly
|
||||
expectedStatus = "enabled"
|
||||
minioSetUserStatusMock = func(accessKey string, status madmin.AccountStatus) error {
|
||||
minioSetUserStatusMock = func(_ string, _ madmin.AccountStatus) error {
|
||||
return errors.New("error")
|
||||
}
|
||||
if err := setUserStatus(ctx, adminClient, userName, expectedStatus); assert.Error(err) {
|
||||
@@ -358,7 +358,7 @@ func TestUserGroupsBulk(t *testing.T) {
|
||||
|
||||
// Test-1: addUsersListToGroups() updates the groups for a users list
|
||||
// mock function response from updateUserGroups(accessKey, groupsToAssign)
|
||||
minioUpdateGroupMembersMock = func(remove madmin.GroupAddRemove) error {
|
||||
minioUpdateGroupMembersMock = func(_ madmin.GroupAddRemove) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -368,7 +368,7 @@ func TestUserGroupsBulk(t *testing.T) {
|
||||
|
||||
// Test-2: addUsersListToGroups() make sure errors are handled correctly when error on updateGroupMembers()
|
||||
// mock function response from removeUser(accessKey)
|
||||
minioUpdateGroupMembersMock = func(remove madmin.GroupAddRemove) error {
|
||||
minioUpdateGroupMembersMock = func(_ madmin.GroupAddRemove) error {
|
||||
return errors.New("error")
|
||||
}
|
||||
|
||||
@@ -527,7 +527,7 @@ func TestListUsersWithAccessToBucket(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
got, _ := listUsersWithAccessToBucket(ctx, adminClient, tt.args.bucket)
|
||||
assert.Equal(got, tt.want)
|
||||
})
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -25,7 +25,6 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/minio/console/pkg/utils"
|
||||
@@ -71,7 +70,7 @@ type MinioAdmin interface {
|
||||
heal(ctx context.Context, bucket, prefix string, healOpts madmin.HealOpts, clientToken string,
|
||||
forceStart, forceStop bool) (healStart madmin.HealStartSuccess, healTaskStatus madmin.HealTaskStatus, err error)
|
||||
// Service Accounts
|
||||
addServiceAccount(ctx context.Context, policy *iampolicy.Policy, user string, accessKey string, secretKey string) (madmin.Credentials, error)
|
||||
addServiceAccount(ctx context.Context, policy *iampolicy.Policy, user string, accessKey string, secretKey string, name string, description string, expiry *time.Time, comment string) (madmin.Credentials, error)
|
||||
listServiceAccounts(ctx context.Context, user string) (madmin.ListServiceAccountsResp, error)
|
||||
deleteServiceAccount(ctx context.Context, serviceAccount string) error
|
||||
infoServiceAccount(ctx context.Context, serviceAccount string) (madmin.InfoServiceAccountResp, error)
|
||||
@@ -98,8 +97,8 @@ type MinioAdmin interface {
|
||||
speedtest(ctx context.Context, opts madmin.SpeedtestOpts) (chan madmin.SpeedTestResult, error)
|
||||
// Site Relication
|
||||
getSiteReplicationInfo(ctx context.Context) (*madmin.SiteReplicationInfo, error)
|
||||
addSiteReplicationInfo(ctx context.Context, sites []madmin.PeerSite) (*madmin.ReplicateAddStatus, error)
|
||||
editSiteReplicationInfo(ctx context.Context, site madmin.PeerInfo) (*madmin.ReplicateEditStatus, error)
|
||||
addSiteReplicationInfo(ctx context.Context, sites []madmin.PeerSite, opts madmin.SRAddOptions) (*madmin.ReplicateAddStatus, error)
|
||||
editSiteReplicationInfo(ctx context.Context, site madmin.PeerInfo, opts madmin.SREditOptions) (*madmin.ReplicateEditStatus, error)
|
||||
deleteSiteReplicationInfo(ctx context.Context, removeReq madmin.SRRemoveReq) (*madmin.ReplicateRemoveStatus, error)
|
||||
|
||||
// Replication status
|
||||
@@ -306,16 +305,20 @@ func (ac AdminClient) getLogs(ctx context.Context, node string, lineCnt int, log
|
||||
}
|
||||
|
||||
// implements madmin.AddServiceAccount()
|
||||
func (ac AdminClient) addServiceAccount(ctx context.Context, policy *iampolicy.Policy, user string, accessKey string, secretKey string) (madmin.Credentials, error) {
|
||||
func (ac AdminClient) addServiceAccount(ctx context.Context, policy *iampolicy.Policy, user string, accessKey string, secretKey string, name string, description string, expiry *time.Time, comment string) (madmin.Credentials, error) {
|
||||
buf, err := json.Marshal(policy)
|
||||
if err != nil {
|
||||
return madmin.Credentials{}, err
|
||||
}
|
||||
return ac.Client.AddServiceAccount(ctx, madmin.AddServiceAccountReq{
|
||||
Policy: buf,
|
||||
TargetUser: user,
|
||||
AccessKey: accessKey,
|
||||
SecretKey: secretKey,
|
||||
Policy: buf,
|
||||
TargetUser: user,
|
||||
AccessKey: accessKey,
|
||||
SecretKey: secretKey,
|
||||
Name: name,
|
||||
Description: description,
|
||||
Expiration: expiry,
|
||||
Comment: comment,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -392,7 +395,7 @@ func (ac AdminClient) serverHealthInfo(ctx context.Context, healthDataTypes []ma
|
||||
var version string
|
||||
var tryCount int
|
||||
for info.Version == "" && tryCount < 10 {
|
||||
resp, version, err := ac.Client.ServerHealthInfo(ctx, healthDataTypes, deadline)
|
||||
resp, version, err := ac.Client.ServerHealthInfo(ctx, healthDataTypes, deadline, "")
|
||||
if err != nil {
|
||||
return nil, version, err
|
||||
}
|
||||
@@ -482,15 +485,6 @@ func newAdminFromCreds(accessKey, secretKey, endpoint string, tlsEnabled bool) (
|
||||
return minioClient, nil
|
||||
}
|
||||
|
||||
// httpClient is a custom http client, this client should not be called directly and instead be
|
||||
// called using GetConsoleHTTPClient() to ensure is initialized and the certificates are loaded correctly
|
||||
var httpClients = struct {
|
||||
sync.Mutex
|
||||
m map[string]*http.Client
|
||||
}{
|
||||
m: make(map[string]*http.Client),
|
||||
}
|
||||
|
||||
// isLocalAddress returns true if the url contains an IPv4/IPv6 hostname
|
||||
// that points to the local machine - FQDN are not supported
|
||||
func isLocalIPEndpoint(addr string) bool {
|
||||
@@ -520,17 +514,8 @@ func GetConsoleHTTPClient(address string, clientIP string) *http.Client {
|
||||
address = u.Hostname()
|
||||
}
|
||||
|
||||
httpClients.Lock()
|
||||
client, ok := httpClients.m[address]
|
||||
httpClients.Unlock()
|
||||
if ok {
|
||||
return client
|
||||
}
|
||||
client := PrepareConsoleHTTPClient(isLocalIPAddress(address), clientIP)
|
||||
|
||||
client = PrepareConsoleHTTPClient(isLocalIPAddress(address), clientIP)
|
||||
httpClients.Lock()
|
||||
httpClients.m[address] = client
|
||||
httpClients.Unlock()
|
||||
return client
|
||||
}
|
||||
|
||||
@@ -580,8 +565,8 @@ func (ac AdminClient) getSiteReplicationInfo(ctx context.Context) (*madmin.SiteR
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (ac AdminClient) addSiteReplicationInfo(ctx context.Context, sites []madmin.PeerSite) (*madmin.ReplicateAddStatus, error) {
|
||||
res, err := ac.Client.SiteReplicationAdd(ctx, sites)
|
||||
func (ac AdminClient) addSiteReplicationInfo(ctx context.Context, sites []madmin.PeerSite, opts madmin.SRAddOptions) (*madmin.ReplicateAddStatus, error) {
|
||||
res, err := ac.Client.SiteReplicationAdd(ctx, sites, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -594,8 +579,8 @@ func (ac AdminClient) addSiteReplicationInfo(ctx context.Context, sites []madmin
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (ac AdminClient) editSiteReplicationInfo(ctx context.Context, site madmin.PeerInfo) (*madmin.ReplicateEditStatus, error) {
|
||||
res, err := ac.Client.SiteReplicationEdit(ctx, site)
|
||||
func (ac AdminClient) editSiteReplicationInfo(ctx context.Context, site madmin.PeerInfo, opts madmin.SREditOptions) (*madmin.ReplicateEditStatus, error) {
|
||||
res, err := ac.Client.SiteReplicationEdit(ctx, site, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import "testing"
|
||||
|
||||
@@ -76,7 +76,7 @@ func Test_computeObjectURLWithoutEncode(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
got, err := computeObjectURLWithoutEncode(tt.args.bucketName, tt.args.prefix)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("computeObjectURLWithoutEncode() errors = %v, wantErr %v", err, tt.wantErr)
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
@@ -213,11 +213,6 @@ func GetSecureForceSTSHeader() bool {
|
||||
return strings.ToLower(env.Get(ConsoleSecureForceSTSHeader, "off")) == "on"
|
||||
}
|
||||
|
||||
// PublicKey implements HPKP to prevent MITM attacks with forged certificates. Default is "".
|
||||
func GetSecurePublicKey() string {
|
||||
return env.Get(ConsoleSecurePublicKey, "")
|
||||
}
|
||||
|
||||
// ReferrerPolicy allows the Referrer-Policy header with the value to be set with a custom value. Default is "".
|
||||
func GetSecureReferrerPolicy() string {
|
||||
return env.Get(ConsoleSecureReferrerPolicy, "")
|
||||
@@ -228,10 +223,6 @@ func GetSecureFeaturePolicy() string {
|
||||
return env.Get(ConsoleSecureFeaturePolicy, "")
|
||||
}
|
||||
|
||||
func GetSecureExpectCTHeader() string {
|
||||
return env.Get(ConsoleSecureExpectCTHeader, "")
|
||||
}
|
||||
|
||||
func getLogSearchAPIToken() string {
|
||||
if v := env.Get(ConsoleLogQueryAuthToken, ""); v != "" {
|
||||
return v
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"os"
|
||||
@@ -54,7 +54,7 @@ func TestGetPort(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
os.Setenv(ConsolePort, tt.args.env)
|
||||
assert.Equalf(t, tt.want, GetPort(), "GetPort()")
|
||||
os.Unsetenv(ConsolePort)
|
||||
@@ -87,7 +87,7 @@ func TestGetTLSPort(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
os.Setenv(ConsoleTLSPort, tt.args.env)
|
||||
assert.Equalf(t, tt.want, GetTLSPort(), "GetTLSPort()")
|
||||
os.Unsetenv(ConsoleTLSPort)
|
||||
@@ -120,7 +120,7 @@ func TestGetSecureAllowedHosts(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
os.Setenv(ConsoleSecureAllowedHosts, tt.args.env)
|
||||
assert.Equalf(t, tt.want, GetSecureAllowedHosts(), "GetSecureAllowedHosts()")
|
||||
os.Unsetenv(ConsoleSecureAllowedHosts)
|
||||
@@ -153,7 +153,7 @@ func TestGetSecureHostsProxyHeaders(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
os.Setenv(ConsoleSecureHostsProxyHeaders, tt.args.env)
|
||||
assert.Equalf(t, tt.want, GetSecureHostsProxyHeaders(), "GetSecureHostsProxyHeaders()")
|
||||
os.Unsetenv(ConsoleSecureHostsProxyHeaders)
|
||||
@@ -186,7 +186,7 @@ func TestGetSecureSTSSeconds(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
os.Setenv(ConsoleSecureSTSSeconds, tt.args.env)
|
||||
assert.Equalf(t, tt.want, GetSecureSTSSeconds(), "GetSecureSTSSeconds()")
|
||||
os.Unsetenv(ConsoleSecureSTSSeconds)
|
||||
@@ -219,7 +219,7 @@ func Test_getLogSearchAPIToken(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
os.Setenv(ConsoleLogQueryAuthToken, tt.args.env)
|
||||
assert.Equalf(t, tt.want, getLogSearchAPIToken(), "getLogSearchAPIToken()")
|
||||
os.Setenv(ConsoleLogQueryAuthToken, tt.args.env)
|
||||
@@ -252,7 +252,7 @@ func Test_getPrometheusURL(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
os.Setenv(PrometheusURL, tt.args.env)
|
||||
assert.Equalf(t, tt.want, getPrometheusURL(), "getPrometheusURL()")
|
||||
os.Setenv(PrometheusURL, tt.args.env)
|
||||
@@ -285,7 +285,7 @@ func Test_getPrometheusJobID(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
os.Setenv(PrometheusJobID, tt.args.env)
|
||||
assert.Equalf(t, tt.want, getPrometheusJobID(), "getPrometheusJobID()")
|
||||
os.Setenv(PrometheusJobID, tt.args.env)
|
||||
@@ -318,7 +318,7 @@ func Test_getMaxConcurrentUploadsLimit(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
os.Setenv(ConsoleMaxConcurrentUploads, tt.args.env)
|
||||
assert.Equalf(t, tt.want, getMaxConcurrentUploadsLimit(), "getMaxConcurrentUploadsLimit()")
|
||||
os.Unsetenv(ConsoleMaxConcurrentUploads)
|
||||
@@ -351,7 +351,7 @@ func Test_getMaxConcurrentDownloadsLimit(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
os.Setenv(ConsoleMaxConcurrentDownloads, tt.args.env)
|
||||
assert.Equalf(t, tt.want, getMaxConcurrentDownloadsLimit(), "getMaxConcurrentDownloadsLimit()")
|
||||
os.Unsetenv(ConsoleMaxConcurrentDownloads)
|
||||
@@ -384,7 +384,7 @@ func Test_getConsoleDevMode(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
os.Setenv(ConsoleDevMode, tt.args.env)
|
||||
assert.Equalf(t, tt.want, getConsoleDevMode(), "getConsoleDevMode()")
|
||||
os.Unsetenv(ConsoleDevMode)
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
// This file is safe to edit. Once it exists it will not be overwritten
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -35,22 +35,24 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/minio/console/pkg/logger"
|
||||
"github.com/minio/console/pkg/utils"
|
||||
"github.com/minio/minio-go/v7/pkg/credentials"
|
||||
|
||||
"github.com/klauspost/compress/gzhttp"
|
||||
|
||||
portal_ui "github.com/minio/console/portal-ui"
|
||||
portal_ui "github.com/minio/console/web-app"
|
||||
"github.com/minio/pkg/v2/env"
|
||||
"github.com/minio/pkg/v2/mimedb"
|
||||
xnet "github.com/minio/pkg/v2/net"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/minio/console/api/operations"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/pkg/auth"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
"github.com/unrolled/secure"
|
||||
)
|
||||
|
||||
@@ -80,7 +82,7 @@ func configureFlags(api *operations.ConsoleAPI) {
|
||||
|
||||
func configureAPI(api *operations.ConsoleAPI) http.Handler {
|
||||
// Applies when the "x-token" header is set
|
||||
api.KeyAuth = func(token string, scopes []string) (*models.Principal, error) {
|
||||
api.KeyAuth = func(token string, _ []string) (*models.Principal, error) {
|
||||
// we are validating the session token by decrypting the claims inside, if the operation succeed that means the jwt
|
||||
// was generated and signed by us in the first place
|
||||
if token == "Anonymous" {
|
||||
@@ -101,7 +103,7 @@ func configureAPI(api *operations.ConsoleAPI) http.Handler {
|
||||
CustomStyleOb: claims.CustomStyleOB,
|
||||
}, nil
|
||||
}
|
||||
api.AnonymousAuth = func(s string) (*models.Principal, error) {
|
||||
api.AnonymousAuth = func(_ string) (*models.Principal, error) {
|
||||
return &models.Principal{}, nil
|
||||
}
|
||||
|
||||
@@ -192,11 +194,7 @@ func setupMiddlewares(handler http.Handler) http.Handler {
|
||||
|
||||
func ContextMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
requestID, err := utils.NewUUID()
|
||||
if err != nil && err != auth.ErrNoAuthToken {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
requestID := uuid.NewString()
|
||||
ctx := context.WithValue(r.Context(), utils.ContextRequestID, requestID)
|
||||
ctx = context.WithValue(ctx, utils.ContextRequestUserAgent, r.UserAgent())
|
||||
ctx = context.WithValue(ctx, utils.ContextRequestHost, r.Host)
|
||||
@@ -256,10 +254,8 @@ func setupGlobalMiddleware(handler http.Handler) http.Handler {
|
||||
BrowserXssFilter: GetSecureBrowserXSSFilter(),
|
||||
ContentSecurityPolicy: GetSecureContentSecurityPolicy(),
|
||||
ContentSecurityPolicyReportOnly: GetSecureContentSecurityPolicyReportOnly(),
|
||||
PublicKey: GetSecurePublicKey(),
|
||||
ReferrerPolicy: GetSecureReferrerPolicy(),
|
||||
FeaturePolicy: GetSecureFeaturePolicy(),
|
||||
ExpectCTHeader: GetSecureExpectCTHeader(),
|
||||
IsDevelopment: false,
|
||||
}
|
||||
secureMiddleware := secure.New(secureOptions)
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"os"
|
||||
@@ -70,7 +70,7 @@ func Test_parseSubPath(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
assert.Equalf(t, tt.want, parseSubPath(tt.args.v), "parseSubPath(%v)", tt.args.v)
|
||||
})
|
||||
}
|
||||
@@ -115,7 +115,7 @@ func Test_getSubPath(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
t.Setenv(SubPath, tt.args.envValue)
|
||||
defer os.Unsetenv(SubPath)
|
||||
subPathOnce = sync.Once{}
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
// list of all console environment constants
|
||||
const (
|
||||
556
api/custom-server.go
Normal file
556
api/custom-server.go
Normal file
@@ -0,0 +1,556 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2023 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 api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/go-openapi/runtime/flagext"
|
||||
"github.com/go-openapi/swag"
|
||||
flags "github.com/jessevdk/go-flags"
|
||||
"golang.org/x/net/netutil"
|
||||
|
||||
"github.com/minio/console/api/operations"
|
||||
)
|
||||
|
||||
const (
|
||||
schemeHTTP = "http"
|
||||
schemeHTTPS = "https"
|
||||
schemeUnix = "unix"
|
||||
)
|
||||
|
||||
var defaultSchemes []string
|
||||
|
||||
func init() {
|
||||
defaultSchemes = []string{
|
||||
schemeHTTP,
|
||||
}
|
||||
}
|
||||
|
||||
// NewServer creates a new api console server but does not configure it
|
||||
func NewServer(api *operations.ConsoleAPI) *Server {
|
||||
s := new(Server)
|
||||
|
||||
s.shutdown = make(chan struct{})
|
||||
s.api = api
|
||||
s.interrupt = make(chan os.Signal, 1)
|
||||
return s
|
||||
}
|
||||
|
||||
// ConfigureAPI configures the API and handlers.
|
||||
func (s *Server) ConfigureAPI() {
|
||||
if s.api != nil {
|
||||
s.handler = configureAPI(s.api)
|
||||
}
|
||||
}
|
||||
|
||||
// ConfigureFlags configures the additional flags defined by the handlers. Needs to be called before the parser.Parse
|
||||
func (s *Server) ConfigureFlags() {
|
||||
if s.api != nil {
|
||||
configureFlags(s.api)
|
||||
}
|
||||
}
|
||||
|
||||
// Server for the console API
|
||||
type Server struct {
|
||||
EnabledListeners []string `long:"scheme" description:"the listeners to enable, this can be repeated and defaults to the schemes in the swagger spec"`
|
||||
CleanupTimeout time.Duration `long:"cleanup-timeout" description:"grace period for which to wait before killing idle connections" default:"10s"`
|
||||
GracefulTimeout time.Duration `long:"graceful-timeout" description:"grace period for which to wait before shutting down the server" default:"15s"`
|
||||
MaxHeaderSize flagext.ByteSize `long:"max-header-size" description:"controls the maximum number of bytes the server will read parsing the request header's keys and values, including the request line. It does not limit the size of the request body." default:"1MiB"`
|
||||
|
||||
SocketPath flags.Filename `long:"socket-path" description:"the unix socket to listen on" default:"/var/run/console.sock"`
|
||||
domainSocketL net.Listener
|
||||
|
||||
Host string `long:"host" description:"the IP to listen on" default:"localhost" env:"HOST"`
|
||||
Port int `long:"port" description:"the port to listen on for insecure connections, defaults to a random value" env:"PORT"`
|
||||
ListenLimit int `long:"listen-limit" description:"limit the number of outstanding requests"`
|
||||
KeepAlive time.Duration `long:"keep-alive" description:"sets the TCP keep-alive timeouts on accepted connections. It prunes dead TCP connections ( e.g. closing laptop mid-download)" default:"3m"`
|
||||
ReadTimeout time.Duration `long:"read-timeout" description:"maximum duration before timing out read of the request" default:"30s"`
|
||||
WriteTimeout time.Duration `long:"write-timeout" description:"maximum duration before timing out write of the response" default:"60s"`
|
||||
httpServerL []net.Listener
|
||||
|
||||
TLSHost string `long:"tls-host" description:"the IP to listen on for tls, when not specified it's the same as --host" env:"TLS_HOST"`
|
||||
TLSPort int `long:"tls-port" description:"the port to listen on for secure connections, defaults to a random value" env:"TLS_PORT"`
|
||||
TLSCertificate flags.Filename `long:"tls-certificate" description:"the certificate to use for secure connections" env:"TLS_CERTIFICATE"`
|
||||
TLSCertificateKey flags.Filename `long:"tls-key" description:"the private key to use for secure connections" env:"TLS_PRIVATE_KEY"`
|
||||
TLSCACertificate flags.Filename `long:"tls-ca" description:"the certificate authority file to be used with mutual tls auth" env:"TLS_CA_CERTIFICATE"`
|
||||
TLSListenLimit int `long:"tls-listen-limit" description:"limit the number of outstanding requests"`
|
||||
TLSKeepAlive time.Duration `long:"tls-keep-alive" description:"sets the TCP keep-alive timeouts on accepted connections. It prunes dead TCP connections ( e.g. closing laptop mid-download)"`
|
||||
TLSReadTimeout time.Duration `long:"tls-read-timeout" description:"maximum duration before timing out read of the request"`
|
||||
TLSWriteTimeout time.Duration `long:"tls-write-timeout" description:"maximum duration before timing out write of the response"`
|
||||
httpsServerL []net.Listener
|
||||
|
||||
api *operations.ConsoleAPI
|
||||
handler http.Handler
|
||||
hasListeners bool
|
||||
shutdown chan struct{}
|
||||
shuttingDown int32
|
||||
interrupted bool
|
||||
interrupt chan os.Signal
|
||||
}
|
||||
|
||||
// Logf logs message either via defined user logger or via system one if no user logger is defined.
|
||||
func (s *Server) Logf(f string, args ...interface{}) {
|
||||
if s.api != nil && s.api.Logger != nil {
|
||||
s.api.Logger(f, args...)
|
||||
} else {
|
||||
log.Printf(f, args...)
|
||||
}
|
||||
}
|
||||
|
||||
// Fatalf logs message either via defined user logger or via system one if no user logger is defined.
|
||||
// Exits with non-zero status after printing
|
||||
func (s *Server) Fatalf(f string, args ...interface{}) {
|
||||
if s.api != nil && s.api.Logger != nil {
|
||||
s.api.Logger(f, args...)
|
||||
os.Exit(1)
|
||||
}
|
||||
log.Fatalf(f, args...)
|
||||
}
|
||||
|
||||
// SetAPI configures the server with the specified API. Needs to be called before Serve
|
||||
func (s *Server) SetAPI(api *operations.ConsoleAPI) {
|
||||
if api == nil {
|
||||
s.api = nil
|
||||
s.handler = nil
|
||||
return
|
||||
}
|
||||
|
||||
s.api = api
|
||||
s.handler = configureAPI(api)
|
||||
}
|
||||
|
||||
func (s *Server) hasScheme(scheme string) bool {
|
||||
schemes := s.EnabledListeners
|
||||
if len(schemes) == 0 {
|
||||
schemes = defaultSchemes
|
||||
}
|
||||
|
||||
for _, v := range schemes {
|
||||
if v == scheme {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Serve the api
|
||||
func (s *Server) Serve() (err error) {
|
||||
if !s.hasListeners {
|
||||
if err = s.Listen(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// set default handler, if none is set
|
||||
if s.handler == nil {
|
||||
if s.api == nil {
|
||||
return errors.New("can't create the default handler, as no api is set")
|
||||
}
|
||||
|
||||
s.SetHandler(s.api.Serve(nil))
|
||||
}
|
||||
|
||||
wg := new(sync.WaitGroup)
|
||||
once := new(sync.Once)
|
||||
signalNotify(s.interrupt)
|
||||
go handleInterrupt(once, s)
|
||||
|
||||
servers := []*http.Server{}
|
||||
|
||||
if s.hasScheme(schemeUnix) {
|
||||
domainSocket := new(http.Server)
|
||||
domainSocket.MaxHeaderBytes = int(s.MaxHeaderSize)
|
||||
domainSocket.Handler = s.handler
|
||||
if int64(s.CleanupTimeout) > 0 {
|
||||
domainSocket.IdleTimeout = s.CleanupTimeout
|
||||
}
|
||||
|
||||
configureServer(domainSocket, "unix", string(s.SocketPath))
|
||||
|
||||
servers = append(servers, domainSocket)
|
||||
wg.Add(1)
|
||||
s.Logf("Serving console at unix://%s", s.SocketPath)
|
||||
go func(l net.Listener) {
|
||||
defer wg.Done()
|
||||
if err := domainSocket.Serve(l); err != nil && err != http.ErrServerClosed {
|
||||
s.Fatalf("%v", err)
|
||||
}
|
||||
s.Logf("Stopped serving console at unix://%s", s.SocketPath)
|
||||
}(s.domainSocketL)
|
||||
}
|
||||
|
||||
if s.hasScheme(schemeHTTP) {
|
||||
httpServer := new(http.Server)
|
||||
httpServer.MaxHeaderBytes = int(s.MaxHeaderSize)
|
||||
httpServer.ReadTimeout = s.ReadTimeout
|
||||
httpServer.WriteTimeout = s.WriteTimeout
|
||||
httpServer.SetKeepAlivesEnabled(int64(s.KeepAlive) > 0)
|
||||
if s.ListenLimit > 0 {
|
||||
for i := range s.httpServerL {
|
||||
s.httpServerL[i] = netutil.LimitListener(s.httpServerL[i], s.ListenLimit)
|
||||
}
|
||||
}
|
||||
|
||||
if int64(s.CleanupTimeout) > 0 {
|
||||
httpServer.IdleTimeout = s.CleanupTimeout
|
||||
}
|
||||
|
||||
httpServer.Handler = s.handler
|
||||
|
||||
configureServer(httpServer, "http", s.httpServerL[0].Addr().String())
|
||||
|
||||
servers = append(servers, httpServer)
|
||||
s.Logf("Serving console at http://%s", s.httpServerL[0].Addr())
|
||||
for i := range s.httpServerL {
|
||||
wg.Add(1)
|
||||
go func(l net.Listener) {
|
||||
defer wg.Done()
|
||||
if err := httpServer.Serve(l); err != nil && err != http.ErrServerClosed {
|
||||
s.Fatalf("%v", err)
|
||||
}
|
||||
s.Logf("Stopped serving console at http://%s", l.Addr())
|
||||
}(s.httpServerL[i])
|
||||
}
|
||||
}
|
||||
|
||||
if s.hasScheme(schemeHTTPS) {
|
||||
httpsServer := new(http.Server)
|
||||
httpsServer.MaxHeaderBytes = int(s.MaxHeaderSize)
|
||||
httpsServer.ReadTimeout = s.TLSReadTimeout
|
||||
httpsServer.WriteTimeout = s.TLSWriteTimeout
|
||||
httpsServer.SetKeepAlivesEnabled(int64(s.TLSKeepAlive) > 0)
|
||||
if s.TLSListenLimit > 0 {
|
||||
for i := range s.httpsServerL {
|
||||
s.httpsServerL[i] = netutil.LimitListener(s.httpsServerL[i], s.TLSListenLimit)
|
||||
}
|
||||
}
|
||||
if int64(s.CleanupTimeout) > 0 {
|
||||
httpsServer.IdleTimeout = s.CleanupTimeout
|
||||
}
|
||||
httpsServer.Handler = s.handler
|
||||
|
||||
// Inspired by https://blog.bracebin.com/achieving-perfect-ssl-labs-score-with-go
|
||||
httpsServer.TLSConfig = &tls.Config{
|
||||
// Causes servers to use Go's default ciphersuite preferences,
|
||||
// which are tuned to avoid attacks. Does nothing on clients.
|
||||
PreferServerCipherSuites: true,
|
||||
// Only use curves which have assembly implementations
|
||||
// https://github.com/golang/go/tree/master/src/crypto/elliptic
|
||||
CurvePreferences: []tls.CurveID{tls.CurveP256},
|
||||
// Use modern tls mode https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility
|
||||
NextProtos: []string{"h2", "http/1.1"},
|
||||
// https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet#Rule_-_Only_Support_Strong_Protocols
|
||||
MinVersion: tls.VersionTLS12,
|
||||
// These ciphersuites support Forward Secrecy: https://en.wikipedia.org/wiki/Forward_secrecy
|
||||
CipherSuites: []uint16{
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
|
||||
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
|
||||
},
|
||||
}
|
||||
|
||||
// build standard config from server options
|
||||
if s.TLSCertificate != "" && s.TLSCertificateKey != "" {
|
||||
httpsServer.TLSConfig.Certificates = make([]tls.Certificate, 1)
|
||||
httpsServer.TLSConfig.Certificates[0], err = tls.LoadX509KeyPair(string(s.TLSCertificate), string(s.TLSCertificateKey))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if s.TLSCACertificate != "" {
|
||||
// include specified CA certificate
|
||||
caCert, caCertErr := os.ReadFile(string(s.TLSCACertificate))
|
||||
if caCertErr != nil {
|
||||
return caCertErr
|
||||
}
|
||||
caCertPool := x509.NewCertPool()
|
||||
ok := caCertPool.AppendCertsFromPEM(caCert)
|
||||
if !ok {
|
||||
return fmt.Errorf("cannot parse CA certificate")
|
||||
}
|
||||
httpsServer.TLSConfig.ClientCAs = caCertPool
|
||||
httpsServer.TLSConfig.ClientAuth = tls.RequireAndVerifyClientCert
|
||||
}
|
||||
|
||||
// call custom TLS configurator
|
||||
configureTLS(httpsServer.TLSConfig)
|
||||
|
||||
if len(httpsServer.TLSConfig.Certificates) == 0 && httpsServer.TLSConfig.GetCertificate == nil {
|
||||
// after standard and custom config are passed, this ends up with no certificate
|
||||
if s.TLSCertificate == "" {
|
||||
if s.TLSCertificateKey == "" {
|
||||
s.Fatalf("the required flags `--tls-certificate` and `--tls-key` were not specified")
|
||||
}
|
||||
s.Fatalf("the required flag `--tls-certificate` was not specified")
|
||||
}
|
||||
if s.TLSCertificateKey == "" {
|
||||
s.Fatalf("the required flag `--tls-key` was not specified")
|
||||
}
|
||||
// this happens with a wrong custom TLS configurator
|
||||
s.Fatalf("no certificate was configured for TLS")
|
||||
}
|
||||
|
||||
configureServer(httpsServer, "https", s.httpsServerL[0].Addr().String())
|
||||
|
||||
servers = append(servers, httpsServer)
|
||||
s.Logf("Serving console at https://%s", s.httpsServerL[0].Addr())
|
||||
for i := range s.httpsServerL {
|
||||
wg.Add(1)
|
||||
go func(l net.Listener) {
|
||||
defer wg.Done()
|
||||
if err := httpsServer.Serve(l); err != nil && err != http.ErrServerClosed {
|
||||
s.Fatalf("%v", err)
|
||||
}
|
||||
s.Logf("Stopped serving console at https://%s", l.Addr())
|
||||
}(tls.NewListener(s.httpsServerL[i], httpsServer.TLSConfig))
|
||||
}
|
||||
}
|
||||
|
||||
wg.Add(1)
|
||||
go s.handleShutdown(wg, &servers)
|
||||
|
||||
wg.Wait()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Listen creates the listeners for the server
|
||||
func (s *Server) Listen() error {
|
||||
if s.hasListeners { // already done this
|
||||
return nil
|
||||
}
|
||||
|
||||
if s.hasScheme(schemeHTTPS) {
|
||||
// Use http host if https host wasn't defined
|
||||
if s.TLSHost == "" {
|
||||
s.TLSHost = s.Host
|
||||
}
|
||||
// Use http listen limit if https listen limit wasn't defined
|
||||
if s.TLSListenLimit == 0 {
|
||||
s.TLSListenLimit = s.ListenLimit
|
||||
}
|
||||
// Use http tcp keep alive if https tcp keep alive wasn't defined
|
||||
if int64(s.TLSKeepAlive) == 0 {
|
||||
s.TLSKeepAlive = s.KeepAlive
|
||||
}
|
||||
// Use http read timeout if https read timeout wasn't defined
|
||||
if int64(s.TLSReadTimeout) == 0 {
|
||||
s.TLSReadTimeout = s.ReadTimeout
|
||||
}
|
||||
// Use http write timeout if https write timeout wasn't defined
|
||||
if int64(s.TLSWriteTimeout) == 0 {
|
||||
s.TLSWriteTimeout = s.WriteTimeout
|
||||
}
|
||||
}
|
||||
|
||||
if s.hasScheme(schemeUnix) {
|
||||
domSockListener, err := net.Listen("unix", string(s.SocketPath))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.domainSocketL = domSockListener
|
||||
}
|
||||
|
||||
lookup := func(addr string) []net.IP {
|
||||
ips, err := net.LookupIP(addr)
|
||||
if err == nil {
|
||||
return ips
|
||||
}
|
||||
return []net.IP{net.ParseIP(addr)}
|
||||
}
|
||||
|
||||
convert := func(ip net.IP) (string, string) {
|
||||
if ip == nil {
|
||||
return "", "tcp"
|
||||
}
|
||||
proto := "tcp4"
|
||||
if ip.To4() == nil {
|
||||
proto = "tcp6"
|
||||
}
|
||||
return ip.String(), proto
|
||||
}
|
||||
|
||||
if s.hasScheme(schemeHTTP) {
|
||||
for _, ip := range lookup(s.Host) {
|
||||
host, proto := convert(ip)
|
||||
listener, err := net.Listen(proto, net.JoinHostPort(host, strconv.Itoa(s.Port)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if s.Host == "" || s.Port == 0 {
|
||||
h, p, err := swag.SplitHostPort(listener.Addr().String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Host = h
|
||||
s.Port = p
|
||||
}
|
||||
s.httpServerL = append(s.httpServerL, listener)
|
||||
}
|
||||
}
|
||||
|
||||
if s.hasScheme(schemeHTTPS) {
|
||||
for _, ip := range lookup(s.TLSHost) {
|
||||
host, proto := convert(ip)
|
||||
tlsListener, err := net.Listen(proto, net.JoinHostPort(host, strconv.Itoa(s.TLSPort)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if s.TLSHost == "" || s.TLSPort == 0 {
|
||||
sh, sp, err := swag.SplitHostPort(tlsListener.Addr().String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.TLSHost = sh
|
||||
s.TLSPort = sp
|
||||
}
|
||||
s.httpsServerL = append(s.httpsServerL, tlsListener)
|
||||
}
|
||||
}
|
||||
|
||||
s.hasListeners = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// Shutdown server and clean up resources
|
||||
func (s *Server) Shutdown() error {
|
||||
if atomic.CompareAndSwapInt32(&s.shuttingDown, 0, 1) {
|
||||
close(s.shutdown)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) handleShutdown(wg *sync.WaitGroup, serversPtr *[]*http.Server) {
|
||||
// wg.Done must occur last, after s.api.ServerShutdown()
|
||||
// (to preserve old behavior)
|
||||
defer wg.Done()
|
||||
|
||||
<-s.shutdown
|
||||
|
||||
servers := *serversPtr
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), s.GracefulTimeout)
|
||||
defer cancel()
|
||||
|
||||
// first execute the pre-shutdown hook
|
||||
s.api.PreServerShutdown()
|
||||
|
||||
shutdownChan := make(chan bool)
|
||||
for i := range servers {
|
||||
server := servers[i]
|
||||
go func() {
|
||||
var success bool
|
||||
defer func() {
|
||||
shutdownChan <- success
|
||||
}()
|
||||
if err := server.Shutdown(ctx); err != nil {
|
||||
// Error from closing listeners, or context timeout:
|
||||
s.Logf("HTTP server Shutdown: %v", err)
|
||||
} else {
|
||||
success = true
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// Wait until all listeners have successfully shut down before calling ServerShutdown
|
||||
success := true
|
||||
for range servers {
|
||||
success = success && <-shutdownChan
|
||||
}
|
||||
if success {
|
||||
s.api.ServerShutdown()
|
||||
}
|
||||
}
|
||||
|
||||
// GetHandler returns a handler useful for testing
|
||||
func (s *Server) GetHandler() http.Handler {
|
||||
return s.handler
|
||||
}
|
||||
|
||||
// SetHandler allows for setting a http handler on this server
|
||||
func (s *Server) SetHandler(handler http.Handler) {
|
||||
s.handler = handler
|
||||
}
|
||||
|
||||
// UnixListener returns the domain socket listener
|
||||
func (s *Server) UnixListener() (net.Listener, error) {
|
||||
if !s.hasListeners {
|
||||
if err := s.Listen(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return s.domainSocketL, nil
|
||||
}
|
||||
|
||||
// HTTPListener returns the http listener
|
||||
func (s *Server) HTTPListener() ([]net.Listener, error) {
|
||||
if !s.hasListeners {
|
||||
if err := s.Listen(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return s.httpServerL, nil
|
||||
}
|
||||
|
||||
// TLSListener returns the https listener
|
||||
func (s *Server) TLSListener() ([]net.Listener, error) {
|
||||
if !s.hasListeners {
|
||||
if err := s.Listen(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return s.httpsServerL, nil
|
||||
}
|
||||
|
||||
func handleInterrupt(once *sync.Once, s *Server) {
|
||||
once.Do(func() {
|
||||
for range s.interrupt {
|
||||
if s.interrupted {
|
||||
s.Logf("Server already shutting down")
|
||||
continue
|
||||
}
|
||||
s.interrupted = true
|
||||
s.Logf("Shutting down... ")
|
||||
if err := s.Shutdown(); err != nil {
|
||||
s.Logf("HTTP server Shutdown: %v", err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func signalNotify(interrupt chan<- os.Signal) {
|
||||
signal.Notify(interrupt, syscall.SIGINT, syscall.SIGTERM)
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
// Package restapi MinIO Console Server
|
||||
// Package api MinIO Console Server
|
||||
//
|
||||
// Schemes:
|
||||
// http
|
||||
@@ -35,4 +35,4 @@
|
||||
// - application/json
|
||||
//
|
||||
// swagger:meta
|
||||
package restapi
|
||||
package api
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -53,6 +53,7 @@ var (
|
||||
ErrAvoidSelfAccountDelete = errors.New("logged in user cannot be deleted by itself")
|
||||
ErrAccessDenied = errors.New("access denied")
|
||||
ErrOauth2Provider = errors.New("unable to contact configured identity provider")
|
||||
ErrOauth2Login = errors.New("unable to login using configured identity provider")
|
||||
ErrNonUniqueAccessKey = errors.New("access key already in use")
|
||||
ErrRemoteTierExists = errors.New("specified remote tier already exists")
|
||||
ErrRemoteTierNotFound = errors.New("specified remote tier was not found")
|
||||
@@ -84,10 +85,12 @@ type CodedAPIError struct {
|
||||
func ErrorWithContext(ctx context.Context, err ...interface{}) *CodedAPIError {
|
||||
errorCode := 500
|
||||
errorMessage := ErrDefault.Error()
|
||||
var detailedMessage string
|
||||
var err1 error
|
||||
var exists bool
|
||||
if len(err) > 0 {
|
||||
if err1, exists = err[0].(error); exists {
|
||||
detailedMessage = err1.Error()
|
||||
var lastError error
|
||||
if len(err) > 1 {
|
||||
if err2, lastExists := err[1].(error); lastExists {
|
||||
@@ -105,15 +108,22 @@ func ErrorWithContext(ctx context.Context, err ...interface{}) *CodedAPIError {
|
||||
errorMessage = ErrNotFound.Error()
|
||||
}
|
||||
if errors.Is(err1, ErrInvalidLogin) {
|
||||
detailedMessage = ""
|
||||
errorCode = 401
|
||||
errorMessage = ErrInvalidLogin.Error()
|
||||
}
|
||||
if strings.Contains(strings.ToLower(err1.Error()), ErrAccessDenied.Error()) {
|
||||
errorCode = 403
|
||||
errorMessage = err1.Error()
|
||||
}
|
||||
// If the last error is ErrInvalidLogin, this is a login failure
|
||||
if errors.Is(lastError, ErrInvalidLogin) {
|
||||
detailedMessage = ""
|
||||
errorCode = 401
|
||||
errorMessage = err1.Error()
|
||||
}
|
||||
if strings.Contains(err1.Error(), ErrLoginNotAllowed.Error()) {
|
||||
detailedMessage = ""
|
||||
errorCode = 400
|
||||
errorMessage = ErrLoginNotAllowed.Error()
|
||||
}
|
||||
@@ -207,6 +217,7 @@ func ErrorWithContext(ctx context.Context, err ...interface{}) *CodedAPIError {
|
||||
errorMessage = ErrAccessDenied.Error()
|
||||
}
|
||||
if madmin.ToErrorResponse(err1).Code == "InvalidAccessKeyId" {
|
||||
|
||||
errorCode = 401
|
||||
errorMessage = ErrInvalidSession.Error()
|
||||
}
|
||||
@@ -257,7 +268,7 @@ func ErrorWithContext(ctx context.Context, err ...interface{}) *CodedAPIError {
|
||||
}
|
||||
}
|
||||
}
|
||||
return &CodedAPIError{Code: errorCode, APIError: &models.APIError{Message: errorMessage, DetailedMessage: err1.Error()}}
|
||||
return &CodedAPIError{Code: errorCode, APIError: &models.APIError{Message: errorMessage, DetailedMessage: detailedMessage}}
|
||||
}
|
||||
|
||||
// Error receives an errors object and parse it against k8sErrors, returns the right errors code paired with a generic errors message
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -44,37 +44,38 @@ func TestError(t *testing.T) {
|
||||
}
|
||||
|
||||
appErrors := map[string]expectedError{
|
||||
"ErrDefault": {code: 500, err: ErrDefault},
|
||||
"ErrInvalidLogin": {code: 401, err: ErrInvalidLogin},
|
||||
"ErrForbidden": {code: 403, err: ErrForbidden},
|
||||
"ErrFileTooLarge": {code: 413, err: ErrFileTooLarge},
|
||||
"ErrInvalidSession": {code: 401, err: ErrInvalidSession},
|
||||
"ErrNotFound": {code: 404, err: ErrNotFound},
|
||||
"ErrGroupAlreadyExists": {code: 400, err: ErrGroupAlreadyExists},
|
||||
"ErrInvalidErasureCodingValue": {code: 400, err: ErrInvalidErasureCodingValue},
|
||||
"ErrBucketBodyNotInRequest": {code: 400, err: ErrBucketBodyNotInRequest},
|
||||
"ErrBucketNameNotInRequest": {code: 400, err: ErrBucketNameNotInRequest},
|
||||
"ErrGroupBodyNotInRequest": {code: 400, err: ErrGroupBodyNotInRequest},
|
||||
"ErrGroupNameNotInRequest": {code: 400, err: ErrGroupNameNotInRequest},
|
||||
"ErrPolicyNameNotInRequest": {code: 400, err: ErrPolicyNameNotInRequest},
|
||||
"ErrPolicyBodyNotInRequest": {code: 400, err: ErrPolicyBodyNotInRequest},
|
||||
"ErrInvalidEncryptionAlgorithm": {code: 500, err: ErrInvalidEncryptionAlgorithm},
|
||||
"ErrSSENotConfigured": {code: 404, err: ErrSSENotConfigured},
|
||||
"ErrBucketLifeCycleNotConfigured": {code: 404, err: ErrBucketLifeCycleNotConfigured},
|
||||
"ErrChangePassword": {code: 403, err: ErrChangePassword},
|
||||
"ErrInvalidLicense": {code: 404, err: ErrInvalidLicense},
|
||||
"ErrLicenseNotFound": {code: 404, err: ErrLicenseNotFound},
|
||||
"ErrAvoidSelfAccountDelete": {code: 403, err: ErrAvoidSelfAccountDelete},
|
||||
"ErrAccessDenied": {code: 403, err: ErrAccessDenied},
|
||||
"ErrDefault": {code: 500, err: ErrDefault},
|
||||
|
||||
"ErrForbidden": {code: 403, err: ErrForbidden},
|
||||
"ErrFileTooLarge": {code: 413, err: ErrFileTooLarge},
|
||||
"ErrInvalidSession": {code: 401, err: ErrInvalidSession},
|
||||
"ErrNotFound": {code: 404, err: ErrNotFound},
|
||||
"ErrGroupAlreadyExists": {code: 400, err: ErrGroupAlreadyExists},
|
||||
"ErrInvalidErasureCodingValue": {code: 400, err: ErrInvalidErasureCodingValue},
|
||||
"ErrBucketBodyNotInRequest": {code: 400, err: ErrBucketBodyNotInRequest},
|
||||
"ErrBucketNameNotInRequest": {code: 400, err: ErrBucketNameNotInRequest},
|
||||
"ErrGroupBodyNotInRequest": {code: 400, err: ErrGroupBodyNotInRequest},
|
||||
"ErrGroupNameNotInRequest": {code: 400, err: ErrGroupNameNotInRequest},
|
||||
"ErrPolicyNameNotInRequest": {code: 400, err: ErrPolicyNameNotInRequest},
|
||||
"ErrPolicyBodyNotInRequest": {code: 400, err: ErrPolicyBodyNotInRequest},
|
||||
"ErrInvalidEncryptionAlgorithm": {code: 500, err: ErrInvalidEncryptionAlgorithm},
|
||||
"ErrSSENotConfigured": {code: 404, err: ErrSSENotConfigured},
|
||||
"ErrBucketLifeCycleNotConfigured": {code: 404, err: ErrBucketLifeCycleNotConfigured},
|
||||
"ErrChangePassword": {code: 403, err: ErrChangePassword},
|
||||
"ErrInvalidLicense": {code: 404, err: ErrInvalidLicense},
|
||||
"ErrLicenseNotFound": {code: 404, err: ErrLicenseNotFound},
|
||||
"ErrAvoidSelfAccountDelete": {code: 403, err: ErrAvoidSelfAccountDelete},
|
||||
|
||||
"ErrNonUniqueAccessKey": {code: 500, err: ErrNonUniqueAccessKey},
|
||||
"ErrRemoteTierExists": {code: 400, err: ErrRemoteTierExists},
|
||||
"ErrRemoteTierNotFound": {code: 400, err: ErrRemoteTierNotFound},
|
||||
"ErrRemoteTierUppercase": {code: 400, err: ErrRemoteTierUppercase},
|
||||
"ErrRemoteTierBucketNotFound": {code: 400, err: ErrRemoteTierBucketNotFound},
|
||||
"ErrRemoteInvalidCredentials": {code: 403, err: ErrRemoteInvalidCredentials},
|
||||
"ErrTooFewNodes": {code: 500, err: ErrTooFewNodes},
|
||||
"ErrUnableToGetTenantUsage": {code: 500, err: ErrUnableToGetTenantUsage},
|
||||
"ErrTooManyNodes": {code: 500, err: ErrTooManyNodes},
|
||||
"ErrTooFewNodes": {code: 500, err: ErrTooFewNodes},
|
||||
"ErrAccessDenied": {code: 403, err: ErrAccessDenied},
|
||||
"ErrTooFewAvailableNodes": {code: 500, err: ErrTooFewAvailableNodes},
|
||||
"ErrFewerThanFourNodes": {code: 500, err: ErrFewerThanFourNodes},
|
||||
"ErrUnableToGetTenantLogs": {code: 500, err: ErrUnableToGetTenantLogs},
|
||||
@@ -96,6 +97,7 @@ func TestError(t *testing.T) {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
tests = append(tests,
|
||||
testError{
|
||||
name: "passing multiple errors but ErrInvalidLogin is last",
|
||||
@@ -104,11 +106,23 @@ func TestError(t *testing.T) {
|
||||
},
|
||||
want: &CodedAPIError{
|
||||
Code: int(401),
|
||||
APIError: &models.APIError{Message: ErrDefault.Error(), DetailedMessage: ErrDefault.Error()},
|
||||
APIError: &models.APIError{Message: ErrDefault.Error(), DetailedMessage: ""},
|
||||
},
|
||||
})
|
||||
tests = append(tests,
|
||||
testError{
|
||||
name: "login error omits detailedMessage",
|
||||
args: args{
|
||||
err: []interface{}{ErrInvalidLogin},
|
||||
},
|
||||
want: &CodedAPIError{
|
||||
Code: int(401),
|
||||
APIError: &models.APIError{Message: ErrInvalidLogin.Error(), DetailedMessage: ""},
|
||||
},
|
||||
})
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
got := Error(tt.args.err...)
|
||||
assert.Equalf(t, tt.want.Code, got.Code, "Error(%v) Got (%v)", tt.want.Code, got.Code)
|
||||
assert.Equalf(t, tt.want.APIError.DetailedMessage, got.APIError.DetailedMessage, "Error(%s) Got (%s)", tt.want.APIError.DetailedMessage, got.APIError.DetailedMessage)
|
||||
@@ -138,7 +152,7 @@ func TestErrorWithContext(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
assert.Equalf(t, tt.want, ErrorWithContext(tt.args.ctx, tt.args.err...), "ErrorWithContext(%v, %v)", tt.args.ctx, tt.args.err)
|
||||
})
|
||||
}
|
||||
@@ -14,12 +14,14 @@
|
||||
// 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 restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/minio/console/pkg/subnet"
|
||||
"github.com/minio/pkg/v2/licverifier"
|
||||
"github.com/minio/pkg/v2/subnet"
|
||||
)
|
||||
|
||||
type SubnetPlan int
|
||||
@@ -43,8 +45,18 @@ func (sp SubnetPlan) String() string {
|
||||
|
||||
var InstanceLicensePlan = PlanAGPL
|
||||
|
||||
func getLicenseInfo(client http.Client, license string) (*licverifier.LicenseInfo, error) {
|
||||
lv := subnet.LicenseValidator{
|
||||
Client: client,
|
||||
ExpiryGracePeriod: 0,
|
||||
}
|
||||
lv.Init(getConsoleDevMode())
|
||||
return lv.ParseLicense(license)
|
||||
}
|
||||
|
||||
func fetchLicensePlan() {
|
||||
licenseInfo, err := subnet.ParseLicense(GetConsoleHTTPClient("", "127.0.0.1"), os.Getenv(EnvSubnetLicense))
|
||||
client := GetConsoleHTTPClient("", "127.0.0.1")
|
||||
licenseInfo, err := getLicenseInfo(*client, os.Getenv(EnvSubnetLicense))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -58,7 +58,7 @@ type Context struct {
|
||||
TLSCertificate, TLSKey, TLSca string
|
||||
}
|
||||
|
||||
// Load loads restapi Context from command line context.
|
||||
// Load loads api Context from command line context.
|
||||
func (c *Context) Load(ctx *cli.Context) error {
|
||||
*c = Context{
|
||||
Host: ctx.String("host"),
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package restapi
|
||||
package api
|
||||
|
||||
import (
|
||||
"flag"
|
||||
@@ -85,7 +85,7 @@ func TestContext_Load(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
c := &Context{}
|
||||
|
||||
fs := flag.NewFlagSet("flags", flag.ContinueOnError)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user