Compare commits
144 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b21aceed7b | ||
|
|
3b82079b8c | ||
|
|
854468a713 | ||
|
|
1d69024e3a | ||
|
|
67082e1b1d | ||
|
|
95f622a597 | ||
|
|
37d7f0025b | ||
|
|
137170521c | ||
|
|
ba9f4d094b | ||
|
|
c62fecbac1 | ||
|
|
3d858ac04a | ||
|
|
573049e53c | ||
|
|
9625d4679c | ||
|
|
790c6b0e2f | ||
|
|
ff433549b6 | ||
|
|
ccebc17f3f | ||
|
|
7c82306cc0 | ||
|
|
4d458c4f8c | ||
|
|
aadc66a739 | ||
|
|
ed73d99590 | ||
|
|
410b4555e3 | ||
|
|
2cae87aaed | ||
|
|
b82441813d | ||
|
|
5dfba3f6c8 | ||
|
|
1b9902a5be | ||
|
|
d6944ccd3b | ||
|
|
ebaa1947de | ||
|
|
9d61af7060 | ||
|
|
1b225e0901 | ||
|
|
7a864d2631 | ||
|
|
dfca19092a | ||
|
|
61cf397a02 | ||
|
|
d31528e2b5 | ||
|
|
8fd1e0db9c | ||
|
|
3d27cd2bd3 | ||
|
|
2269af829f | ||
|
|
8658ac2914 | ||
|
|
19f034adf4 | ||
|
|
3034803054 | ||
|
|
403f8caa8b | ||
|
|
cb886f0130 | ||
|
|
951a041bc5 | ||
|
|
8d203f4797 | ||
|
|
401a051b8e | ||
|
|
2e300dba7d | ||
|
|
4cdb862ae6 | ||
|
|
e6f4ac1e6c | ||
|
|
137ff41be2 | ||
|
|
e7665fae85 | ||
|
|
4b262f2a89 | ||
|
|
4ab1cf1bf2 | ||
|
|
27689a17f3 | ||
|
|
2b6d5e5128 | ||
|
|
64e38ca8d3 | ||
|
|
d85b693751 | ||
|
|
00752d2bb1 | ||
|
|
4cc57fe440 | ||
|
|
4c16789bab | ||
|
|
2ade4ca1cf | ||
|
|
52ee9bb49b | ||
|
|
c93f1ba564 | ||
|
|
b6f818bdd3 | ||
|
|
77eff6ce91 | ||
|
|
15a9e72192 | ||
|
|
9f070d9ebb | ||
|
|
2077004bd3 | ||
|
|
9067e85b55 | ||
|
|
c30f1cee92 | ||
|
|
a060ddbef2 | ||
|
|
8f202ef5a4 | ||
|
|
0fdf5ee0fc | ||
|
|
875647577a | ||
|
|
46d504cddc | ||
|
|
27ac6db99a | ||
|
|
3c8de3a8cf | ||
|
|
e6086afdbe | ||
|
|
59f5f6a9f0 | ||
|
|
67b0261b0b | ||
|
|
e104c4a48e | ||
|
|
ba051dfb7d | ||
|
|
c26928516d | ||
|
|
4135b27cfd | ||
|
|
755e0b49e9 | ||
|
|
605f4d4a62 | ||
|
|
33acf45264 | ||
|
|
f229fee3ee | ||
|
|
21b3ed67af | ||
|
|
90cadc76bb | ||
|
|
b13b6db6f7 | ||
|
|
1d88bb491d | ||
|
|
13cf3e6fa1 | ||
|
|
50c1fe8298 | ||
|
|
39eeedec2c | ||
|
|
0f2a09d5f1 | ||
|
|
6cf657a0e1 | ||
|
|
1ba2627810 | ||
|
|
1ab37e0b00 | ||
|
|
63dac87a75 | ||
|
|
7bf3a6e3f1 | ||
|
|
2fd4be91ad | ||
|
|
296129db02 | ||
|
|
5ece5ba8a7 | ||
|
|
96e9bce331 | ||
|
|
ddd4ab54a7 | ||
|
|
849132fa19 | ||
|
|
d23a7a4fba | ||
|
|
af2a64d0d2 | ||
|
|
6cb8c51754 | ||
|
|
48313d6cd9 | ||
|
|
bb8460a118 | ||
|
|
3e55683c2c | ||
|
|
d86fc2f73c | ||
|
|
24a2edf6a3 | ||
|
|
07bef3280d | ||
|
|
fa465d0ef3 | ||
|
|
1f1537fd60 | ||
|
|
597855364c | ||
|
|
4306d0f661 | ||
|
|
4c01be21ca | ||
|
|
7ec391b6e0 | ||
|
|
8c82124a57 | ||
|
|
0ae0338a8f | ||
|
|
e05c724553 | ||
|
|
deda36a8b5 | ||
|
|
d32ab25ffd | ||
|
|
2332a13477 | ||
|
|
c417cc31c8 | ||
|
|
ec47df3cc1 | ||
|
|
a09be99ae6 | ||
|
|
2debb11f03 | ||
|
|
ba3a0d6cd6 | ||
|
|
4e8763995e | ||
|
|
dfe7e5aa58 | ||
|
|
d2ed375efb | ||
|
|
cabb60bd3f | ||
|
|
0980bd38e7 | ||
|
|
6e1a23e0d6 | ||
|
|
6ea1d51913 | ||
|
|
4369e6e779 | ||
|
|
79a476712f | ||
|
|
4e38a54dd8 | ||
|
|
33610a5269 | ||
|
|
a5a8d2ef62 | ||
|
|
d357ef9bcb |
2
.github/workflows/go.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.16.x]
|
||||
go-version: [1.16.x, 1.17.x]
|
||||
os: [ubuntu-latest]
|
||||
steps:
|
||||
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
|
||||
|
||||
39
.github/workflows/integration.yml
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
name: Go
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Integration Tests with Latest Distributed MinIO
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.16.x]
|
||||
os: [ubuntu-latest]
|
||||
steps:
|
||||
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Build on ${{ matrix.os }}
|
||||
env:
|
||||
GO111MODULE: on
|
||||
GOOS: linux
|
||||
CGO_ENABLED: 0
|
||||
run: |
|
||||
wget -O /tmp/minio https://dl.minio.io/server/minio/release/linux-amd64/minio
|
||||
chmod +x /tmp/minio
|
||||
mkdir -p /tmp/certs-dir
|
||||
/tmp/minio server --quiet -S /tmp/certs-dir /tmp/fs{1...4} &
|
||||
go test github.com/minio/console/integration/...
|
||||
2
.github/workflows/lint.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.16.x]
|
||||
go-version: [1.16.x, 1.17.x]
|
||||
os: [ubuntu-latest]
|
||||
steps:
|
||||
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
|
||||
|
||||
@@ -86,7 +86,7 @@ nfpms:
|
||||
dockers:
|
||||
- image_templates:
|
||||
- "minio/console:{{ .Tag }}-amd64"
|
||||
use_buildx: true
|
||||
use: buildx
|
||||
goarch: amd64
|
||||
dockerfile: Dockerfile.release
|
||||
extra_files:
|
||||
@@ -97,7 +97,7 @@ dockers:
|
||||
- "--build-arg=TAG={{ .Tag }}"
|
||||
- image_templates:
|
||||
- "minio/console:{{ .Tag }}-ppc64le"
|
||||
use_buildx: true
|
||||
use: buildx
|
||||
goarch: ppc64le
|
||||
dockerfile: Dockerfile.release
|
||||
extra_files:
|
||||
@@ -108,7 +108,7 @@ dockers:
|
||||
- "--build-arg=TAG={{ .Tag }}"
|
||||
- image_templates:
|
||||
- "minio/console:{{ .Tag }}-s390x"
|
||||
use_buildx: true
|
||||
use: buildx
|
||||
goarch: s390x
|
||||
dockerfile: Dockerfile.release
|
||||
extra_files:
|
||||
@@ -119,7 +119,7 @@ dockers:
|
||||
- "--build-arg=TAG={{ .Tag }}"
|
||||
- image_templates:
|
||||
- "minio/console:{{ .Tag }}-arm64"
|
||||
use_buildx: true
|
||||
use: buildx
|
||||
goarch: arm64
|
||||
goos: linux
|
||||
dockerfile: Dockerfile.release
|
||||
@@ -131,7 +131,7 @@ dockers:
|
||||
- "--build-arg=TAG={{ .Tag }}"
|
||||
- image_templates:
|
||||
- "quay.io/minio/console:{{ .Tag }}-amd64"
|
||||
use_buildx: true
|
||||
use: buildx
|
||||
goarch: amd64
|
||||
dockerfile: Dockerfile.release
|
||||
extra_files:
|
||||
@@ -142,7 +142,7 @@ dockers:
|
||||
- "--build-arg=TAG={{ .Tag }}"
|
||||
- image_templates:
|
||||
- "quay.io/minio/console:{{ .Tag }}-ppc64le"
|
||||
use_buildx: true
|
||||
use: buildx
|
||||
goarch: ppc64le
|
||||
dockerfile: Dockerfile.release
|
||||
extra_files:
|
||||
@@ -153,7 +153,7 @@ dockers:
|
||||
- "--build-arg=TAG={{ .Tag }}"
|
||||
- image_templates:
|
||||
- "quay.io/minio/console:{{ .Tag }}-s390x"
|
||||
use_buildx: true
|
||||
use: buildx
|
||||
goarch: s390x
|
||||
dockerfile: Dockerfile.release
|
||||
extra_files:
|
||||
@@ -164,7 +164,7 @@ dockers:
|
||||
- "--build-arg=TAG={{ .Tag }}"
|
||||
- image_templates:
|
||||
- "quay.io/minio/console:{{ .Tag }}-arm64"
|
||||
use_buildx: true
|
||||
use: buildx
|
||||
goarch: arm64
|
||||
goos: linux
|
||||
dockerfile: Dockerfile.release
|
||||
|
||||
14
go.mod
@@ -5,7 +5,6 @@ go 1.16
|
||||
require (
|
||||
github.com/blang/semver/v4 v4.0.0
|
||||
github.com/cheggaaa/pb/v3 v3.0.6
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/go-openapi/errors v0.19.9
|
||||
github.com/go-openapi/loads v0.20.2
|
||||
@@ -19,19 +18,18 @@ require (
|
||||
github.com/minio/cli v1.22.0
|
||||
github.com/minio/direct-csi v1.3.5-0.20210601185811-f7776f7961bf
|
||||
github.com/minio/kes v0.11.0
|
||||
github.com/minio/madmin-go v1.0.17
|
||||
github.com/minio/madmin-go v1.1.6
|
||||
github.com/minio/mc v0.0.0-20210626002108-cebf3318546f
|
||||
github.com/minio/minio-go/v7 v7.0.13-0.20210715203016-9e713532886e
|
||||
github.com/minio/operator v0.0.0-20210803012017-0f43eee7fd7a
|
||||
github.com/minio/operator/logsearchapi v0.0.0-20210803012017-0f43eee7fd7a
|
||||
github.com/minio/pkg v1.0.8
|
||||
github.com/minio/minio-go/v7 v7.0.14
|
||||
github.com/minio/operator v0.0.0-20211011212245-31460bbbc4b7
|
||||
github.com/minio/operator/logsearchapi v0.0.0-20211011212245-31460bbbc4b7
|
||||
github.com/minio/pkg v1.1.5
|
||||
github.com/minio/selfupdate v0.3.1
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
|
||||
github.com/rs/xid v1.2.1
|
||||
github.com/secure-io/sio-go v0.3.1
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/unrolled/secure v1.0.7
|
||||
github.com/unrolled/secure v1.0.9
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||
|
||||
60
go.sum
@@ -14,6 +14,7 @@ cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.60.0/go.mod h1:yw2G51M9IfRboUH61Us8GqCeF1PzPblB823Mn2q2eAU=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
@@ -196,8 +197,6 @@ github.com/cockroachdb/cockroach-go/v2 v2.0.3 h1:ZA346ACHIZctef6trOTwBAEvPVm1k0u
|
||||
github.com/cockroachdb/cockroach-go/v2 v2.0.3/go.mod h1:hAuDgiVgDVkfirP9JnhXEfcXEPRKBpYdGz+l7mvYSzw=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/codegangsta/negroni v1.0.0 h1:+aYywywx4bnKXWvoWtRfJ91vC59NbEhEY03sZjQhbVY=
|
||||
github.com/codegangsta/negroni v1.0.0/go.mod h1:v0y3T5G7Y1UlFfyxFn/QLRU4a2EuNau2iZY63YTKWo0=
|
||||
github.com/container-storage-interface/spec v1.1.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4=
|
||||
github.com/container-storage-interface/spec v1.3.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4=
|
||||
github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
@@ -206,8 +205,6 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk=
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
@@ -416,6 +413,7 @@ github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4=
|
||||
github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ=
|
||||
@@ -555,6 +553,7 @@ github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hf
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200507031123-427632fa3b1c/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/rpmpack v0.0.0-20191226140753-aa36bfddb3a0/go.mod h1:RaTPr0KUf2K7fnZYLNDrr8rxAamWs3iNywJLtQ2AzBg=
|
||||
github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||
@@ -630,6 +629,7 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
|
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
@@ -879,8 +879,8 @@ github.com/minio/filepath v1.0.0/go.mod h1:/nRZA2ldl5z6jT9/KQuvZcQlxZIMQoFFQPvEX
|
||||
github.com/minio/kes v0.11.0 h1:8ma6OCVSxKT50b1uYXLJro3m7PmZtCLxBaTddQexI5k=
|
||||
github.com/minio/kes v0.11.0/go.mod h1:mTF1Bv8YVEtQqF/B7Felp4tLee44Pp+dgI0rhCvgNg8=
|
||||
github.com/minio/madmin-go v1.0.12/go.mod h1:BK+z4XRx7Y1v8SFWXsuLNqQqnq5BO/axJ8IDJfgyvfs=
|
||||
github.com/minio/madmin-go v1.0.17 h1:VMEn4nMKf0X3uNH0u+fZcn17KSwVkQGwyER/igG556E=
|
||||
github.com/minio/madmin-go v1.0.17/go.mod h1:4nl9hvLWFnwCjkLfZSsZXEHgDODa2XSG6xGlIZyQ2oA=
|
||||
github.com/minio/madmin-go v1.1.6 h1:L53ALIbAilaEvuvMMT4XkJpd6mtaorkMBwCQ+zraYBA=
|
||||
github.com/minio/madmin-go v1.1.6/go.mod h1:vw+c3/u+DeVKqReEavo///Cl2OO8nt5s4ee843hJeLs=
|
||||
github.com/minio/mc v0.0.0-20210626002108-cebf3318546f h1:hyFvo5hSFw2K417YvDr/vAKlgCG69uTuhZW/5LNdL0U=
|
||||
github.com/minio/mc v0.0.0-20210626002108-cebf3318546f/go.mod h1:tuaonkPjVApCXkbtKENHBtsqUf7YTV33qmFrC+Pgp5g=
|
||||
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
|
||||
@@ -888,16 +888,18 @@ github.com/minio/md5-simd v1.1.1 h1:9ojcLbuZ4gXbB2sX53MKn8JUZ0sB/2wfwsEcRw+I08U=
|
||||
github.com/minio/md5-simd v1.1.1/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
|
||||
github.com/minio/minio-go/v7 v7.0.11-0.20210302210017-6ae69c73ce78/go.mod h1:mTh2uJuAbEqdhMVl6CMIIZLUeiMiWtJR4JB8/5g2skw=
|
||||
github.com/minio/minio-go/v7 v7.0.11-0.20210607181445-e162fdb8e584/go.mod h1:WoyW+ySKAKjY98B9+7ZbI8z8S3jaxaisdcvj9TGlazA=
|
||||
github.com/minio/minio-go/v7 v7.0.13-0.20210715203016-9e713532886e h1:aVnxKPpUI1gVeEf9vC+QEt8OxMXiiNMeUWcrBM62oDU=
|
||||
github.com/minio/minio-go/v7 v7.0.13-0.20210715203016-9e713532886e/go.mod h1:S23iSP5/gbMwtxeY5FM71R+TkAYyzEdoNEDDwpt8yWs=
|
||||
github.com/minio/operator v0.0.0-20210803012017-0f43eee7fd7a h1:jvEyFZBLo1mIc5YTg+AIAieDkzoAnc9+j4yT5kZO15E=
|
||||
github.com/minio/operator v0.0.0-20210803012017-0f43eee7fd7a/go.mod h1:zQqn6VGT46xlSpVXh1I/VZRv+eSgHtVu6URdg71YKX8=
|
||||
github.com/minio/operator/logsearchapi v0.0.0-20210803012017-0f43eee7fd7a h1:tnyzzgWP0PXM1nrwHtlyawuBguY+6R9/yee0bezbGDY=
|
||||
github.com/minio/operator/logsearchapi v0.0.0-20210803012017-0f43eee7fd7a/go.mod h1:R+38Pf3wfm+JMiyLPb/r8OMrBm0vK2hZgUT4y4aYoSY=
|
||||
github.com/minio/minio-go/v7 v7.0.14 h1:T7cw8P586gVwEEd0y21kTYtloD576XZgP62N8pE130s=
|
||||
github.com/minio/minio-go/v7 v7.0.14/go.mod h1:S23iSP5/gbMwtxeY5FM71R+TkAYyzEdoNEDDwpt8yWs=
|
||||
github.com/minio/operator v0.0.0-20211011212245-31460bbbc4b7 h1:dkfuMNslMjGoJ4ArAMSoQhidYNdm3SgzLBP+f96O3/E=
|
||||
github.com/minio/operator v0.0.0-20211011212245-31460bbbc4b7/go.mod h1:lDpuz8nwsfhKlfiBaA3Z8AW019fWEAjO2gltfLbdorE=
|
||||
github.com/minio/operator/logsearchapi v0.0.0-20211011212245-31460bbbc4b7 h1:vFtQqCt67ETp0JAkOKRWTKkgwFv14Vc1jJSxmQ8wJE0=
|
||||
github.com/minio/operator/logsearchapi v0.0.0-20211011212245-31460bbbc4b7/go.mod h1:R+38Pf3wfm+JMiyLPb/r8OMrBm0vK2hZgUT4y4aYoSY=
|
||||
github.com/minio/pkg v1.0.3/go.mod h1:obU54TZ9QlMv0TRaDgQ/JTzf11ZSXxnSfLrm4tMtBP8=
|
||||
github.com/minio/pkg v1.0.4/go.mod h1:obU54TZ9QlMv0TRaDgQ/JTzf11ZSXxnSfLrm4tMtBP8=
|
||||
github.com/minio/pkg v1.0.8 h1:lWQwHSeYlvnRoPpO+wS0I4mL6c00ABxBgbGjSmjwOi4=
|
||||
github.com/minio/pkg v1.0.8/go.mod h1:32x/3OmGB0EOi1N+3ggnp+B5VFkSBBB9svPMVfpnf14=
|
||||
github.com/minio/pkg v1.0.11/go.mod h1:32x/3OmGB0EOi1N+3ggnp+B5VFkSBBB9svPMVfpnf14=
|
||||
github.com/minio/pkg v1.1.5 h1:phwKkJBQdVLyxOXC3RChPVGLtebplzQJ5jJ3l/HBvnk=
|
||||
github.com/minio/pkg v1.1.5/go.mod h1:32x/3OmGB0EOi1N+3ggnp+B5VFkSBBB9svPMVfpnf14=
|
||||
github.com/minio/selfupdate v0.3.1 h1:BWEFSNnrZVMUWXbXIgLDNDjbejkmpAmZvy/nCz1HlEs=
|
||||
github.com/minio/selfupdate v0.3.1/go.mod h1:b8ThJzzH7u2MkF6PcIra7KaXO9Khf6alWPvMSyTDCFM=
|
||||
github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
|
||||
@@ -955,8 +957,9 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS
|
||||
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
@@ -970,8 +973,9 @@ github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
|
||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4=
|
||||
github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
github.com/onsi/ginkgo v1.16.1 h1:foqVmeWDD6yYpK+Yz3fHyNIxFYNxswxqNFjSKe+vI54=
|
||||
github.com/onsi/ginkgo v1.16.1/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
@@ -980,8 +984,9 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
|
||||
github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
|
||||
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs=
|
||||
github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.11.0 h1:+CqWgvj0OZycCaqclBD1pxKHAU+tOkHmQIWvDHq2aug=
|
||||
github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
@@ -1026,8 +1031,6 @@ github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndr
|
||||
github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo=
|
||||
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.44.1/go.mod h1:3WYi4xqXxGGXWDdQIITnLNmuDzO5n6wYva9spVhR4fg=
|
||||
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.46.0/go.mod h1:3WYi4xqXxGGXWDdQIITnLNmuDzO5n6wYva9spVhR4fg=
|
||||
github.com/prometheus-operator/prometheus-operator/pkg/client v0.46.0/go.mod h1:k4BrWlVQQsvBiTcDnKEMgyh/euRxyxgrHdur/ZX/sdA=
|
||||
@@ -1063,8 +1066,9 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
|
||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=
|
||||
github.com/quasilyte/go-ruleguard v0.1.2-0.20200318202121-b00d7a75d3d8/go.mod h1:CGFX09Ci3pq9QZdj86B+VGIdNj4VyCo2iPOGS9esB/k=
|
||||
@@ -1106,6 +1110,7 @@ github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAm
|
||||
github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada h1:WokF3GuxBeL+n4Lk4Fa8v9mbdjlrl7bHuneF4N1bk2I=
|
||||
github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc=
|
||||
github.com/shirou/gopsutil/v3 v3.21.4/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw=
|
||||
github.com/shirou/gopsutil/v3 v3.21.5/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw=
|
||||
github.com/shirou/gopsutil/v3 v3.21.6 h1:vU7jrp1Ic/2sHB7w6UNs7MIkn7ebVtTb5D9j45o9VYE=
|
||||
github.com/shirou/gopsutil/v3 v3.21.6/go.mod h1:JfVbDpIBLVzT8oKbvMg9P3wEIMDDpVn+LwHTKj0ST88=
|
||||
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
|
||||
@@ -1209,10 +1214,12 @@ github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4A
|
||||
github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/ultraware/funlen v0.0.2/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
|
||||
github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA=
|
||||
github.com/unrolled/secure v1.0.7 h1:BcQHp3iKZyZCKj5gRqwQG+5urnGBF00wGgoPPwtheVQ=
|
||||
github.com/unrolled/secure v1.0.7/go.mod h1:uGc1OcRF8gCVBA+ANksKmvM85Hka6SZtQIbrKc3sHS4=
|
||||
github.com/unrolled/secure v1.0.9 h1:BWRuEb1vDrBFFDdbCnKkof3gZ35I/bnHGyt0LB0TNyQ=
|
||||
github.com/unrolled/secure v1.0.9/go.mod h1:fO+mEan+FLB0CdEnHf6Q4ZZVNqG+5fuLFnP8p0BXDPI=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=
|
||||
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
|
||||
github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s=
|
||||
@@ -1392,6 +1399,7 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
@@ -1424,6 +1432,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180816055513-1c9583448a9c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -1491,14 +1500,16 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe h1:WdX7u8s3yOigWAhHEaDl8r9G+4XwFQEQFtBMYyN+kXQ=
|
||||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
|
||||
@@ -1600,8 +1611,10 @@ golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roY
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210114065538-d78b04bdf963/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
@@ -1634,6 +1647,7 @@ google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.25.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@@ -1674,6 +1688,7 @@ google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfG
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200626011028-ee7919e894b5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a h1:pOwg4OoaRYScjmR4LlLgdtnyoHYTSAVhhqe5uPdpII8=
|
||||
google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
|
||||
@@ -1716,7 +1731,6 @@ gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/square/go-jose.v2 v2.3.1 h1:SK5KegNXmKmqE342YYN2qPHEnUYeoMiXXl1poUlI+o4=
|
||||
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
|
||||
5
iconos/Lambda.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="227.615" height="256" viewBox="0 0 227.615 256">
|
||||
<g id="lambda-icn" transform="translate(-89.849 -94.42)">
|
||||
<path id="Trazado_442" data-name="Trazado 442" d="M71.316,41.17a15.363,15.363,0,0,0,0,30.727c23.352,0,32.017,14.872,40.928,34.353l1.475,3.134c1.229,2.643,3.872,8.542,7.436,16.408L37.271,274.264A15.363,15.363,0,0,0,64,289.382l72.823-128.623c19.481,44,44,99.494,44.431,100.415A58.2,58.2,0,0,0,252.3,294.544a15.375,15.375,0,0,0-9.1-29.375,27.531,27.531,0,0,1-33.861-16.593c-2.458-5.531-59.856-135.751-67.6-152.282l-1.352-2.95C132.462,76.506,116.3,41.17,71.316,41.17Z" transform="translate(54.335 53.25)" fill="#020202"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 692 B |
7
iconos/Tiers.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="236.312" height="256" viewBox="0 0 236.312 256">
|
||||
<g id="tiers-icn" transform="translate(-34.003 -3)">
|
||||
<g id="tiers" transform="translate(34.003 3)">
|
||||
<path id="Trazado_441" data-name="Trazado 441" d="M122.387,3a9.847,9.847,0,0,0-5.154,1.308L8.925,66.851a9.847,9.847,0,0,0,0,17.039l33.4,19.289-33.4,19.289a9.847,9.847,0,0,0,0,17.058l33.4,19.27-33.4,19.289a9.847,9.847,0,0,0,0,17.058l108.308,62.54a9.847,9.847,0,0,0,9.846,0l108.308-62.54a9.847,9.847,0,0,0,0-17.058l-33.4-19.289,33.4-19.27a9.847,9.847,0,0,0,0-17.058l-33.4-19.289,33.4-19.289a9.847,9.847,0,0,0,0-17.039L127.079,4.311A9.847,9.847,0,0,0,122.387,3ZM62.041,114.563l55.192,31.866a9.847,9.847,0,0,0,9.846,0l55.192-31.866,28.5,16.443L122.156,182.16,33.54,131.006Zm-.02,55.617,55.212,31.866a9.847,9.847,0,0,0,9.846,0l55.212-31.866,28.481,16.443-88.615,51.155L33.54,186.622Z" transform="translate(-4 -3)"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 942 B |
340
integration/buckets_test.go
Normal file
@@ -0,0 +1,340 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package integration
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-openapi/loads"
|
||||
"github.com/minio/console/restapi"
|
||||
"github.com/minio/console/restapi/operations"
|
||||
|
||||
"github.com/minio/console/models"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var token string
|
||||
|
||||
func initConsoleServer() (*restapi.Server, error) {
|
||||
|
||||
//os.Setenv("CONSOLE_MINIO_SERVER", "localhost:9000")
|
||||
|
||||
swaggerSpec, err := loads.Embedded(restapi.SwaggerJSON, restapi.FlatSwaggerJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
noLog := func(string, ...interface{}) {
|
||||
// nothing to log
|
||||
}
|
||||
|
||||
// Initialize MinIO loggers
|
||||
restapi.LogInfo = noLog
|
||||
restapi.LogError = noLog
|
||||
|
||||
api := operations.NewConsoleAPI(swaggerSpec)
|
||||
api.Logger = noLog
|
||||
|
||||
server := restapi.NewServer(api)
|
||||
// register all APIs
|
||||
server.ConfigureAPI()
|
||||
|
||||
//restapi.GlobalRootCAs, restapi.GlobalPublicCerts, restapi.GlobalTLSCertsManager = globalRootCAs, globalPublicCerts, globalTLSCerts
|
||||
|
||||
consolePort, _ := strconv.Atoi("9090")
|
||||
|
||||
server.Host = "0.0.0.0"
|
||||
server.Port = consolePort
|
||||
restapi.Port = "9090"
|
||||
restapi.Hostname = "0.0.0.0"
|
||||
|
||||
return server, nil
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
|
||||
// start console server
|
||||
go func() {
|
||||
fmt.Println("start server")
|
||||
srv, err := initConsoleServer()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
log.Println("init fail")
|
||||
return
|
||||
}
|
||||
srv.Serve()
|
||||
|
||||
}()
|
||||
|
||||
fmt.Println("sleeping")
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
client := &http.Client{
|
||||
Timeout: 2 * time.Second,
|
||||
}
|
||||
// get login credentials
|
||||
|
||||
requestData := map[string]string{
|
||||
"accessKey": "minioadmin",
|
||||
"secretKey": "minioadmin",
|
||||
}
|
||||
|
||||
requestDataJSON, _ := json.Marshal(requestData)
|
||||
|
||||
requestDataBody := bytes.NewReader(requestDataJSON)
|
||||
|
||||
request, err := http.NewRequest("POST", "http://localhost:9090/api/v1/login", requestDataBody)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
request.Header.Add("Content-Type", "application/json")
|
||||
|
||||
response, err := client.Do(request)
|
||||
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
if response != nil {
|
||||
bodyBytes, _ := ioutil.ReadAll(response.Body)
|
||||
|
||||
loginResponse := models.LoginResponse{}
|
||||
err = json.Unmarshal(bodyBytes, &loginResponse)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
token = loginResponse.SessionID
|
||||
|
||||
}
|
||||
|
||||
code := m.Run()
|
||||
|
||||
requestDataAdd := map[string]interface{}{
|
||||
"name": "test1",
|
||||
}
|
||||
|
||||
requestDataJSON, _ = json.Marshal(requestDataAdd)
|
||||
|
||||
requestDataBody = bytes.NewReader(requestDataJSON)
|
||||
|
||||
// get list of buckets
|
||||
request, err = http.NewRequest("DELETE", "http://localhost:9090/api/v1/buckets/test1", requestDataBody)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
|
||||
request.Header.Add("Content-Type", "application/json")
|
||||
|
||||
response, err = client.Do(request)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
if response != nil {
|
||||
fmt.Println("DELETE StatusCode:", response.StatusCode)
|
||||
}
|
||||
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
func TestAddBucket(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
client := &http.Client{
|
||||
Timeout: 2 * time.Second,
|
||||
}
|
||||
|
||||
requestDataAdd := map[string]interface{}{
|
||||
"name": "test1",
|
||||
"versioning": false,
|
||||
"locking": false,
|
||||
}
|
||||
|
||||
requestDataJSON, _ := json.Marshal(requestDataAdd)
|
||||
|
||||
requestDataBody := bytes.NewReader(requestDataJSON)
|
||||
|
||||
// get list of buckets
|
||||
request, err := http.NewRequest("POST", "http://localhost:9090/api/v1/buckets", requestDataBody)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
|
||||
request.Header.Add("Content-Type", "application/json")
|
||||
|
||||
response, err := client.Do(request)
|
||||
assert.Nil(err)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
if response != nil {
|
||||
assert.Equal(201, response.StatusCode, "Status Code is incorrect")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBucketVersioning(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
client := &http.Client{
|
||||
Timeout: 2 * time.Second,
|
||||
}
|
||||
|
||||
request, err := http.NewRequest("GET", "http://localhost:9090/api/v1/session", nil)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
|
||||
|
||||
response, err := client.Do(request)
|
||||
assert.Nil(err)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
var distributedSystem bool
|
||||
|
||||
if response != nil {
|
||||
|
||||
bodyBytes, _ := ioutil.ReadAll(response.Body)
|
||||
|
||||
sessionResponse := models.SessionResponse{}
|
||||
err = json.Unmarshal(bodyBytes, &sessionResponse)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
distributedSystem = sessionResponse.DistributedMode
|
||||
|
||||
}
|
||||
|
||||
requestDataVersioning := map[string]interface{}{
|
||||
"name": "test2",
|
||||
"versioning": true,
|
||||
"locking": false,
|
||||
}
|
||||
|
||||
requestDataJSON, _ := json.Marshal(requestDataVersioning)
|
||||
|
||||
requestDataBody := bytes.NewReader(requestDataJSON)
|
||||
|
||||
request, err = http.NewRequest("POST", "http://localhost:9090/api/v1/buckets", requestDataBody)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
|
||||
request.Header.Add("Content-Type", "application/json")
|
||||
|
||||
response, err = client.Do(request)
|
||||
assert.Nil(err)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("Versioned bucket creation test status:", response.Status)
|
||||
if distributedSystem {
|
||||
assert.Equal(201, response.StatusCode, "Versioning test Status Code is incorrect - bucket failed to create")
|
||||
} else {
|
||||
assert.NotEqual(201, response.StatusCode, "Versioning test Status Code is incorrect - versioned bucket created on non-distributed system")
|
||||
}
|
||||
|
||||
request, err = http.NewRequest("DELETE", "http://localhost:9090/api/v1/buckets/test2", requestDataBody)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
|
||||
request.Header.Add("Content-Type", "application/json")
|
||||
|
||||
response, err = client.Do(request)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
if response != nil {
|
||||
fmt.Println("DELETE StatusCode:", response.StatusCode)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestBucketsGet(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
client := &http.Client{
|
||||
Timeout: 2 * time.Second,
|
||||
}
|
||||
|
||||
// get list of buckets
|
||||
request, err := http.NewRequest("GET", "http://localhost:9090/api/v1/buckets", nil)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
|
||||
|
||||
response, err := client.Do(request)
|
||||
assert.Nil(err)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
if response != nil {
|
||||
assert.Equal(200, response.StatusCode, "Status Code is incorrect")
|
||||
bodyBytes, _ := ioutil.ReadAll(response.Body)
|
||||
|
||||
listBuckets := models.ListBucketsResponse{}
|
||||
err = json.Unmarshal(bodyBytes, &listBuckets)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
assert.Nil(err)
|
||||
}
|
||||
|
||||
assert.Greater(len(listBuckets.Buckets), 0, "No bucket was returned")
|
||||
assert.Greater(listBuckets.Total, int64(0), "Total buckets is 0")
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
71
integration/login_test.go
Normal file
@@ -0,0 +1,71 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package integration
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/minio/console/models"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestLoginStrategy(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
// image for now:
|
||||
// minio: 9000
|
||||
// console: 9090
|
||||
|
||||
client := &http.Client{
|
||||
Timeout: 2 * time.Second,
|
||||
}
|
||||
// copy query params
|
||||
request, err := http.NewRequest("GET", "http://localhost:9090/api/v1/login", nil)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
response, err := client.Do(request)
|
||||
assert.Nil(err)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
if response != nil {
|
||||
bodyBytes, _ := ioutil.ReadAll(response.Body)
|
||||
|
||||
loginDetails := models.LoginDetails{}
|
||||
|
||||
err = json.Unmarshal(bodyBytes, &loginDetails)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
assert.Nil(err)
|
||||
|
||||
assert.Equal(models.LoginDetailsLoginStrategyForm, loginDetails.LoginStrategy, "Login Details don't match")
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: console-sa-binding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: console-sa-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: console-sa
|
||||
namespace: default
|
||||
@@ -1,222 +0,0 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: console-sa-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- secrets
|
||||
verbs:
|
||||
- get
|
||||
- watch
|
||||
- create
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- deletecollection
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- namespaces
|
||||
- pods
|
||||
- services
|
||||
- events
|
||||
- resourcequotas
|
||||
- nodes
|
||||
verbs:
|
||||
- get
|
||||
- watch
|
||||
- create
|
||||
- list
|
||||
- patch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- persistentvolumeclaims
|
||||
verbs:
|
||||
- deletecollection
|
||||
- list
|
||||
- get
|
||||
- watch
|
||||
- update
|
||||
- apiGroups:
|
||||
- "storage.k8s.io"
|
||||
resources:
|
||||
- storageclasses
|
||||
verbs:
|
||||
- get
|
||||
- watch
|
||||
- create
|
||||
- list
|
||||
- patch
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- statefulsets
|
||||
- deployments
|
||||
verbs:
|
||||
- get
|
||||
- create
|
||||
- list
|
||||
- patch
|
||||
- watch
|
||||
- update
|
||||
- delete
|
||||
- apiGroups:
|
||||
- batch
|
||||
resources:
|
||||
- jobs
|
||||
verbs:
|
||||
- get
|
||||
- create
|
||||
- list
|
||||
- patch
|
||||
- watch
|
||||
- update
|
||||
- delete
|
||||
- apiGroups:
|
||||
- "certificates.k8s.io"
|
||||
resources:
|
||||
- "certificatesigningrequests"
|
||||
- "certificatesigningrequests/approval"
|
||||
- "certificatesigningrequests/status"
|
||||
verbs:
|
||||
- update
|
||||
- create
|
||||
- get
|
||||
- apiGroups:
|
||||
- minio.min.io
|
||||
resources:
|
||||
- "*"
|
||||
verbs:
|
||||
- "*"
|
||||
- apiGroups:
|
||||
- min.io
|
||||
resources:
|
||||
- "*"
|
||||
verbs:
|
||||
- "*"
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- persistentvolumes
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- persistentvolumeclaims
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- update
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- list
|
||||
- watch
|
||||
- update
|
||||
- patch
|
||||
- apiGroups:
|
||||
- snapshot.storage.k8s.io
|
||||
resources:
|
||||
- volumesnapshots
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- apiGroups:
|
||||
- snapshot.storage.k8s.io
|
||||
resources:
|
||||
- volumesnapshotcontents
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- apiGroups:
|
||||
- storage.k8s.io
|
||||
resources:
|
||||
- csinodes
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- storage.k8s.io
|
||||
resources:
|
||||
- volumeattachments
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- endpoints
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- update
|
||||
- delete
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
resources:
|
||||
- leases
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- update
|
||||
- delete
|
||||
- apiGroups:
|
||||
- direct.csi.min.io
|
||||
resources:
|
||||
- volumes
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- update
|
||||
- delete
|
||||
- apiGroups:
|
||||
- apiextensions.k8s.io
|
||||
resources:
|
||||
- customresourcedefinitions
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- update
|
||||
- delete
|
||||
- apiGroups:
|
||||
- direct.csi.min.io
|
||||
resources:
|
||||
- directcsidrives
|
||||
- directcsivolumes
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- update
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pod
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
@@ -1,7 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: console-env
|
||||
data:
|
||||
CONSOLE_PORT: "9090"
|
||||
CONSOLE_TLS_PORT: "9443"
|
||||
@@ -1,26 +0,0 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: console
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: console
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: console
|
||||
spec:
|
||||
serviceAccountName: console-sa
|
||||
containers:
|
||||
- name: console
|
||||
image: minio/console:v0.8.3
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
args:
|
||||
- server
|
||||
ports:
|
||||
- containerPort: 9090
|
||||
name: http
|
||||
- containerPort: 9433
|
||||
name: https
|
||||
@@ -1,5 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: console-sa
|
||||
namespace: default
|
||||
@@ -1,14 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: console
|
||||
labels:
|
||||
name: console
|
||||
spec:
|
||||
ports:
|
||||
- port: 9090
|
||||
name: http
|
||||
- port: 9443
|
||||
name: https
|
||||
selector:
|
||||
app: console
|
||||
@@ -1,11 +0,0 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
# beginning of customizations
|
||||
resources:
|
||||
- console-service-account.yaml
|
||||
- console-cluster-role.yaml
|
||||
- console-cluster-role-binding.yaml
|
||||
- console-configmap.yaml
|
||||
- console-service.yaml
|
||||
- console-deployment.yaml
|
||||
- https://github.com/minio/operator/?ref=v3.0.10
|
||||
@@ -19,7 +19,6 @@ rules:
|
||||
- ""
|
||||
resources:
|
||||
- namespaces
|
||||
- pods
|
||||
- services
|
||||
- events
|
||||
- resourcequotas
|
||||
@@ -30,6 +29,18 @@ rules:
|
||||
- create
|
||||
- list
|
||||
- patch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
verbs:
|
||||
- get
|
||||
- watch
|
||||
- create
|
||||
- list
|
||||
- patch
|
||||
- delete
|
||||
- deletecollection
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
|
||||
@@ -15,7 +15,7 @@ spec:
|
||||
serviceAccountName: console-sa
|
||||
containers:
|
||||
- name: console
|
||||
image: minio/console:v0.8.3
|
||||
image: minio/console:v0.11.0
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
env:
|
||||
- name: CONSOLE_OPERATOR_MODE
|
||||
|
||||
70
models/access_rule.go
Normal file
@@ -0,0 +1,70 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// AccessRule access rule
|
||||
//
|
||||
// swagger:model accessRule
|
||||
type AccessRule struct {
|
||||
|
||||
// access
|
||||
Access string `json:"access,omitempty"`
|
||||
|
||||
// prefix
|
||||
Prefix string `json:"prefix,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this access rule
|
||||
func (m *AccessRule) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this access rule based on context it is used
|
||||
func (m *AccessRule) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *AccessRule) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *AccessRule) UnmarshalBinary(b []byte) error {
|
||||
var res AccessRule
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -44,6 +44,10 @@ type AddUserRequest struct {
|
||||
// Required: true
|
||||
Groups []string `json:"groups"`
|
||||
|
||||
// policies
|
||||
// Required: true
|
||||
Policies []string `json:"policies"`
|
||||
|
||||
// secret key
|
||||
// Required: true
|
||||
SecretKey *string `json:"secretKey"`
|
||||
@@ -61,6 +65,10 @@ func (m *AddUserRequest) Validate(formats strfmt.Registry) error {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validatePolicies(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateSecretKey(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -89,6 +97,15 @@ func (m *AddUserRequest) validateGroups(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AddUserRequest) validatePolicies(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("policies", "body", m.Policies); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AddUserRequest) validateSecretKey(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("secretKey", "body", m.SecretKey); err != nil {
|
||||
|
||||
@@ -42,6 +42,9 @@ type AdminInfoResponse struct {
|
||||
// objects
|
||||
Objects int64 `json:"objects,omitempty"`
|
||||
|
||||
// servers
|
||||
Servers []*ServerProperties `json:"servers"`
|
||||
|
||||
// usage
|
||||
Usage int64 `json:"usage,omitempty"`
|
||||
|
||||
@@ -53,6 +56,10 @@ type AdminInfoResponse struct {
|
||||
func (m *AdminInfoResponse) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateServers(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateWidgets(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -63,6 +70,30 @@ func (m *AdminInfoResponse) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AdminInfoResponse) validateServers(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Servers) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.Servers); i++ {
|
||||
if swag.IsZero(m.Servers[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.Servers[i] != nil {
|
||||
if err := m.Servers[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("servers" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AdminInfoResponse) validateWidgets(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Widgets) { // not required
|
||||
return nil
|
||||
@@ -91,6 +122,10 @@ func (m *AdminInfoResponse) validateWidgets(formats strfmt.Registry) error {
|
||||
func (m *AdminInfoResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateServers(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidateWidgets(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -101,6 +136,24 @@ func (m *AdminInfoResponse) ContextValidate(ctx context.Context, formats strfmt.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AdminInfoResponse) contextValidateServers(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.Servers); i++ {
|
||||
|
||||
if m.Servers[i] != nil {
|
||||
if err := m.Servers[i].ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("servers" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AdminInfoResponse) contextValidateWidgets(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.Widgets); i++ {
|
||||
|
||||
313
models/azure_configuration.go
Normal file
@@ -0,0 +1,313 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/validate"
|
||||
)
|
||||
|
||||
// AzureConfiguration azure configuration
|
||||
//
|
||||
// swagger:model azureConfiguration
|
||||
type AzureConfiguration struct {
|
||||
|
||||
// keyvault
|
||||
// Required: true
|
||||
Keyvault *AzureConfigurationKeyvault `json:"keyvault"`
|
||||
}
|
||||
|
||||
// Validate validates this azure configuration
|
||||
func (m *AzureConfiguration) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateKeyvault(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AzureConfiguration) validateKeyvault(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("keyvault", "body", m.Keyvault); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if m.Keyvault != nil {
|
||||
if err := m.Keyvault.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("keyvault")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this azure configuration based on the context it is used
|
||||
func (m *AzureConfiguration) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateKeyvault(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AzureConfiguration) contextValidateKeyvault(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.Keyvault != nil {
|
||||
if err := m.Keyvault.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("keyvault")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *AzureConfiguration) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *AzureConfiguration) UnmarshalBinary(b []byte) error {
|
||||
var res AzureConfiguration
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
|
||||
// AzureConfigurationKeyvault azure configuration keyvault
|
||||
//
|
||||
// swagger:model AzureConfigurationKeyvault
|
||||
type AzureConfigurationKeyvault struct {
|
||||
|
||||
// credentials
|
||||
Credentials *AzureConfigurationKeyvaultCredentials `json:"credentials,omitempty"`
|
||||
|
||||
// endpoint
|
||||
// Required: true
|
||||
Endpoint *string `json:"endpoint"`
|
||||
}
|
||||
|
||||
// Validate validates this azure configuration keyvault
|
||||
func (m *AzureConfigurationKeyvault) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateCredentials(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateEndpoint(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AzureConfigurationKeyvault) validateCredentials(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Credentials) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.Credentials != nil {
|
||||
if err := m.Credentials.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("keyvault" + "." + "credentials")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AzureConfigurationKeyvault) validateEndpoint(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("keyvault"+"."+"endpoint", "body", m.Endpoint); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this azure configuration keyvault based on the context it is used
|
||||
func (m *AzureConfigurationKeyvault) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateCredentials(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AzureConfigurationKeyvault) contextValidateCredentials(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.Credentials != nil {
|
||||
if err := m.Credentials.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("keyvault" + "." + "credentials")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *AzureConfigurationKeyvault) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *AzureConfigurationKeyvault) UnmarshalBinary(b []byte) error {
|
||||
var res AzureConfigurationKeyvault
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
|
||||
// AzureConfigurationKeyvaultCredentials azure configuration keyvault credentials
|
||||
//
|
||||
// swagger:model AzureConfigurationKeyvaultCredentials
|
||||
type AzureConfigurationKeyvaultCredentials struct {
|
||||
|
||||
// client id
|
||||
// Required: true
|
||||
ClientID *string `json:"client_id"`
|
||||
|
||||
// client secret
|
||||
// Required: true
|
||||
ClientSecret *string `json:"client_secret"`
|
||||
|
||||
// tenant id
|
||||
// Required: true
|
||||
TenantID *string `json:"tenant_id"`
|
||||
}
|
||||
|
||||
// Validate validates this azure configuration keyvault credentials
|
||||
func (m *AzureConfigurationKeyvaultCredentials) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateClientID(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateClientSecret(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateTenantID(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AzureConfigurationKeyvaultCredentials) validateClientID(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("keyvault"+"."+"credentials"+"."+"client_id", "body", m.ClientID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AzureConfigurationKeyvaultCredentials) validateClientSecret(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("keyvault"+"."+"credentials"+"."+"client_secret", "body", m.ClientSecret); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AzureConfigurationKeyvaultCredentials) validateTenantID(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("keyvault"+"."+"credentials"+"."+"tenant_id", "body", m.TenantID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this azure configuration keyvault credentials based on context it is used
|
||||
func (m *AzureConfigurationKeyvaultCredentials) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *AzureConfigurationKeyvaultCredentials) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *AzureConfigurationKeyvaultCredentials) UnmarshalBinary(b []byte) error {
|
||||
var res AzureConfigurationKeyvaultCredentials
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
321
models/bucket.go
@@ -24,6 +24,7 @@ package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
@@ -42,11 +43,20 @@ type Bucket struct {
|
||||
// creation date
|
||||
CreationDate string `json:"creation_date,omitempty"`
|
||||
|
||||
// details
|
||||
Details *BucketDetails `json:"details,omitempty"`
|
||||
|
||||
// name
|
||||
// Required: true
|
||||
// Min Length: 3
|
||||
Name *string `json:"name"`
|
||||
|
||||
// objects
|
||||
Objects int64 `json:"objects,omitempty"`
|
||||
|
||||
// rw access
|
||||
RwAccess *BucketRwAccess `json:"rw_access,omitempty"`
|
||||
|
||||
// size
|
||||
Size int64 `json:"size,omitempty"`
|
||||
}
|
||||
@@ -59,10 +69,18 @@ func (m *Bucket) Validate(formats strfmt.Registry) error {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateDetails(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateName(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateRwAccess(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
@@ -86,6 +104,23 @@ func (m *Bucket) validateAccess(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Bucket) validateDetails(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Details) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.Details != nil {
|
||||
if err := m.Details.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("details")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Bucket) validateName(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("name", "body", m.Name); err != nil {
|
||||
@@ -99,6 +134,23 @@ func (m *Bucket) validateName(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Bucket) validateRwAccess(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.RwAccess) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.RwAccess != nil {
|
||||
if err := m.RwAccess.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("rw_access")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this bucket based on the context it is used
|
||||
func (m *Bucket) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
@@ -107,6 +159,14 @@ func (m *Bucket) ContextValidate(ctx context.Context, formats strfmt.Registry) e
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidateDetails(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidateRwAccess(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
@@ -127,6 +187,34 @@ func (m *Bucket) contextValidateAccess(ctx context.Context, formats strfmt.Regis
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Bucket) contextValidateDetails(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.Details != nil {
|
||||
if err := m.Details.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("details")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Bucket) contextValidateRwAccess(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.RwAccess != nil {
|
||||
if err := m.RwAccess.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("rw_access")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *Bucket) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
@@ -144,3 +232,236 @@ func (m *Bucket) UnmarshalBinary(b []byte) error {
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
|
||||
// BucketDetails bucket details
|
||||
//
|
||||
// swagger:model BucketDetails
|
||||
type BucketDetails struct {
|
||||
|
||||
// locking
|
||||
Locking bool `json:"locking,omitempty"`
|
||||
|
||||
// quota
|
||||
Quota *BucketDetailsQuota `json:"quota,omitempty"`
|
||||
|
||||
// replication
|
||||
Replication bool `json:"replication,omitempty"`
|
||||
|
||||
// tags
|
||||
Tags map[string]string `json:"tags,omitempty"`
|
||||
|
||||
// versioning
|
||||
Versioning bool `json:"versioning,omitempty"`
|
||||
|
||||
// versioning suspended
|
||||
VersioningSuspended bool `json:"versioningSuspended,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this bucket details
|
||||
func (m *BucketDetails) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateQuota(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *BucketDetails) validateQuota(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Quota) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.Quota != nil {
|
||||
if err := m.Quota.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("details" + "." + "quota")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this bucket details based on the context it is used
|
||||
func (m *BucketDetails) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateQuota(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *BucketDetails) contextValidateQuota(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.Quota != nil {
|
||||
if err := m.Quota.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("details" + "." + "quota")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *BucketDetails) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *BucketDetails) UnmarshalBinary(b []byte) error {
|
||||
var res BucketDetails
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
|
||||
// BucketDetailsQuota bucket details quota
|
||||
//
|
||||
// swagger:model BucketDetailsQuota
|
||||
type BucketDetailsQuota struct {
|
||||
|
||||
// quota
|
||||
Quota int64 `json:"quota,omitempty"`
|
||||
|
||||
// type
|
||||
// Enum: [fifo hard]
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this bucket details quota
|
||||
func (m *BucketDetailsQuota) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateType(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var bucketDetailsQuotaTypeTypePropEnum []interface{}
|
||||
|
||||
func init() {
|
||||
var res []string
|
||||
if err := json.Unmarshal([]byte(`["fifo","hard"]`), &res); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, v := range res {
|
||||
bucketDetailsQuotaTypeTypePropEnum = append(bucketDetailsQuotaTypeTypePropEnum, v)
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
// BucketDetailsQuotaTypeFifo captures enum value "fifo"
|
||||
BucketDetailsQuotaTypeFifo string = "fifo"
|
||||
|
||||
// BucketDetailsQuotaTypeHard captures enum value "hard"
|
||||
BucketDetailsQuotaTypeHard string = "hard"
|
||||
)
|
||||
|
||||
// prop value enum
|
||||
func (m *BucketDetailsQuota) validateTypeEnum(path, location string, value string) error {
|
||||
if err := validate.EnumCase(path, location, value, bucketDetailsQuotaTypeTypePropEnum, true); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *BucketDetailsQuota) validateType(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Type) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
// value enum
|
||||
if err := m.validateTypeEnum("details"+"."+"quota"+"."+"type", "body", m.Type); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this bucket details quota based on context it is used
|
||||
func (m *BucketDetailsQuota) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *BucketDetailsQuota) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *BucketDetailsQuota) UnmarshalBinary(b []byte) error {
|
||||
var res BucketDetailsQuota
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
|
||||
// BucketRwAccess bucket rw access
|
||||
//
|
||||
// swagger:model BucketRwAccess
|
||||
type BucketRwAccess struct {
|
||||
|
||||
// read
|
||||
Read bool `json:"read,omitempty"`
|
||||
|
||||
// write
|
||||
Write bool `json:"write,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this bucket rw access
|
||||
func (m *BucketRwAccess) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this bucket rw access based on context it is used
|
||||
func (m *BucketRwAccess) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *BucketRwAccess) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *BucketRwAccess) UnmarshalBinary(b []byte) error {
|
||||
var res BucketRwAccess
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,134 +0,0 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// ConsoleConfiguration console configuration
|
||||
//
|
||||
// swagger:model consoleConfiguration
|
||||
type ConsoleConfiguration struct {
|
||||
MetadataFields
|
||||
|
||||
// image
|
||||
Image string `json:"image,omitempty"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals this object from a JSON structure
|
||||
func (m *ConsoleConfiguration) UnmarshalJSON(raw []byte) error {
|
||||
// AO0
|
||||
var aO0 MetadataFields
|
||||
if err := swag.ReadJSON(raw, &aO0); err != nil {
|
||||
return err
|
||||
}
|
||||
m.MetadataFields = aO0
|
||||
|
||||
// AO1
|
||||
var dataAO1 struct {
|
||||
Image string `json:"image,omitempty"`
|
||||
}
|
||||
if err := swag.ReadJSON(raw, &dataAO1); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m.Image = dataAO1.Image
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON marshals this object to a JSON structure
|
||||
func (m ConsoleConfiguration) MarshalJSON() ([]byte, error) {
|
||||
_parts := make([][]byte, 0, 2)
|
||||
|
||||
aO0, err := swag.WriteJSON(m.MetadataFields)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_parts = append(_parts, aO0)
|
||||
var dataAO1 struct {
|
||||
Image string `json:"image,omitempty"`
|
||||
}
|
||||
|
||||
dataAO1.Image = m.Image
|
||||
|
||||
jsonDataAO1, errAO1 := swag.WriteJSON(dataAO1)
|
||||
if errAO1 != nil {
|
||||
return nil, errAO1
|
||||
}
|
||||
_parts = append(_parts, jsonDataAO1)
|
||||
return swag.ConcatJSON(_parts...), nil
|
||||
}
|
||||
|
||||
// Validate validates this console configuration
|
||||
func (m *ConsoleConfiguration) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
// validation for a type composition with MetadataFields
|
||||
if err := m.MetadataFields.Validate(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this console configuration based on the context it is used
|
||||
func (m *ConsoleConfiguration) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
// validation for a type composition with MetadataFields
|
||||
if err := m.MetadataFields.ContextValidate(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *ConsoleConfiguration) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *ConsoleConfiguration) UnmarshalBinary(b []byte) error {
|
||||
var res ConsoleConfiguration
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -43,12 +43,6 @@ type CreateTenantRequest struct {
|
||||
// annotations
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
|
||||
// console
|
||||
Console *ConsoleConfiguration `json:"console,omitempty"`
|
||||
|
||||
// console image
|
||||
ConsoleImage string `json:"console_image,omitempty"`
|
||||
|
||||
// enable console
|
||||
EnableConsole *bool `json:"enable_console,omitempty"`
|
||||
|
||||
@@ -118,10 +112,6 @@ type CreateTenantRequest struct {
|
||||
func (m *CreateTenantRequest) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateConsole(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateEncryption(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -164,23 +154,6 @@ func (m *CreateTenantRequest) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *CreateTenantRequest) validateConsole(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Console) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.Console != nil {
|
||||
if err := m.Console.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("console")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *CreateTenantRequest) validateEncryption(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Encryption) { // not required
|
||||
return nil
|
||||
@@ -334,10 +307,6 @@ func (m *CreateTenantRequest) validateTLS(formats strfmt.Registry) error {
|
||||
func (m *CreateTenantRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateConsole(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidateEncryption(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -372,20 +341,6 @@ func (m *CreateTenantRequest) ContextValidate(ctx context.Context, formats strfm
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *CreateTenantRequest) contextValidateConsole(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.Console != nil {
|
||||
if err := m.Console.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("console")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *CreateTenantRequest) contextValidateEncryption(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.Encryption != nil {
|
||||
|
||||
@@ -38,6 +38,9 @@ type CreateTenantResponse struct {
|
||||
|
||||
// console
|
||||
Console []*TenantResponseItem `json:"console"`
|
||||
|
||||
// external ID p
|
||||
ExternalIDP bool `json:"externalIDP,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this create tenant response
|
||||
|
||||
@@ -39,6 +39,9 @@ type EncryptionConfiguration struct {
|
||||
// aws
|
||||
Aws *AwsConfiguration `json:"aws,omitempty"`
|
||||
|
||||
// azure
|
||||
Azure *AzureConfiguration `json:"azure,omitempty"`
|
||||
|
||||
// client
|
||||
Client *KeyPairConfiguration `json:"client,omitempty"`
|
||||
|
||||
@@ -54,6 +57,9 @@ type EncryptionConfiguration struct {
|
||||
// replicas
|
||||
Replicas string `json:"replicas,omitempty"`
|
||||
|
||||
// security context
|
||||
SecurityContext *SecurityContext `json:"securityContext,omitempty"`
|
||||
|
||||
// server
|
||||
Server *KeyPairConfiguration `json:"server,omitempty"`
|
||||
|
||||
@@ -74,6 +80,8 @@ func (m *EncryptionConfiguration) UnmarshalJSON(raw []byte) error {
|
||||
var dataAO1 struct {
|
||||
Aws *AwsConfiguration `json:"aws,omitempty"`
|
||||
|
||||
Azure *AzureConfiguration `json:"azure,omitempty"`
|
||||
|
||||
Client *KeyPairConfiguration `json:"client,omitempty"`
|
||||
|
||||
Gcp *GcpConfiguration `json:"gcp,omitempty"`
|
||||
@@ -84,6 +92,8 @@ func (m *EncryptionConfiguration) UnmarshalJSON(raw []byte) error {
|
||||
|
||||
Replicas string `json:"replicas,omitempty"`
|
||||
|
||||
SecurityContext *SecurityContext `json:"securityContext,omitempty"`
|
||||
|
||||
Server *KeyPairConfiguration `json:"server,omitempty"`
|
||||
|
||||
Vault *VaultConfiguration `json:"vault,omitempty"`
|
||||
@@ -94,6 +104,8 @@ func (m *EncryptionConfiguration) UnmarshalJSON(raw []byte) error {
|
||||
|
||||
m.Aws = dataAO1.Aws
|
||||
|
||||
m.Azure = dataAO1.Azure
|
||||
|
||||
m.Client = dataAO1.Client
|
||||
|
||||
m.Gcp = dataAO1.Gcp
|
||||
@@ -104,6 +116,8 @@ func (m *EncryptionConfiguration) UnmarshalJSON(raw []byte) error {
|
||||
|
||||
m.Replicas = dataAO1.Replicas
|
||||
|
||||
m.SecurityContext = dataAO1.SecurityContext
|
||||
|
||||
m.Server = dataAO1.Server
|
||||
|
||||
m.Vault = dataAO1.Vault
|
||||
@@ -123,6 +137,8 @@ func (m EncryptionConfiguration) MarshalJSON() ([]byte, error) {
|
||||
var dataAO1 struct {
|
||||
Aws *AwsConfiguration `json:"aws,omitempty"`
|
||||
|
||||
Azure *AzureConfiguration `json:"azure,omitempty"`
|
||||
|
||||
Client *KeyPairConfiguration `json:"client,omitempty"`
|
||||
|
||||
Gcp *GcpConfiguration `json:"gcp,omitempty"`
|
||||
@@ -133,6 +149,8 @@ func (m EncryptionConfiguration) MarshalJSON() ([]byte, error) {
|
||||
|
||||
Replicas string `json:"replicas,omitempty"`
|
||||
|
||||
SecurityContext *SecurityContext `json:"securityContext,omitempty"`
|
||||
|
||||
Server *KeyPairConfiguration `json:"server,omitempty"`
|
||||
|
||||
Vault *VaultConfiguration `json:"vault,omitempty"`
|
||||
@@ -140,6 +158,8 @@ func (m EncryptionConfiguration) MarshalJSON() ([]byte, error) {
|
||||
|
||||
dataAO1.Aws = m.Aws
|
||||
|
||||
dataAO1.Azure = m.Azure
|
||||
|
||||
dataAO1.Client = m.Client
|
||||
|
||||
dataAO1.Gcp = m.Gcp
|
||||
@@ -150,6 +170,8 @@ func (m EncryptionConfiguration) MarshalJSON() ([]byte, error) {
|
||||
|
||||
dataAO1.Replicas = m.Replicas
|
||||
|
||||
dataAO1.SecurityContext = m.SecurityContext
|
||||
|
||||
dataAO1.Server = m.Server
|
||||
|
||||
dataAO1.Vault = m.Vault
|
||||
@@ -175,6 +197,10 @@ func (m *EncryptionConfiguration) Validate(formats strfmt.Registry) error {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateAzure(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateClient(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -187,6 +213,10 @@ func (m *EncryptionConfiguration) Validate(formats strfmt.Registry) error {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateSecurityContext(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateServer(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -219,6 +249,24 @@ func (m *EncryptionConfiguration) validateAws(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *EncryptionConfiguration) validateAzure(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.Azure) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.Azure != nil {
|
||||
if err := m.Azure.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("azure")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *EncryptionConfiguration) validateClient(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.Client) { // not required
|
||||
@@ -273,6 +321,24 @@ func (m *EncryptionConfiguration) validateGemalto(formats strfmt.Registry) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *EncryptionConfiguration) validateSecurityContext(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.SecurityContext) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.SecurityContext != nil {
|
||||
if err := m.SecurityContext.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("securityContext")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *EncryptionConfiguration) validateServer(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.Server) { // not required
|
||||
@@ -322,6 +388,10 @@ func (m *EncryptionConfiguration) ContextValidate(ctx context.Context, formats s
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidateAzure(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidateClient(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -334,6 +404,10 @@ func (m *EncryptionConfiguration) ContextValidate(ctx context.Context, formats s
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidateSecurityContext(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidateServer(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -362,6 +436,20 @@ func (m *EncryptionConfiguration) contextValidateAws(ctx context.Context, format
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *EncryptionConfiguration) contextValidateAzure(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.Azure != nil {
|
||||
if err := m.Azure.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("azure")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *EncryptionConfiguration) contextValidateClient(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.Client != nil {
|
||||
@@ -404,6 +492,20 @@ func (m *EncryptionConfiguration) contextValidateGemalto(ctx context.Context, fo
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *EncryptionConfiguration) contextValidateSecurityContext(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.SecurityContext != nil {
|
||||
if err := m.SecurityContext.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("securityContext")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *EncryptionConfiguration) contextValidateServer(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.Server != nil {
|
||||
|
||||
@@ -407,10 +407,6 @@ type IdpConfigurationOidc struct {
|
||||
// secret id
|
||||
// Required: true
|
||||
SecretID *string `json:"secret_id"`
|
||||
|
||||
// url
|
||||
// Required: true
|
||||
URL *string `json:"url"`
|
||||
}
|
||||
|
||||
// Validate validates this idp configuration oidc
|
||||
@@ -433,10 +429,6 @@ func (m *IdpConfigurationOidc) Validate(formats strfmt.Registry) error {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateURL(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
@@ -479,15 +471,6 @@ func (m *IdpConfigurationOidc) validateSecretID(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *IdpConfigurationOidc) validateURL(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("oidc"+"."+"url", "body", m.URL); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this idp configuration oidc based on context it is used
|
||||
func (m *IdpConfigurationOidc) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
|
||||
132
models/list_access_rules_response.go
Normal file
@@ -0,0 +1,132 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// ListAccessRulesResponse list access rules response
|
||||
//
|
||||
// swagger:model listAccessRulesResponse
|
||||
type ListAccessRulesResponse struct {
|
||||
|
||||
// list of policies
|
||||
AccessRules []*AccessRule `json:"accessRules"`
|
||||
|
||||
// total number of policies
|
||||
Total int64 `json:"total,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this list access rules response
|
||||
func (m *ListAccessRulesResponse) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateAccessRules(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ListAccessRulesResponse) validateAccessRules(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.AccessRules) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.AccessRules); i++ {
|
||||
if swag.IsZero(m.AccessRules[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.AccessRules[i] != nil {
|
||||
if err := m.AccessRules[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("accessRules" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this list access rules response based on the context it is used
|
||||
func (m *ListAccessRulesResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateAccessRules(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ListAccessRulesResponse) contextValidateAccessRules(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.AccessRules); i++ {
|
||||
|
||||
if m.AccessRules[i] != nil {
|
||||
if err := m.AccessRules[i].ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("accessRules" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *ListAccessRulesResponse) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *ListAccessRulesResponse) UnmarshalBinary(b []byte) error {
|
||||
var res ListAccessRulesResponse
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -25,6 +25,7 @@ package models
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
@@ -40,6 +41,15 @@ type LogSearchConfiguration struct {
|
||||
// postgres image
|
||||
PostgresImage string `json:"postgres_image,omitempty"`
|
||||
|
||||
// postgres init image
|
||||
PostgresInitImage string `json:"postgres_init_image,omitempty"`
|
||||
|
||||
// postgres security context
|
||||
PostgresSecurityContext *SecurityContext `json:"postgres_securityContext,omitempty"`
|
||||
|
||||
// security context
|
||||
SecurityContext *SecurityContext `json:"securityContext,omitempty"`
|
||||
|
||||
// storage class
|
||||
StorageClass string `json:"storageClass,omitempty"`
|
||||
|
||||
@@ -49,11 +59,99 @@ type LogSearchConfiguration struct {
|
||||
|
||||
// Validate validates this log search configuration
|
||||
func (m *LogSearchConfiguration) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validatePostgresSecurityContext(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateSecurityContext(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this log search configuration based on context it is used
|
||||
func (m *LogSearchConfiguration) validatePostgresSecurityContext(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.PostgresSecurityContext) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.PostgresSecurityContext != nil {
|
||||
if err := m.PostgresSecurityContext.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("postgres_securityContext")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *LogSearchConfiguration) validateSecurityContext(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.SecurityContext) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.SecurityContext != nil {
|
||||
if err := m.SecurityContext.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("securityContext")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this log search configuration based on the context it is used
|
||||
func (m *LogSearchConfiguration) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidatePostgresSecurityContext(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidateSecurityContext(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *LogSearchConfiguration) contextValidatePostgresSecurityContext(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.PostgresSecurityContext != nil {
|
||||
if err := m.PostgresSecurityContext.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("postgres_securityContext")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *LogSearchConfiguration) contextValidateSecurityContext(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.SecurityContext != nil {
|
||||
if err := m.SecurityContext.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("securityContext")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,9 @@ type Pool struct {
|
||||
// resources
|
||||
Resources *PoolResources `json:"resources,omitempty"`
|
||||
|
||||
// security context
|
||||
SecurityContext *SecurityContext `json:"securityContext,omitempty"`
|
||||
|
||||
// servers
|
||||
// Required: true
|
||||
Servers *int64 `json:"servers"`
|
||||
@@ -76,6 +79,10 @@ func (m *Pool) Validate(formats strfmt.Registry) error {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateSecurityContext(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateServers(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -132,6 +139,23 @@ func (m *Pool) validateResources(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Pool) validateSecurityContext(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.SecurityContext) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.SecurityContext != nil {
|
||||
if err := m.SecurityContext.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("securityContext")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Pool) validateServers(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("servers", "body", m.Servers); err != nil {
|
||||
@@ -195,6 +219,10 @@ func (m *Pool) ContextValidate(ctx context.Context, formats strfmt.Registry) err
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidateSecurityContext(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidateTolerations(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -237,6 +265,20 @@ func (m *Pool) contextValidateResources(ctx context.Context, formats strfmt.Regi
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Pool) contextValidateSecurityContext(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.SecurityContext != nil {
|
||||
if err := m.SecurityContext.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("securityContext")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Pool) contextValidateTolerations(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if err := m.Tolerations.ContextValidate(ctx, formats); err != nil {
|
||||
|
||||
70
models/prefix_access_pair.go
Normal file
@@ -0,0 +1,70 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// PrefixAccessPair prefix access pair
|
||||
//
|
||||
// swagger:model prefixAccessPair
|
||||
type PrefixAccessPair struct {
|
||||
|
||||
// access
|
||||
Access string `json:"access,omitempty"`
|
||||
|
||||
// prefix
|
||||
Prefix string `json:"prefix,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this prefix access pair
|
||||
func (m *PrefixAccessPair) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this prefix access pair based on context it is used
|
||||
func (m *PrefixAccessPair) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *PrefixAccessPair) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *PrefixAccessPair) UnmarshalBinary(b []byte) error {
|
||||
var res PrefixAccessPair
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
67
models/prefix_wrapper.go
Normal file
@@ -0,0 +1,67 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// PrefixWrapper prefix wrapper
|
||||
//
|
||||
// swagger:model prefixWrapper
|
||||
type PrefixWrapper struct {
|
||||
|
||||
// prefix
|
||||
Prefix string `json:"prefix,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this prefix wrapper
|
||||
func (m *PrefixWrapper) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this prefix wrapper based on context it is used
|
||||
func (m *PrefixWrapper) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *PrefixWrapper) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *PrefixWrapper) UnmarshalBinary(b []byte) error {
|
||||
var res PrefixWrapper
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -45,9 +45,6 @@ type Principal struct {
|
||||
|
||||
// account access key
|
||||
AccountAccessKey string `json:"accountAccessKey,omitempty"`
|
||||
|
||||
// actions
|
||||
Actions []string `json:"actions"`
|
||||
}
|
||||
|
||||
// Validate validates this principal
|
||||
|
||||
@@ -25,6 +25,7 @@ package models
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
@@ -37,6 +38,15 @@ type PrometheusConfiguration struct {
|
||||
// image
|
||||
Image string `json:"image,omitempty"`
|
||||
|
||||
// init image
|
||||
InitImage string `json:"init_image,omitempty"`
|
||||
|
||||
// security context
|
||||
SecurityContext *SecurityContext `json:"securityContext,omitempty"`
|
||||
|
||||
// sidecar image
|
||||
SidecarImage string `json:"sidecar_image,omitempty"`
|
||||
|
||||
// storage class
|
||||
StorageClass string `json:"storageClass,omitempty"`
|
||||
|
||||
@@ -46,11 +56,60 @@ type PrometheusConfiguration struct {
|
||||
|
||||
// Validate validates this prometheus configuration
|
||||
func (m *PrometheusConfiguration) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateSecurityContext(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this prometheus configuration based on context it is used
|
||||
func (m *PrometheusConfiguration) validateSecurityContext(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.SecurityContext) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.SecurityContext != nil {
|
||||
if err := m.SecurityContext.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("securityContext")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this prometheus configuration based on the context it is used
|
||||
func (m *PrometheusConfiguration) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateSecurityContext(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *PrometheusConfiguration) contextValidateSecurityContext(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.SecurityContext != nil {
|
||||
if err := m.SecurityContext.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("securityContext")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
139
models/security_context.go
Normal file
@@ -0,0 +1,139 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/validate"
|
||||
)
|
||||
|
||||
// SecurityContext security context
|
||||
//
|
||||
// swagger:model securityContext
|
||||
type SecurityContext struct {
|
||||
|
||||
// fs group
|
||||
// Required: true
|
||||
FsGroup *string `json:"fsGroup"`
|
||||
|
||||
// run as group
|
||||
// Required: true
|
||||
RunAsGroup *string `json:"runAsGroup"`
|
||||
|
||||
// run as non root
|
||||
// Required: true
|
||||
RunAsNonRoot *bool `json:"runAsNonRoot"`
|
||||
|
||||
// run as user
|
||||
// Required: true
|
||||
RunAsUser *string `json:"runAsUser"`
|
||||
}
|
||||
|
||||
// Validate validates this security context
|
||||
func (m *SecurityContext) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateFsGroup(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateRunAsGroup(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateRunAsNonRoot(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateRunAsUser(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *SecurityContext) validateFsGroup(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("fsGroup", "body", m.FsGroup); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *SecurityContext) validateRunAsGroup(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("runAsGroup", "body", m.RunAsGroup); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *SecurityContext) validateRunAsNonRoot(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("runAsNonRoot", "body", m.RunAsNonRoot); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *SecurityContext) validateRunAsUser(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("runAsUser", "body", m.RunAsUser); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this security context based on context it is used
|
||||
func (m *SecurityContext) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *SecurityContext) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *SecurityContext) UnmarshalBinary(b []byte) error {
|
||||
var res SecurityContext
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
94
models/server_drives.go
Normal file
@@ -0,0 +1,94 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// ServerDrives server drives
|
||||
//
|
||||
// swagger:model serverDrives
|
||||
type ServerDrives struct {
|
||||
|
||||
// available space
|
||||
AvailableSpace int64 `json:"availableSpace,omitempty"`
|
||||
|
||||
// drive path
|
||||
DrivePath string `json:"drivePath,omitempty"`
|
||||
|
||||
// endpoint
|
||||
Endpoint string `json:"endpoint,omitempty"`
|
||||
|
||||
// healing
|
||||
Healing bool `json:"healing,omitempty"`
|
||||
|
||||
// model
|
||||
Model string `json:"model,omitempty"`
|
||||
|
||||
// root disk
|
||||
RootDisk bool `json:"rootDisk,omitempty"`
|
||||
|
||||
// state
|
||||
State string `json:"state,omitempty"`
|
||||
|
||||
// total space
|
||||
TotalSpace int64 `json:"totalSpace,omitempty"`
|
||||
|
||||
// used space
|
||||
UsedSpace int64 `json:"usedSpace,omitempty"`
|
||||
|
||||
// uuid
|
||||
UUID string `json:"uuid,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this server drives
|
||||
func (m *ServerDrives) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this server drives based on context it is used
|
||||
func (m *ServerDrives) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *ServerDrives) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *ServerDrives) UnmarshalBinary(b []byte) error {
|
||||
var res ServerDrives
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
150
models/server_properties.go
Normal file
@@ -0,0 +1,150 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// ServerProperties server properties
|
||||
//
|
||||
// swagger:model serverProperties
|
||||
type ServerProperties struct {
|
||||
|
||||
// commit ID
|
||||
CommitID string `json:"commitID,omitempty"`
|
||||
|
||||
// drives
|
||||
Drives []*ServerDrives `json:"drives"`
|
||||
|
||||
// endpoint
|
||||
Endpoint string `json:"endpoint,omitempty"`
|
||||
|
||||
// network
|
||||
Network map[string]string `json:"network,omitempty"`
|
||||
|
||||
// pool number
|
||||
PoolNumber int64 `json:"poolNumber,omitempty"`
|
||||
|
||||
// state
|
||||
State string `json:"state,omitempty"`
|
||||
|
||||
// uptime
|
||||
Uptime int64 `json:"uptime,omitempty"`
|
||||
|
||||
// version
|
||||
Version string `json:"version,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this server properties
|
||||
func (m *ServerProperties) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateDrives(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ServerProperties) validateDrives(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Drives) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.Drives); i++ {
|
||||
if swag.IsZero(m.Drives[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.Drives[i] != nil {
|
||||
if err := m.Drives[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("drives" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this server properties based on the context it is used
|
||||
func (m *ServerProperties) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateDrives(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ServerProperties) contextValidateDrives(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.Drives); i++ {
|
||||
|
||||
if m.Drives[i] != nil {
|
||||
if err := m.Drives[i].ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("drives" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *ServerProperties) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *ServerProperties) UnmarshalBinary(b []byte) error {
|
||||
var res ServerProperties
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
73
models/service_account_request_creds.go
Normal file
@@ -0,0 +1,73 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// ServiceAccountRequestCreds service account request creds
|
||||
//
|
||||
// swagger:model serviceAccountRequestCreds
|
||||
type ServiceAccountRequestCreds struct {
|
||||
|
||||
// access key
|
||||
AccessKey string `json:"accessKey,omitempty"`
|
||||
|
||||
// policy to be applied to the Service Account if any
|
||||
Policy string `json:"policy,omitempty"`
|
||||
|
||||
// secret key
|
||||
SecretKey string `json:"secretKey,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this service account request creds
|
||||
func (m *ServiceAccountRequestCreds) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this service account request creds based on context it is used
|
||||
func (m *ServiceAccountRequestCreds) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *ServiceAccountRequestCreds) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *ServiceAccountRequestCreds) UnmarshalBinary(b []byte) error {
|
||||
var res ServiceAccountRequestCreds
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -31,20 +31,23 @@ import (
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// SetPolicyMultipleRequest set policy multiple request
|
||||
// SetPolicyMultipleNameRequest set policy multiple name request
|
||||
//
|
||||
// swagger:model setPolicyMultipleRequest
|
||||
type SetPolicyMultipleRequest struct {
|
||||
// swagger:model setPolicyMultipleNameRequest
|
||||
type SetPolicyMultipleNameRequest struct {
|
||||
|
||||
// groups
|
||||
Groups []IamEntity `json:"groups"`
|
||||
|
||||
// name
|
||||
Name []string `json:"name"`
|
||||
|
||||
// users
|
||||
Users []IamEntity `json:"users"`
|
||||
}
|
||||
|
||||
// Validate validates this set policy multiple request
|
||||
func (m *SetPolicyMultipleRequest) Validate(formats strfmt.Registry) error {
|
||||
// Validate validates this set policy multiple name request
|
||||
func (m *SetPolicyMultipleNameRequest) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateGroups(formats); err != nil {
|
||||
@@ -61,7 +64,7 @@ func (m *SetPolicyMultipleRequest) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *SetPolicyMultipleRequest) validateGroups(formats strfmt.Registry) error {
|
||||
func (m *SetPolicyMultipleNameRequest) validateGroups(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Groups) { // not required
|
||||
return nil
|
||||
}
|
||||
@@ -80,7 +83,7 @@ func (m *SetPolicyMultipleRequest) validateGroups(formats strfmt.Registry) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *SetPolicyMultipleRequest) validateUsers(formats strfmt.Registry) error {
|
||||
func (m *SetPolicyMultipleNameRequest) validateUsers(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Users) { // not required
|
||||
return nil
|
||||
}
|
||||
@@ -99,8 +102,8 @@ func (m *SetPolicyMultipleRequest) validateUsers(formats strfmt.Registry) error
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this set policy multiple request based on the context it is used
|
||||
func (m *SetPolicyMultipleRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
// ContextValidate validate this set policy multiple name request based on the context it is used
|
||||
func (m *SetPolicyMultipleNameRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateGroups(ctx, formats); err != nil {
|
||||
@@ -117,7 +120,7 @@ func (m *SetPolicyMultipleRequest) ContextValidate(ctx context.Context, formats
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *SetPolicyMultipleRequest) contextValidateGroups(ctx context.Context, formats strfmt.Registry) error {
|
||||
func (m *SetPolicyMultipleNameRequest) contextValidateGroups(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.Groups); i++ {
|
||||
|
||||
@@ -133,7 +136,7 @@ func (m *SetPolicyMultipleRequest) contextValidateGroups(ctx context.Context, fo
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *SetPolicyMultipleRequest) contextValidateUsers(ctx context.Context, formats strfmt.Registry) error {
|
||||
func (m *SetPolicyMultipleNameRequest) contextValidateUsers(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.Users); i++ {
|
||||
|
||||
@@ -150,7 +153,7 @@ func (m *SetPolicyMultipleRequest) contextValidateUsers(ctx context.Context, for
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *SetPolicyMultipleRequest) MarshalBinary() ([]byte, error) {
|
||||
func (m *SetPolicyMultipleNameRequest) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -158,8 +161,8 @@ func (m *SetPolicyMultipleRequest) MarshalBinary() ([]byte, error) {
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *SetPolicyMultipleRequest) UnmarshalBinary(b []byte) error {
|
||||
var res SetPolicyMultipleRequest
|
||||
func (m *SetPolicyMultipleNameRequest) UnmarshalBinary(b []byte) error {
|
||||
var res SetPolicyMultipleNameRequest
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
158
models/set_policy_name_request.go
Normal file
@@ -0,0 +1,158 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/validate"
|
||||
)
|
||||
|
||||
// SetPolicyNameRequest set policy name request
|
||||
//
|
||||
// swagger:model setPolicyNameRequest
|
||||
type SetPolicyNameRequest struct {
|
||||
|
||||
// entity name
|
||||
// Required: true
|
||||
EntityName *string `json:"entityName"`
|
||||
|
||||
// entity type
|
||||
// Required: true
|
||||
EntityType *PolicyEntity `json:"entityType"`
|
||||
|
||||
// name
|
||||
// Required: true
|
||||
Name []string `json:"name"`
|
||||
}
|
||||
|
||||
// Validate validates this set policy name request
|
||||
func (m *SetPolicyNameRequest) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateEntityName(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateEntityType(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateName(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *SetPolicyNameRequest) validateEntityName(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("entityName", "body", m.EntityName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *SetPolicyNameRequest) validateEntityType(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("entityType", "body", m.EntityType); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validate.Required("entityType", "body", m.EntityType); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if m.EntityType != nil {
|
||||
if err := m.EntityType.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("entityType")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *SetPolicyNameRequest) validateName(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("name", "body", m.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this set policy name request based on the context it is used
|
||||
func (m *SetPolicyNameRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateEntityType(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *SetPolicyNameRequest) contextValidateEntityType(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.EntityType != nil {
|
||||
if err := m.EntityType.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("entityType")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *SetPolicyNameRequest) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *SetPolicyNameRequest) UnmarshalBinary(b []byte) error {
|
||||
var res SetPolicyNameRequest
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -36,15 +36,6 @@ import (
|
||||
// swagger:model tenant
|
||||
type Tenant struct {
|
||||
|
||||
// console enabled
|
||||
ConsoleEnabled bool `json:"consoleEnabled,omitempty"`
|
||||
|
||||
// console TLS
|
||||
ConsoleTLS bool `json:"consoleTLS,omitempty"`
|
||||
|
||||
// console image
|
||||
ConsoleImage string `json:"console_image,omitempty"`
|
||||
|
||||
// creation date
|
||||
CreationDate string `json:"creation_date,omitempty"`
|
||||
|
||||
|
||||
@@ -125,12 +125,6 @@ func (m *TenantSecurityResponse) UnmarshalBinary(b []byte) error {
|
||||
// swagger:model TenantSecurityResponseCustomCertificates
|
||||
type TenantSecurityResponseCustomCertificates struct {
|
||||
|
||||
// console
|
||||
Console []*CertificateInfo `json:"console"`
|
||||
|
||||
// console c as
|
||||
ConsoleCAs []*CertificateInfo `json:"consoleCAs"`
|
||||
|
||||
// minio
|
||||
Minio []*CertificateInfo `json:"minio"`
|
||||
|
||||
@@ -142,14 +136,6 @@ type TenantSecurityResponseCustomCertificates struct {
|
||||
func (m *TenantSecurityResponseCustomCertificates) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateConsole(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateConsoleCAs(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateMinio(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -164,54 +150,6 @@ func (m *TenantSecurityResponseCustomCertificates) Validate(formats strfmt.Regis
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *TenantSecurityResponseCustomCertificates) validateConsole(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Console) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.Console); i++ {
|
||||
if swag.IsZero(m.Console[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.Console[i] != nil {
|
||||
if err := m.Console[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("customCertificates" + "." + "console" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *TenantSecurityResponseCustomCertificates) validateConsoleCAs(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.ConsoleCAs) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.ConsoleCAs); i++ {
|
||||
if swag.IsZero(m.ConsoleCAs[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.ConsoleCAs[i] != nil {
|
||||
if err := m.ConsoleCAs[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("customCertificates" + "." + "consoleCAs" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *TenantSecurityResponseCustomCertificates) validateMinio(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Minio) { // not required
|
||||
return nil
|
||||
@@ -264,14 +202,6 @@ func (m *TenantSecurityResponseCustomCertificates) validateMinioCAs(formats strf
|
||||
func (m *TenantSecurityResponseCustomCertificates) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateConsole(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidateConsoleCAs(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidateMinio(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -286,42 +216,6 @@ func (m *TenantSecurityResponseCustomCertificates) ContextValidate(ctx context.C
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *TenantSecurityResponseCustomCertificates) contextValidateConsole(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.Console); i++ {
|
||||
|
||||
if m.Console[i] != nil {
|
||||
if err := m.Console[i].ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("customCertificates" + "." + "console" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *TenantSecurityResponseCustomCertificates) contextValidateConsoleCAs(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.ConsoleCAs); i++ {
|
||||
|
||||
if m.ConsoleCAs[i] != nil {
|
||||
if err := m.ConsoleCAs[i].ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("customCertificates" + "." + "consoleCAs" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *TenantSecurityResponseCustomCertificates) contextValidateMinio(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.Minio); i++ {
|
||||
|
||||
@@ -39,12 +39,6 @@ type TLSConfiguration struct {
|
||||
// ca certificates
|
||||
CaCertificates []string `json:"ca_certificates"`
|
||||
|
||||
// console
|
||||
Console *KeyPairConfiguration `json:"console,omitempty"`
|
||||
|
||||
// console ca certificates
|
||||
ConsoleCaCertificates []string `json:"console_ca_certificates"`
|
||||
|
||||
// minio
|
||||
Minio []*KeyPairConfiguration `json:"minio"`
|
||||
}
|
||||
@@ -53,10 +47,6 @@ type TLSConfiguration struct {
|
||||
func (m *TLSConfiguration) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateConsole(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateMinio(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -67,23 +57,6 @@ func (m *TLSConfiguration) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *TLSConfiguration) validateConsole(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Console) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.Console != nil {
|
||||
if err := m.Console.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("console")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *TLSConfiguration) validateMinio(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Minio) { // not required
|
||||
return nil
|
||||
@@ -112,10 +85,6 @@ func (m *TLSConfiguration) validateMinio(formats strfmt.Registry) error {
|
||||
func (m *TLSConfiguration) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateConsole(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidateMinio(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -126,20 +95,6 @@ func (m *TLSConfiguration) ContextValidate(ctx context.Context, formats strfmt.R
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *TLSConfiguration) contextValidateConsole(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.Console != nil {
|
||||
if err := m.Console.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("console")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *TLSConfiguration) contextValidateMinio(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.Minio); i++ {
|
||||
|
||||
@@ -36,10 +36,6 @@ import (
|
||||
// swagger:model updateTenantRequest
|
||||
type UpdateTenantRequest struct {
|
||||
|
||||
// console image
|
||||
// Pattern: ^((.*?)/(.*?):(.+))$
|
||||
ConsoleImage string `json:"console_image,omitempty"`
|
||||
|
||||
// enable prometheus
|
||||
EnablePrometheus bool `json:"enable_prometheus,omitempty"`
|
||||
|
||||
@@ -58,10 +54,6 @@ type UpdateTenantRequest struct {
|
||||
func (m *UpdateTenantRequest) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateConsoleImage(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateImage(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -76,18 +68,6 @@ func (m *UpdateTenantRequest) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *UpdateTenantRequest) validateConsoleImage(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.ConsoleImage) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := validate.Pattern("console_image", "body", m.ConsoleImage, `^((.*?)/(.*?):(.+))$`); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *UpdateTenantRequest) validateImage(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Image) { // not required
|
||||
return nil
|
||||
|
||||
@@ -125,12 +125,6 @@ func (m *UpdateTenantSecurityRequest) UnmarshalBinary(b []byte) error {
|
||||
// swagger:model UpdateTenantSecurityRequestCustomCertificates
|
||||
type UpdateTenantSecurityRequestCustomCertificates struct {
|
||||
|
||||
// console
|
||||
Console []*KeyPairConfiguration `json:"console"`
|
||||
|
||||
// console c as
|
||||
ConsoleCAs []string `json:"consoleCAs"`
|
||||
|
||||
// minio
|
||||
Minio []*KeyPairConfiguration `json:"minio"`
|
||||
|
||||
@@ -145,10 +139,6 @@ type UpdateTenantSecurityRequestCustomCertificates struct {
|
||||
func (m *UpdateTenantSecurityRequestCustomCertificates) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateConsole(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateMinio(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -159,30 +149,6 @@ func (m *UpdateTenantSecurityRequestCustomCertificates) Validate(formats strfmt.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *UpdateTenantSecurityRequestCustomCertificates) validateConsole(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Console) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.Console); i++ {
|
||||
if swag.IsZero(m.Console[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.Console[i] != nil {
|
||||
if err := m.Console[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("customCertificates" + "." + "console" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *UpdateTenantSecurityRequestCustomCertificates) validateMinio(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Minio) { // not required
|
||||
return nil
|
||||
@@ -211,10 +177,6 @@ func (m *UpdateTenantSecurityRequestCustomCertificates) validateMinio(formats st
|
||||
func (m *UpdateTenantSecurityRequestCustomCertificates) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateConsole(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidateMinio(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -225,24 +187,6 @@ func (m *UpdateTenantSecurityRequestCustomCertificates) ContextValidate(ctx cont
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *UpdateTenantSecurityRequestCustomCertificates) contextValidateConsole(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.Console); i++ {
|
||||
|
||||
if m.Console[i] != nil {
|
||||
if err := m.Console[i].ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("customCertificates" + "." + "console" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *UpdateTenantSecurityRequestCustomCertificates) contextValidateMinio(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.Minio); i++ {
|
||||
|
||||
@@ -37,6 +37,9 @@ type User struct {
|
||||
// access key
|
||||
AccessKey string `json:"accessKey,omitempty"`
|
||||
|
||||
// has policy
|
||||
HasPolicy bool `json:"hasPolicy,omitempty"`
|
||||
|
||||
// member of
|
||||
MemberOf []string `json:"memberOf"`
|
||||
|
||||
|
||||
6
node_modules/.yarn-integrity
generated
vendored
@@ -1,10 +1,12 @@
|
||||
{
|
||||
"systemParams": "darwin-x64-93",
|
||||
"systemParams": "linux-x64-93",
|
||||
"modulesFolders": [
|
||||
"node_modules"
|
||||
],
|
||||
"flags": [],
|
||||
"linkedModules": [],
|
||||
"linkedModules": [
|
||||
"one-ui-common"
|
||||
],
|
||||
"topLevelPatterns": [],
|
||||
"lockfileEntries": {},
|
||||
"files": [],
|
||||
|
||||
@@ -56,12 +56,6 @@ var (
|
||||
GlobalTLSCertsManager *xcerts.Manager
|
||||
)
|
||||
|
||||
var consoleImage string
|
||||
|
||||
func init() {
|
||||
consoleImage = env.Get(ConsoleOperatorConsoleImage, ConsoleImageDefaultVersion)
|
||||
}
|
||||
|
||||
// getK8sSAToken assumes the plugin is running inside a k8s pod and extract the current service account from the
|
||||
// /var/run/secrets/kubernetes.io/serviceaccount/token file
|
||||
func getK8sSAToken() string {
|
||||
@@ -71,6 +65,3 @@ func getK8sSAToken() string {
|
||||
}
|
||||
return string(dat)
|
||||
}
|
||||
func getConsoleImage() string {
|
||||
return consoleImage
|
||||
}
|
||||
|
||||
@@ -65,7 +65,6 @@ func configureAPI(api *operations.OperatorAPI) http.Handler {
|
||||
}
|
||||
return &models.Principal{
|
||||
STSAccessKeyID: claims.STSAccessKeyID,
|
||||
Actions: claims.Actions,
|
||||
STSSecretAccessKey: claims.STSSecretAccessKey,
|
||||
STSSessionToken: claims.STSSessionToken,
|
||||
AccountAccessKey: claims.AccountAccessKey,
|
||||
@@ -93,7 +92,7 @@ func configureAPI(api *operations.OperatorAPI) http.Handler {
|
||||
// Namespaces handlers
|
||||
registerNamespaceHandlers(api)
|
||||
// Subscription handlers
|
||||
registerOperatorSubscriptionHandlers(api)
|
||||
registerSubscriptionHandlers(api)
|
||||
|
||||
api.PreServerShutdown = func() {}
|
||||
|
||||
|
||||
@@ -18,37 +18,9 @@ package operatorapi
|
||||
|
||||
// list of all console environment constants
|
||||
const (
|
||||
// Constants for common configuration
|
||||
ConsoleMinIOServer = "CONSOLE_MINIO_SERVER"
|
||||
ConsoleMinIORegion = "CONSOLE_MINIO_REGION"
|
||||
ConsoleHostname = "CONSOLE_HOSTNAME"
|
||||
ConsolePort = "CONSOLE_PORT"
|
||||
ConsoleTLSHostname = "CONSOLE_TLS_HOSTNAME"
|
||||
ConsoleTLSPort = "CONSOLE_TLS_PORT"
|
||||
ConsoleSubnetLicense = "CONSOLE_SUBNET_LICENSE"
|
||||
|
||||
// Constants for Secure middleware
|
||||
ConsoleSecureAllowedHosts = "CONSOLE_SECURE_ALLOWED_HOSTS"
|
||||
ConsoleSecureAllowedHostsAreRegex = "CONSOLE_SECURE_ALLOWED_HOSTS_ARE_REGEX"
|
||||
ConsoleSecureFrameDeny = "CONSOLE_SECURE_FRAME_DENY"
|
||||
ConsoleSecureContentTypeNoSniff = "CONSOLE_SECURE_CONTENT_TYPE_NO_SNIFF"
|
||||
ConsoleSecureBrowserXSSFilter = "CONSOLE_SECURE_BROWSER_XSS_FILTER"
|
||||
ConsoleSecureContentSecurityPolicy = "CONSOLE_SECURE_CONTENT_SECURITY_POLICY"
|
||||
ConsoleSecureContentSecurityPolicyReportOnly = "CONSOLE_SECURE_CONTENT_SECURITY_POLICY_REPORT_ONLY"
|
||||
ConsoleSecureHostsProxyHeaders = "CONSOLE_SECURE_HOSTS_PROXY_HEADERS"
|
||||
ConsoleSecureSTSSeconds = "CONSOLE_SECURE_STS_SECONDS"
|
||||
ConsoleSecureSTSIncludeSubdomains = "CONSOLE_SECURE_STS_INCLUDE_SUB_DOMAINS"
|
||||
ConsoleSecureSTSPreload = "CONSOLE_SECURE_STS_PRELOAD"
|
||||
ConsoleSecureTLSRedirect = "CONSOLE_SECURE_TLS_REDIRECT"
|
||||
ConsoleSecureTLSHost = "CONSOLE_SECURE_TLS_HOST"
|
||||
ConsoleSecureTLSTemporaryRedirect = "CONSOLE_SECURE_TLS_TEMPORARY_REDIRECT"
|
||||
ConsoleSecureForceSTSHeader = "CONSOLE_SECURE_FORCE_STS_HEADER"
|
||||
ConsoleSecurePublicKey = "CONSOLE_SECURE_PUBLIC_KEY"
|
||||
ConsoleSecureReferrerPolicy = "CONSOLE_SECURE_REFERRER_POLICY"
|
||||
ConsoleSecureFeaturePolicy = "CONSOLE_SECURE_FEATURE_POLICY"
|
||||
ConsoleSecureExpectCTHeader = "CONSOLE_SECURE_EXPECT_CT_HEADER"
|
||||
ConsoleOperatorSAToken = "CONSOLE_OPERATOR_SA_TOKEN"
|
||||
ConsoleOperatorConsoleImage = "CONSOLE_OPERATOR_CONSOLE_IMAGE"
|
||||
ConsoleSubnetLicense = "CONSOLE_SUBNET_LICENSE"
|
||||
ConsoleOperatorSAToken = "CONSOLE_OPERATOR_SA_TOKEN"
|
||||
MinIOSubnetLicense = "MINIO_SUBNET_LICENSE"
|
||||
|
||||
// Constants for prometheus annotations
|
||||
prometheusPath = "prometheus.io/path"
|
||||
@@ -58,8 +30,7 @@ const (
|
||||
|
||||
// Image versions
|
||||
const (
|
||||
KESImageVersion = "minio/kes:v0.13.4"
|
||||
ConsoleImageDefaultVersion = "minio/console:v0.8.3"
|
||||
KESImageVersion = "minio/kes:v0.16.1"
|
||||
)
|
||||
|
||||
// K8s
|
||||
|
||||
@@ -37,6 +37,7 @@ type K8sClientI interface {
|
||||
deletePodCollection(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error
|
||||
deleteSecret(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error
|
||||
createSecret(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.CreateOptions) (*v1.Secret, error)
|
||||
updateSecret(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.UpdateOptions) (*v1.Secret, error)
|
||||
}
|
||||
|
||||
// Interface implementation
|
||||
@@ -70,6 +71,10 @@ func (c *k8sClient) createSecret(ctx context.Context, namespace string, secret *
|
||||
return c.client.CoreV1().Secrets(namespace).Create(ctx, secret, opts)
|
||||
}
|
||||
|
||||
func (c *k8sClient) updateSecret(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.UpdateOptions) (*v1.Secret, error) {
|
||||
return c.client.CoreV1().Secrets(namespace).Update(ctx, secret, opts)
|
||||
}
|
||||
|
||||
func (c *k8sClient) getNamespace(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Namespace, error) {
|
||||
return c.client.CoreV1().Namespaces().Get(ctx, name, opts)
|
||||
}
|
||||
|
||||
@@ -117,6 +117,9 @@ func NewOperatorAPI(spec *loads.Document) *OperatorAPI {
|
||||
OperatorAPIListPVCsHandler: operator_api.ListPVCsHandlerFunc(func(params operator_api.ListPVCsParams, principal *models.Principal) middleware.Responder {
|
||||
return middleware.NotImplemented("operation operator_api.ListPVCs has not yet been implemented")
|
||||
}),
|
||||
OperatorAPIListPVCsForTenantHandler: operator_api.ListPVCsForTenantHandlerFunc(func(params operator_api.ListPVCsForTenantParams, principal *models.Principal) middleware.Responder {
|
||||
return middleware.NotImplemented("operation operator_api.ListPVCsForTenant has not yet been implemented")
|
||||
}),
|
||||
OperatorAPIListTenantsHandler: operator_api.ListTenantsHandlerFunc(func(params operator_api.ListTenantsParams, principal *models.Principal) middleware.Responder {
|
||||
return middleware.NotImplemented("operation operator_api.ListTenants has not yet been implemented")
|
||||
}),
|
||||
@@ -262,6 +265,8 @@ type OperatorAPI struct {
|
||||
OperatorAPIListNodeLabelsHandler operator_api.ListNodeLabelsHandler
|
||||
// OperatorAPIListPVCsHandler sets the operation handler for the list p v cs operation
|
||||
OperatorAPIListPVCsHandler operator_api.ListPVCsHandler
|
||||
// OperatorAPIListPVCsForTenantHandler sets the operation handler for the list p v cs for tenant operation
|
||||
OperatorAPIListPVCsForTenantHandler operator_api.ListPVCsForTenantHandler
|
||||
// OperatorAPIListTenantsHandler sets the operation handler for the list tenants operation
|
||||
OperatorAPIListTenantsHandler operator_api.ListTenantsHandler
|
||||
// UserAPILoginHandler sets the operation handler for the login operation
|
||||
@@ -437,6 +442,9 @@ func (o *OperatorAPI) Validate() error {
|
||||
if o.OperatorAPIListPVCsHandler == nil {
|
||||
unregistered = append(unregistered, "operator_api.ListPVCsHandler")
|
||||
}
|
||||
if o.OperatorAPIListPVCsForTenantHandler == nil {
|
||||
unregistered = append(unregistered, "operator_api.ListPVCsForTenantHandler")
|
||||
}
|
||||
if o.OperatorAPIListTenantsHandler == nil {
|
||||
unregistered = append(unregistered, "operator_api.ListTenantsHandler")
|
||||
}
|
||||
@@ -670,6 +678,10 @@ func (o *OperatorAPI) initHandlerCache() {
|
||||
if o.handlers["GET"] == nil {
|
||||
o.handlers["GET"] = make(map[string]http.Handler)
|
||||
}
|
||||
o.handlers["GET"]["/namespaces/{namespace}/tenants/{tenant}/pvcs"] = operator_api.NewListPVCsForTenant(o.context, o.OperatorAPIListPVCsForTenantHandler)
|
||||
if o.handlers["GET"] == nil {
|
||||
o.handlers["GET"] = make(map[string]http.Handler)
|
||||
}
|
||||
o.handlers["GET"]["/namespaces/{namespace}/tenants"] = operator_api.NewListTenants(o.context, o.OperatorAPIListTenantsHandler)
|
||||
if o.handlers["POST"] == nil {
|
||||
o.handlers["POST"] = make(map[string]http.Handler)
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
package operator_api
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the generate command
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
|
||||
"github.com/minio/console/models"
|
||||
)
|
||||
|
||||
// ListPVCsForTenantHandlerFunc turns a function with the right signature into a list p v cs for tenant handler
|
||||
type ListPVCsForTenantHandlerFunc func(ListPVCsForTenantParams, *models.Principal) middleware.Responder
|
||||
|
||||
// Handle executing the request and returning a response
|
||||
func (fn ListPVCsForTenantHandlerFunc) Handle(params ListPVCsForTenantParams, principal *models.Principal) middleware.Responder {
|
||||
return fn(params, principal)
|
||||
}
|
||||
|
||||
// ListPVCsForTenantHandler interface for that can handle valid list p v cs for tenant params
|
||||
type ListPVCsForTenantHandler interface {
|
||||
Handle(ListPVCsForTenantParams, *models.Principal) middleware.Responder
|
||||
}
|
||||
|
||||
// NewListPVCsForTenant creates a new http.Handler for the list p v cs for tenant operation
|
||||
func NewListPVCsForTenant(ctx *middleware.Context, handler ListPVCsForTenantHandler) *ListPVCsForTenant {
|
||||
return &ListPVCsForTenant{Context: ctx, Handler: handler}
|
||||
}
|
||||
|
||||
/* ListPVCsForTenant swagger:route GET /namespaces/{namespace}/tenants/{tenant}/pvcs OperatorAPI listPVCsForTenant
|
||||
|
||||
List all PVCs from given Tenant
|
||||
|
||||
*/
|
||||
type ListPVCsForTenant struct {
|
||||
Context *middleware.Context
|
||||
Handler ListPVCsForTenantHandler
|
||||
}
|
||||
|
||||
func (o *ListPVCsForTenant) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
route, rCtx, _ := o.Context.RouteInfo(r)
|
||||
if rCtx != nil {
|
||||
*r = *rCtx
|
||||
}
|
||||
var Params = NewListPVCsForTenantParams()
|
||||
uprinc, aCtx, err := o.Context.Authorize(r, route)
|
||||
if err != nil {
|
||||
o.Context.Respond(rw, r, route.Produces, route, err)
|
||||
return
|
||||
}
|
||||
if aCtx != nil {
|
||||
*r = *aCtx
|
||||
}
|
||||
var principal *models.Principal
|
||||
if uprinc != nil {
|
||||
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
|
||||
}
|
||||
|
||||
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
|
||||
o.Context.Respond(rw, r, route.Produces, route, err)
|
||||
return
|
||||
}
|
||||
|
||||
res := o.Handler.Handle(Params, principal) // actually handle the request
|
||||
o.Context.Respond(rw, r, route.Produces, route, res)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
package operator_api
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/go-openapi/strfmt"
|
||||
)
|
||||
|
||||
// NewListPVCsForTenantParams creates a new ListPVCsForTenantParams object
|
||||
//
|
||||
// There are no default values defined in the spec.
|
||||
func NewListPVCsForTenantParams() ListPVCsForTenantParams {
|
||||
|
||||
return ListPVCsForTenantParams{}
|
||||
}
|
||||
|
||||
// ListPVCsForTenantParams contains all the bound params for the list p v cs for tenant operation
|
||||
// typically these are obtained from a http.Request
|
||||
//
|
||||
// swagger:parameters ListPVCsForTenant
|
||||
type ListPVCsForTenantParams struct {
|
||||
|
||||
// HTTP Request Object
|
||||
HTTPRequest *http.Request `json:"-"`
|
||||
|
||||
/*
|
||||
Required: true
|
||||
In: path
|
||||
*/
|
||||
Namespace string
|
||||
/*
|
||||
Required: true
|
||||
In: path
|
||||
*/
|
||||
Tenant string
|
||||
}
|
||||
|
||||
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
|
||||
// for simple values it will use straight method calls.
|
||||
//
|
||||
// To ensure default values, the struct must have been initialized with NewListPVCsForTenantParams() beforehand.
|
||||
func (o *ListPVCsForTenantParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
|
||||
var res []error
|
||||
|
||||
o.HTTPRequest = r
|
||||
|
||||
rNamespace, rhkNamespace, _ := route.Params.GetOK("namespace")
|
||||
if err := o.bindNamespace(rNamespace, rhkNamespace, route.Formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
rTenant, rhkTenant, _ := route.Params.GetOK("tenant")
|
||||
if err := o.bindTenant(rTenant, rhkTenant, route.Formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// bindNamespace binds and validates parameter Namespace from path.
|
||||
func (o *ListPVCsForTenantParams) bindNamespace(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||
var raw string
|
||||
if len(rawData) > 0 {
|
||||
raw = rawData[len(rawData)-1]
|
||||
}
|
||||
|
||||
// Required: true
|
||||
// Parameter is provided by construction from the route
|
||||
o.Namespace = raw
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// bindTenant binds and validates parameter Tenant from path.
|
||||
func (o *ListPVCsForTenantParams) bindTenant(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||
var raw string
|
||||
if len(rawData) > 0 {
|
||||
raw = rawData[len(rawData)-1]
|
||||
}
|
||||
|
||||
// Required: true
|
||||
// Parameter is provided by construction from the route
|
||||
o.Tenant = raw
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
package operator_api
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/go-openapi/runtime"
|
||||
|
||||
"github.com/minio/console/models"
|
||||
)
|
||||
|
||||
// ListPVCsForTenantOKCode is the HTTP code returned for type ListPVCsForTenantOK
|
||||
const ListPVCsForTenantOKCode int = 200
|
||||
|
||||
/*ListPVCsForTenantOK A successful response.
|
||||
|
||||
swagger:response listPVCsForTenantOK
|
||||
*/
|
||||
type ListPVCsForTenantOK struct {
|
||||
|
||||
/*
|
||||
In: Body
|
||||
*/
|
||||
Payload *models.ListPVCsResponse `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// NewListPVCsForTenantOK creates ListPVCsForTenantOK with default headers values
|
||||
func NewListPVCsForTenantOK() *ListPVCsForTenantOK {
|
||||
|
||||
return &ListPVCsForTenantOK{}
|
||||
}
|
||||
|
||||
// WithPayload adds the payload to the list p v cs for tenant o k response
|
||||
func (o *ListPVCsForTenantOK) WithPayload(payload *models.ListPVCsResponse) *ListPVCsForTenantOK {
|
||||
o.Payload = payload
|
||||
return o
|
||||
}
|
||||
|
||||
// SetPayload sets the payload to the list p v cs for tenant o k response
|
||||
func (o *ListPVCsForTenantOK) SetPayload(payload *models.ListPVCsResponse) {
|
||||
o.Payload = payload
|
||||
}
|
||||
|
||||
// WriteResponse to the client
|
||||
func (o *ListPVCsForTenantOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||
|
||||
rw.WriteHeader(200)
|
||||
if o.Payload != nil {
|
||||
payload := o.Payload
|
||||
if err := producer.Produce(rw, payload); err != nil {
|
||||
panic(err) // let the recovery middleware deal with this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*ListPVCsForTenantDefault Generic error response.
|
||||
|
||||
swagger:response listPVCsForTenantDefault
|
||||
*/
|
||||
type ListPVCsForTenantDefault struct {
|
||||
_statusCode int
|
||||
|
||||
/*
|
||||
In: Body
|
||||
*/
|
||||
Payload *models.Error `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// NewListPVCsForTenantDefault creates ListPVCsForTenantDefault with default headers values
|
||||
func NewListPVCsForTenantDefault(code int) *ListPVCsForTenantDefault {
|
||||
if code <= 0 {
|
||||
code = 500
|
||||
}
|
||||
|
||||
return &ListPVCsForTenantDefault{
|
||||
_statusCode: code,
|
||||
}
|
||||
}
|
||||
|
||||
// WithStatusCode adds the status to the list p v cs for tenant default response
|
||||
func (o *ListPVCsForTenantDefault) WithStatusCode(code int) *ListPVCsForTenantDefault {
|
||||
o._statusCode = code
|
||||
return o
|
||||
}
|
||||
|
||||
// SetStatusCode sets the status to the list p v cs for tenant default response
|
||||
func (o *ListPVCsForTenantDefault) SetStatusCode(code int) {
|
||||
o._statusCode = code
|
||||
}
|
||||
|
||||
// WithPayload adds the payload to the list p v cs for tenant default response
|
||||
func (o *ListPVCsForTenantDefault) WithPayload(payload *models.Error) *ListPVCsForTenantDefault {
|
||||
o.Payload = payload
|
||||
return o
|
||||
}
|
||||
|
||||
// SetPayload sets the payload to the list p v cs for tenant default response
|
||||
func (o *ListPVCsForTenantDefault) SetPayload(payload *models.Error) {
|
||||
o.Payload = payload
|
||||
}
|
||||
|
||||
// WriteResponse to the client
|
||||
func (o *ListPVCsForTenantDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||
|
||||
rw.WriteHeader(o._statusCode)
|
||||
if o.Payload != nil {
|
||||
payload := o.Payload
|
||||
if err := producer.Produce(rw, payload); err != nil {
|
||||
panic(err) // let the recovery middleware deal with this
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
package operator_api
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the generate command
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/url"
|
||||
golangswaggerpaths "path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ListPVCsForTenantURL generates an URL for the list p v cs for tenant operation
|
||||
type ListPVCsForTenantURL struct {
|
||||
Namespace string
|
||||
Tenant string
|
||||
|
||||
_basePath string
|
||||
// avoid unkeyed usage
|
||||
_ struct{}
|
||||
}
|
||||
|
||||
// WithBasePath sets the base path for this url builder, only required when it's different from the
|
||||
// base path specified in the swagger spec.
|
||||
// When the value of the base path is an empty string
|
||||
func (o *ListPVCsForTenantURL) WithBasePath(bp string) *ListPVCsForTenantURL {
|
||||
o.SetBasePath(bp)
|
||||
return o
|
||||
}
|
||||
|
||||
// SetBasePath sets the base path for this url builder, only required when it's different from the
|
||||
// base path specified in the swagger spec.
|
||||
// When the value of the base path is an empty string
|
||||
func (o *ListPVCsForTenantURL) SetBasePath(bp string) {
|
||||
o._basePath = bp
|
||||
}
|
||||
|
||||
// Build a url path and query string
|
||||
func (o *ListPVCsForTenantURL) Build() (*url.URL, error) {
|
||||
var _result url.URL
|
||||
|
||||
var _path = "/namespaces/{namespace}/tenants/{tenant}/pvcs"
|
||||
|
||||
namespace := o.Namespace
|
||||
if namespace != "" {
|
||||
_path = strings.Replace(_path, "{namespace}", namespace, -1)
|
||||
} else {
|
||||
return nil, errors.New("namespace is required on ListPVCsForTenantURL")
|
||||
}
|
||||
|
||||
tenant := o.Tenant
|
||||
if tenant != "" {
|
||||
_path = strings.Replace(_path, "{tenant}", tenant, -1)
|
||||
} else {
|
||||
return nil, errors.New("tenant is required on ListPVCsForTenantURL")
|
||||
}
|
||||
|
||||
_basePath := o._basePath
|
||||
if _basePath == "" {
|
||||
_basePath = "/api/v1"
|
||||
}
|
||||
_result.Path = golangswaggerpaths.Join(_basePath, _path)
|
||||
|
||||
return &_result, nil
|
||||
}
|
||||
|
||||
// Must is a helper function to panic when the url builder returns an error
|
||||
func (o *ListPVCsForTenantURL) Must(u *url.URL, err error) *url.URL {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if u == nil {
|
||||
panic("url can't be nil")
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
// String returns the string representation of the path with query string
|
||||
func (o *ListPVCsForTenantURL) String() string {
|
||||
return o.Must(o.Build()).String()
|
||||
}
|
||||
|
||||
// BuildFull builds a full url with scheme, host, path and query string
|
||||
func (o *ListPVCsForTenantURL) BuildFull(scheme, host string) (*url.URL, error) {
|
||||
if scheme == "" {
|
||||
return nil, errors.New("scheme is required for a full url on ListPVCsForTenantURL")
|
||||
}
|
||||
if host == "" {
|
||||
return nil, errors.New("host is required for a full url on ListPVCsForTenantURL")
|
||||
}
|
||||
|
||||
base, err := o.Build()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
base.Scheme = scheme
|
||||
base.Host = host
|
||||
return base, nil
|
||||
}
|
||||
|
||||
// StringFull returns the string representation of a complete url
|
||||
func (o *ListPVCsForTenantURL) StringFull(scheme, host string) string {
|
||||
return o.Must(o.BuildFull(scheme, host)).String()
|
||||
}
|
||||
@@ -17,23 +17,17 @@
|
||||
package operatorapi
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/minio/minio-go/v7/pkg/credentials"
|
||||
|
||||
"github.com/minio/console/restapi"
|
||||
|
||||
iampolicy "github.com/minio/pkg/iam/policy"
|
||||
|
||||
"github.com/go-openapi/runtime"
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/console/operatorapi/operations"
|
||||
"github.com/minio/console/operatorapi/operations/user_api"
|
||||
"github.com/minio/console/pkg/acl"
|
||||
"github.com/minio/console/pkg/auth"
|
||||
"github.com/minio/console/pkg/auth/idp/oauth2"
|
||||
)
|
||||
@@ -95,7 +89,7 @@ func login(credentials restapi.ConsoleCredentialsI) (*string, error) {
|
||||
return nil, err
|
||||
}
|
||||
// if we made it here, the consoleCredentials work, generate a jwt with claims
|
||||
token, err := auth.NewEncryptedTokenForClient(&tokens, credentials.GetAccountAccessKey(), credentials.GetActions())
|
||||
token, err := auth.NewEncryptedTokenForClient(&tokens, credentials.GetAccountAccessKey())
|
||||
if err != nil {
|
||||
LogError("error authenticating user: %v", err)
|
||||
return nil, errInvalidCredentials
|
||||
@@ -103,67 +97,22 @@ func login(credentials restapi.ConsoleCredentialsI) (*string, error) {
|
||||
return &token, nil
|
||||
}
|
||||
|
||||
// getAccountPolicy will return the associated policy of the current account
|
||||
func getAccountPolicy(ctx context.Context, client restapi.MinioAdmin) (*iampolicy.Policy, error) {
|
||||
// Obtain the current policy assigned to this user
|
||||
// necessary for generating the list of allowed endpoints
|
||||
accountInfo, err := client.AccountInfo(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return iampolicy.ParseConfig(bytes.NewReader(accountInfo.Policy))
|
||||
}
|
||||
|
||||
// getConsoleCredentials will return consoleCredentials interface including the associated policy of the current account
|
||||
func getConsoleCredentials(ctx context.Context, accessKey, secretKey string) (*restapi.ConsoleCredentials, error) {
|
||||
func getConsoleCredentials(accessKey, secretKey string) (*restapi.ConsoleCredentials, error) {
|
||||
creds, err := newConsoleCredentials(secretKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// cCredentials will be sts credentials, account credentials will be need it in the scenario the user wish
|
||||
// to change its password
|
||||
cCredentials := &restapi.ConsoleCredentials{
|
||||
return &restapi.ConsoleCredentials{
|
||||
ConsoleCredentials: creds,
|
||||
AccountAccessKey: accessKey,
|
||||
}
|
||||
tokens, err := cCredentials.Get()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// initialize admin client
|
||||
mAdminClient, err := restapi.NewMinioAdminClient(&models.Principal{
|
||||
STSAccessKeyID: tokens.AccessKeyID,
|
||||
STSSecretAccessKey: tokens.SecretAccessKey,
|
||||
STSSessionToken: tokens.SessionToken,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
userAdminClient := restapi.AdminClient{Client: mAdminClient}
|
||||
// Obtain the current policy assigned to this user
|
||||
// necessary for generating the list of allowed endpoints
|
||||
policy, err := getAccountPolicy(ctx, userAdminClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// by default every user starts with an empty array of available actions
|
||||
// therefore we would have access only to pages that doesn't require any privilege
|
||||
// ie: service-account page
|
||||
var actions []string
|
||||
// if a policy is assigned to this user we parse the actions from there
|
||||
if policy != nil {
|
||||
actions = acl.GetActionsStringFromPolicy(policy)
|
||||
}
|
||||
cCredentials.Actions = actions
|
||||
return cCredentials, nil
|
||||
}, nil
|
||||
}
|
||||
|
||||
// getLoginResponse performs login() and serializes it to the handler's output
|
||||
func getLoginResponse(lr *models.LoginRequest) (*models.LoginResponse, *models.Error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||
defer cancel()
|
||||
// prepare console credentials
|
||||
consolCreds, err := getConsoleCredentials(ctx, *lr.AccessKey, *lr.SecretKey)
|
||||
consolCreds, err := getConsoleCredentials(*lr.AccessKey, *lr.SecretKey)
|
||||
if err != nil {
|
||||
return nil, prepareError(errInvalidCredentials, nil, err)
|
||||
}
|
||||
@@ -180,15 +129,13 @@ func getLoginResponse(lr *models.LoginRequest) (*models.LoginResponse, *models.E
|
||||
|
||||
// getLoginDetailsResponse returns information regarding the Console authentication mechanism.
|
||||
func getLoginDetailsResponse() (*models.LoginDetails, *models.Error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||
defer cancel()
|
||||
loginStrategy := models.LoginDetailsLoginStrategyServiceDashAccount
|
||||
redirectURL := ""
|
||||
|
||||
if oauth2.IsIdpEnabled() {
|
||||
if oauth2.IsIDPEnabled() {
|
||||
loginStrategy = models.LoginDetailsLoginStrategyRedirect
|
||||
// initialize new oauth2 client
|
||||
oauth2Client, err := oauth2.NewOauth2ProviderClient(ctx, nil, restapi.GetConsoleSTSClient())
|
||||
oauth2Client, err := oauth2.NewOauth2ProviderClient(nil, restapi.GetConsoleHTTPClient())
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
@@ -210,7 +157,7 @@ func getLoginOauth2AuthResponse() (*models.LoginResponse, *models.Error) {
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
consoleCredentials := restapi.ConsoleCredentials{ConsoleCredentials: creds, Actions: []string{}}
|
||||
consoleCredentials := restapi.ConsoleCredentials{ConsoleCredentials: creds}
|
||||
token, err := login(consoleCredentials)
|
||||
if err != nil {
|
||||
return nil, prepareError(errInvalidCredentials, nil, err)
|
||||
@@ -236,7 +183,7 @@ func getLoginOperatorResponse(lmr *models.LoginOperatorRequest) (*models.LoginRe
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
consoleCreds := restapi.ConsoleCredentials{ConsoleCredentials: creds, Actions: []string{}}
|
||||
consoleCreds := restapi.ConsoleCredentials{ConsoleCredentials: creds}
|
||||
token, err := login(consoleCreds)
|
||||
if err != nil {
|
||||
return nil, prepareError(errInvalidCredentials, nil, err)
|
||||
|
||||
@@ -42,7 +42,7 @@ func getSessionResponse(session *models.Principal) (*models.OperatorSessionRespo
|
||||
return nil, prepareError(errorGenericInvalidSession)
|
||||
}
|
||||
sessionResp := &models.OperatorSessionResponse{
|
||||
Pages: acl.GetAuthorizedEndpoints(session.Actions),
|
||||
Pages: acl.GetAuthorizedEndpoints([]string{}),
|
||||
Features: getListOfEnabledFeatures(),
|
||||
Status: models.OperatorSessionResponseStatusOk,
|
||||
Operator: true,
|
||||
|
||||
@@ -20,13 +20,12 @@ package operatorapi
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/minio/console/pkg/subnet"
|
||||
|
||||
miniov2 "github.com/minio/operator/pkg/apis/minio.min.io/v2"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/minio/console/restapi"
|
||||
@@ -38,10 +37,10 @@ import (
|
||||
"github.com/minio/console/operatorapi/operations/operator_api"
|
||||
)
|
||||
|
||||
func registerOperatorSubscriptionHandlers(api *operations.OperatorAPI) {
|
||||
func registerSubscriptionHandlers(api *operations.OperatorAPI) {
|
||||
// Activate license subscription for a particular tenant
|
||||
api.OperatorAPISubscriptionActivateHandler = operator_api.SubscriptionActivateHandlerFunc(func(params operator_api.SubscriptionActivateParams, session *models.Principal) middleware.Responder {
|
||||
err := getOperatorSubscriptionActivateResponse(session, params.Namespace, params.Tenant)
|
||||
err := getSubscriptionActivateResponse(session, params.Namespace, params.Tenant)
|
||||
if err != nil {
|
||||
return operator_api.NewSubscriptionActivateDefault(int(err.Code)).WithPayload(err)
|
||||
}
|
||||
@@ -55,10 +54,33 @@ func registerOperatorSubscriptionHandlers(api *operations.OperatorAPI) {
|
||||
}
|
||||
return operator_api.NewSubscriptionRefreshOK().WithPayload(license)
|
||||
})
|
||||
// Validate subscription handler
|
||||
api.OperatorAPISubscriptionValidateHandler = operator_api.SubscriptionValidateHandlerFunc(func(params operator_api.SubscriptionValidateParams, session *models.Principal) middleware.Responder {
|
||||
license, err := getSubscriptionValidateResponse(session, params.Body)
|
||||
if err != nil {
|
||||
return operator_api.NewSubscriptionValidateDefault(int(err.Code)).WithPayload(err)
|
||||
}
|
||||
return operator_api.NewSubscriptionValidateOK().WithPayload(license)
|
||||
})
|
||||
// Get subscription information handler
|
||||
api.OperatorAPISubscriptionInfoHandler = operator_api.SubscriptionInfoHandlerFunc(func(params operator_api.SubscriptionInfoParams, session *models.Principal) middleware.Responder {
|
||||
license, err := getSubscriptionInfoResponse(session)
|
||||
if err != nil {
|
||||
return operator_api.NewSubscriptionInfoDefault(int(err.Code)).WithPayload(err)
|
||||
}
|
||||
return operator_api.NewSubscriptionInfoOK().WithPayload(license)
|
||||
})
|
||||
// Refresh license for k8s cluster
|
||||
api.OperatorAPISubscriptionRefreshHandler = operator_api.SubscriptionRefreshHandlerFunc(func(params operator_api.SubscriptionRefreshParams, session *models.Principal) middleware.Responder {
|
||||
license, err := getSubscriptionRefreshResponse(session)
|
||||
if err != nil {
|
||||
return operator_api.NewSubscriptionRefreshDefault(int(err.Code)).WithPayload(err)
|
||||
}
|
||||
return operator_api.NewSubscriptionRefreshOK().WithPayload(license)
|
||||
})
|
||||
}
|
||||
|
||||
// retrieveLicense returns license from K8S secrets (If console is deployed in operator mode) or from
|
||||
// the configured CONSOLE_SUBNET_LICENSE environment variable
|
||||
// retrieveLicense returns license from K8S secrets
|
||||
func retrieveLicense(ctx context.Context, sessionToken string) (string, error) {
|
||||
var license string
|
||||
|
||||
@@ -79,46 +101,6 @@ func retrieveLicense(ctx context.Context, sessionToken string) (string, error) {
|
||||
return license, nil
|
||||
}
|
||||
|
||||
func getOperatorSubscriptionActivateResponse(session *models.Principal, namespace, tenant string) *models.Error {
|
||||
// 20 seconds timeout
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||
defer cancel()
|
||||
opClientClientSet, err := cluster.OperatorClient(session.STSSessionToken)
|
||||
if err != nil {
|
||||
return prepareError(restapi.ErrorGeneric, nil, err)
|
||||
}
|
||||
clientSet, err := cluster.K8sClient(session.STSSessionToken)
|
||||
if err != nil {
|
||||
return prepareError(restapi.ErrorGeneric, nil, err)
|
||||
}
|
||||
opClient := &operatorClient{
|
||||
client: opClientClientSet,
|
||||
}
|
||||
minTenant, err := getTenant(ctx, opClient, namespace, tenant)
|
||||
if err != nil {
|
||||
return prepareError(err, restapi.ErrorGeneric)
|
||||
}
|
||||
// If console is not deployed for this tenant return an error
|
||||
if minTenant.Spec.Console == nil {
|
||||
return prepareError(restapi.ErrorGenericNotFound)
|
||||
}
|
||||
|
||||
// configure kubernetes client
|
||||
k8sClient := k8sClient{
|
||||
client: clientSet,
|
||||
}
|
||||
// Get cluster subscription license
|
||||
license, err := getSubscriptionLicense(ctx, &k8sClient, cluster.Namespace, OperatorSubnetLicenseSecretName)
|
||||
if err != nil {
|
||||
return prepareError(errInvalidCredentials, nil, err)
|
||||
}
|
||||
// add subscription license to existing console Tenant
|
||||
if err = addSubscriptionLicenseToTenant(ctx, &k8sClient, license, namespace, tenant, minTenant.Spec.Console.ConsoleSecret.Name); err != nil {
|
||||
return prepareError(err, restapi.ErrorGeneric)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getSubscriptionLicense will retrieve stored license jwt from k8s secret
|
||||
func getSubscriptionLicense(ctx context.Context, clientSet K8sClientI, namespace, secretName string) (string, error) {
|
||||
// retrieve license stored in k8s
|
||||
@@ -135,86 +117,66 @@ func getSubscriptionLicense(ctx context.Context, clientSet K8sClientI, namespace
|
||||
}
|
||||
|
||||
// addSubscriptionLicenseToTenant replace existing console tenant secret and adds the subnet license key
|
||||
func addSubscriptionLicenseToTenant(ctx context.Context, clientSet K8sClientI, license, namespace, tenantName, secretName string) error {
|
||||
// Retrieve console secret for Tenant
|
||||
consoleSecret, err := clientSet.getSecret(ctx, namespace, secretName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Copy current console secret
|
||||
dataNewSecret := consoleSecret.Data
|
||||
// Add subnet license to the new console secret
|
||||
dataNewSecret[ConsoleSubnetLicense] = []byte(license)
|
||||
// Delete existing console secret
|
||||
err = clientSet.deleteSecret(ctx, namespace, secretName, metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Prepare the new Console Secret
|
||||
imm := true
|
||||
newConsoleSecret := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: secretName,
|
||||
Labels: map[string]string{
|
||||
miniov2.TenantLabel: tenantName,
|
||||
},
|
||||
},
|
||||
Immutable: &imm,
|
||||
Data: dataNewSecret,
|
||||
}
|
||||
// Create new Console secret with the subnet License
|
||||
_, err = clientSet.createSecret(ctx, namespace, newConsoleSecret, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// restart Console pods based on label:
|
||||
// v1.min.io/console: TENANT-console
|
||||
err = clientSet.deletePodCollection(ctx, namespace, metav1.DeleteOptions{}, metav1.ListOptions{
|
||||
LabelSelector: fmt.Sprintf("%s=%s%s", miniov2.ConsoleTenantLabel, tenantName, miniov2.ConsoleName),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateTenantLicenseAndRestartConsole
|
||||
func updateTenantLicenseAndRestartConsole(ctx context.Context, clientSet K8sClientI, license, namespace, tenantName string) error {
|
||||
consoleSelector := fmt.Sprintf("%s-console", tenantName)
|
||||
consoleSecretName := fmt.Sprintf("%s-secret", consoleSelector)
|
||||
// read current console configuration from k8s secrets
|
||||
currentConsoleSecret, err := clientSet.getSecret(ctx, namespace, consoleSecretName, metav1.GetOptions{})
|
||||
if err != nil || currentConsoleSecret == nil {
|
||||
return err
|
||||
}
|
||||
secretData := currentConsoleSecret.Data
|
||||
secretData[ConsoleSubnetLicense] = []byte(license)
|
||||
// delete existing console configuration from k8s secrets
|
||||
err = clientSet.deleteSecret(ctx, namespace, consoleSecretName, metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
// log the error if any and continue
|
||||
LogError("unable to delete secret %s: %v", consoleSecretName, err)
|
||||
}
|
||||
// Save subnet license in k8s secrets
|
||||
imm := true
|
||||
consoleConfigSecret := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: consoleSecretName,
|
||||
},
|
||||
Immutable: &imm,
|
||||
Data: secretData,
|
||||
}
|
||||
_, err = clientSet.createSecret(ctx, namespace, consoleConfigSecret, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// restart Console pods based on label:
|
||||
// v1.min.io/console: TENANT-console
|
||||
err = clientSet.deletePodCollection(ctx, namespace, metav1.DeleteOptions{}, metav1.ListOptions{
|
||||
LabelSelector: fmt.Sprintf("%s=%s%s", miniov2.ConsoleTenantLabel, tenantName, miniov2.ConsoleName),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
func addSubscriptionLicenseToTenant(ctx context.Context, clientSet K8sClientI, opClient OperatorClientI, license string, tenant *miniov2.Tenant) error {
|
||||
// If Tenant has a configuration secret update the license there and MinIO pods doesn't need to get restarted
|
||||
if tenant.HasConfigurationSecret() {
|
||||
// Update the Tenant Configuration
|
||||
tenantConfigurationSecret, err := clientSet.getSecret(ctx, tenant.Namespace, tenant.Spec.Configuration.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, ok := tenantConfigurationSecret.Data["config.env"]; ok {
|
||||
updatedTenantConfiguration := map[string]string{}
|
||||
tenantConfigurationMap := miniov2.ParseRawConfiguration(tenantConfigurationSecret.Data["config.env"])
|
||||
for key, val := range tenantConfigurationMap {
|
||||
updatedTenantConfiguration[key] = string(val)
|
||||
}
|
||||
updatedTenantConfiguration[MinIOSubnetLicense] = license
|
||||
// removing accesskey & secretkey that are added automatically by parsing function
|
||||
// and are not need it for the tenant itself
|
||||
delete(updatedTenantConfiguration, "accesskey")
|
||||
delete(updatedTenantConfiguration, "secretkey")
|
||||
tenantConfigurationSecret.Data = map[string][]byte{
|
||||
"config.env": []byte(GenerateTenantConfigurationFile(updatedTenantConfiguration)),
|
||||
}
|
||||
_, err = clientSet.updateSecret(ctx, tenant.Namespace, tenantConfigurationSecret, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return errors.New("tenant configuration secret has wrong format")
|
||||
}
|
||||
} else {
|
||||
// If configuration file is not present set the license to the container env
|
||||
updatedTenant := tenant.DeepCopy()
|
||||
// reset container env vars
|
||||
updatedTenant.Spec.Env = []corev1.EnvVar{}
|
||||
var licenseIsSet bool
|
||||
for _, env := range tenant.GetEnvVars() {
|
||||
// check if license already exists and override
|
||||
if env.Name == MinIOSubnetLicense {
|
||||
updatedTenant.Spec.Env = append(updatedTenant.Spec.Env, corev1.EnvVar{
|
||||
Name: MinIOSubnetLicense,
|
||||
Value: license,
|
||||
})
|
||||
licenseIsSet = true
|
||||
} else {
|
||||
// copy existing container env variables
|
||||
updatedTenant.Spec.Env = append(updatedTenant.Spec.Env, env)
|
||||
}
|
||||
}
|
||||
// if license didnt exists append it
|
||||
if !licenseIsSet {
|
||||
updatedTenant.Spec.Env = append(updatedTenant.Spec.Env, corev1.EnvVar{
|
||||
Name: MinIOSubnetLicense,
|
||||
Value: license,
|
||||
})
|
||||
}
|
||||
// this will start MinIO pods rolling restart
|
||||
_, err := opClient.TenantUpdate(ctx, updatedTenant, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -224,9 +186,9 @@ func getSubscriptionRefreshResponse(session *models.Principal) (*models.License,
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||
defer cancel()
|
||||
client := &cluster.HTTPClient{
|
||||
Client: restapi.GetConsoleSTSClient(),
|
||||
Client: restapi.GetConsoleHTTPClient(),
|
||||
}
|
||||
licenseKey, err := retrieveLicense(context.Background(), session.STSSessionToken)
|
||||
licenseKey, err := retrieveLicense(ctx, session.STSSessionToken)
|
||||
if err != nil {
|
||||
return nil, prepareError(errLicenseNotFound, nil, err)
|
||||
}
|
||||
@@ -251,17 +213,17 @@ func getSubscriptionRefreshResponse(session *models.Principal) (*models.License,
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
opClient := &operatorClient{
|
||||
opClient := operatorClient{
|
||||
client: opClientClientSet,
|
||||
}
|
||||
tenants, err := listTenants(ctx, opClient, "", nil)
|
||||
// iterate over all tenants and update licenses
|
||||
tenants, err := opClient.TenantList(ctx, "", metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
// iterate over all tenants, update console configuration and restart console pods
|
||||
for _, tenant := range tenants.Tenants {
|
||||
if err := updateTenantLicenseAndRestartConsole(ctx, &k8sClient, licenseRaw, tenant.Namespace, tenant.Name); err != nil {
|
||||
LogError("unable to updateTenantLicenseAndRestartConsole: %v", err)
|
||||
for _, tenant := range tenants.Items {
|
||||
if err = addSubscriptionLicenseToTenant(ctx, &k8sClient, &opClient, licenseRaw, &tenant); err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,7 +242,7 @@ func RefreshLicense() error {
|
||||
return err
|
||||
}
|
||||
client := &cluster.HTTPClient{
|
||||
Client: restapi.GetConsoleSTSClient(),
|
||||
Client: restapi.GetConsoleHTTPClient(),
|
||||
}
|
||||
// Attempt to refresh license
|
||||
_, refreshedLicenseKey, err := subscriptionRefresh(client, licenseKey)
|
||||
@@ -321,24 +283,31 @@ func subscriptionRefresh(httpClient *cluster.HTTPClient, license string) (*model
|
||||
|
||||
// saveSubscriptionLicense will create or replace an existing subnet license secret in the k8s cluster
|
||||
func saveSubscriptionLicense(ctx context.Context, clientSet K8sClientI, license string) error {
|
||||
// Delete subnet license secret if exists
|
||||
err := clientSet.deleteSecret(ctx, cluster.Namespace, OperatorSubnetLicenseSecretName, metav1.DeleteOptions{})
|
||||
licenseSecret, err := clientSet.getSecret(ctx, cluster.Namespace, OperatorSubnetLicenseSecretName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
// log the error if any and continue
|
||||
LogError("unable to delete secret %s: %v", OperatorSubnetLicenseSecretName, err)
|
||||
if k8serrors.IsNotFound(err) {
|
||||
// Save subnet license in k8s secrets
|
||||
licenseSecret := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: OperatorSubnetLicenseSecretName,
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
ConsoleSubnetLicense: []byte(license),
|
||||
},
|
||||
}
|
||||
_, err = clientSet.createSecret(ctx, cluster.Namespace, licenseSecret, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
// Save subnet license in k8s secrets
|
||||
imm := true
|
||||
licenseSecret := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: OperatorSubnetLicenseSecretName,
|
||||
},
|
||||
Immutable: &imm,
|
||||
Data: map[string][]byte{
|
||||
ConsoleSubnetLicense: []byte(license),
|
||||
},
|
||||
// update existing license
|
||||
licenseSecret.Data = map[string][]byte{
|
||||
ConsoleSubnetLicense: []byte(license),
|
||||
}
|
||||
_, err = clientSet.createSecret(ctx, cluster.Namespace, licenseSecret, metav1.CreateOptions{})
|
||||
_, err = clientSet.updateSecret(ctx, cluster.Namespace, licenseSecret, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -360,3 +329,88 @@ func subscriptionValidate(client cluster.HTTPClientI, license, email, password s
|
||||
Organization: licenseInfo.Organization,
|
||||
}, rawLicense, nil
|
||||
}
|
||||
|
||||
// getSubscriptionValidateResponse
|
||||
func getSubscriptionValidateResponse(session *models.Principal, params *models.SubscriptionValidateRequest) (*models.License, *models.Error) {
|
||||
// 20 seconds timeout
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||
defer cancel()
|
||||
|
||||
client := &cluster.HTTPClient{
|
||||
Client: restapi.GetConsoleHTTPClient(),
|
||||
}
|
||||
// validate license key
|
||||
licenseInfo, license, err := subscriptionValidate(client, params.License, params.Email, params.Password)
|
||||
if err != nil {
|
||||
return nil, prepareError(errInvalidLicense, nil, err)
|
||||
}
|
||||
// configure kubernetes client
|
||||
clientSet, err := cluster.K8sClient(session.STSSessionToken)
|
||||
k8sClient := k8sClient{
|
||||
client: clientSet,
|
||||
}
|
||||
if err != nil {
|
||||
return nil, prepareError(errorGeneric, nil, err)
|
||||
}
|
||||
// save license key to k8s
|
||||
if err = saveSubscriptionLicense(ctx, &k8sClient, license); err != nil {
|
||||
return nil, prepareError(errorGeneric, nil, err)
|
||||
}
|
||||
return licenseInfo, nil
|
||||
}
|
||||
|
||||
func getSubscriptionActivateResponse(session *models.Principal, namespace, tenantName string) *models.Error {
|
||||
// 20 seconds timeout
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||
defer cancel()
|
||||
opClientClientSet, err := cluster.OperatorClient(session.STSSessionToken)
|
||||
if err != nil {
|
||||
return prepareError(errorGeneric, nil, err)
|
||||
}
|
||||
clientSet, err := cluster.K8sClient(session.STSSessionToken)
|
||||
if err != nil {
|
||||
return prepareError(errorGeneric, nil, err)
|
||||
}
|
||||
opClient := operatorClient{
|
||||
client: opClientClientSet,
|
||||
}
|
||||
tenant, err := getTenant(ctx, &opClient, namespace, tenantName)
|
||||
if err != nil {
|
||||
return prepareError(err, errorGeneric)
|
||||
}
|
||||
// configure kubernetes client
|
||||
k8sClient := k8sClient{
|
||||
client: clientSet,
|
||||
}
|
||||
// Get cluster subscription license
|
||||
license, err := getSubscriptionLicense(ctx, &k8sClient, cluster.Namespace, OperatorSubnetLicenseSecretName)
|
||||
if err != nil {
|
||||
return prepareError(errInvalidCredentials, nil, err)
|
||||
}
|
||||
// add subscription license to existing console Tenant
|
||||
if err = addSubscriptionLicenseToTenant(ctx, &k8sClient, &opClient, license, tenant); err != nil {
|
||||
return prepareError(err, errorGeneric)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getSubscriptionInfoResponse returns information about the current configured subnet license for Console
|
||||
func getSubscriptionInfoResponse(session *models.Principal) (*models.License, *models.Error) {
|
||||
// 20 seconds timeout
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||
defer cancel()
|
||||
var licenseInfo *models.License
|
||||
client := &cluster.HTTPClient{
|
||||
Client: restapi.GetConsoleHTTPClient(),
|
||||
}
|
||||
licenseKey, err := retrieveLicense(ctx, session.STSSessionToken)
|
||||
if err != nil {
|
||||
return nil, prepareError(errLicenseNotFound, nil, err)
|
||||
}
|
||||
// validate license key and obtain license info
|
||||
licenseInfo, _, err = subscriptionValidate(client, licenseKey, "", "")
|
||||
if err != nil {
|
||||
return nil, prepareError(errLicenseNotFound, nil, err)
|
||||
}
|
||||
return licenseInfo, nil
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
v2 "github.com/minio/operator/pkg/apis/minio.min.io/v2"
|
||||
|
||||
"errors"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
@@ -28,13 +30,17 @@ import (
|
||||
|
||||
func Test_addSubscriptionLicenseToTenant(t *testing.T) {
|
||||
k8sClient := k8sClientMock{}
|
||||
opClient := opClientMock{}
|
||||
tenant := &v2.Tenant{
|
||||
ObjectMeta: metav1.ObjectMeta{},
|
||||
Spec: v2.TenantSpec{},
|
||||
}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
clientSet K8sClientI
|
||||
license string
|
||||
namespace string
|
||||
tenantName string
|
||||
secretName string
|
||||
ctx context.Context
|
||||
clientSet K8sClientI
|
||||
opClient OperatorClientI
|
||||
license string
|
||||
tenant *v2.Tenant
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -43,150 +49,158 @@ func Test_addSubscriptionLicenseToTenant(t *testing.T) {
|
||||
mockFunc func()
|
||||
}{
|
||||
{
|
||||
name: "error because subnet license doesnt exists",
|
||||
name: "success updating subscription for tenant with configuration file",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
clientSet: k8sClient,
|
||||
license: "",
|
||||
namespace: "",
|
||||
tenantName: "",
|
||||
secretName: "subnet-license",
|
||||
},
|
||||
wantErr: true,
|
||||
mockFunc: func() {
|
||||
k8sclientGetSecretMock = func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
return nil, errors.New("something went wrong")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "error because existing license could not be deleted",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
clientSet: k8sClient,
|
||||
license: "",
|
||||
namespace: "",
|
||||
tenantName: "",
|
||||
secretName: OperatorSubnetLicenseSecretName,
|
||||
},
|
||||
wantErr: true,
|
||||
mockFunc: func() {
|
||||
k8sclientGetSecretMock = func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
imm := true
|
||||
return &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: OperatorSubnetLicenseSecretName,
|
||||
},
|
||||
Immutable: &imm,
|
||||
Data: map[string][]byte{
|
||||
ConsoleSubnetLicense: []byte("eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZW5pbitjMUBtaW5pby5pbyIsInRlYW1OYW1lIjoiY29uc29sZS1jdXN0b21lciIsImV4cCI6MS42Mzk5NTI2MTE2MDkxNDQ3MzJlOSwiaXNzIjoic3VibmV0QG1pbmlvLmlvIiwiY2FwYWNpdHkiOjI1LCJpYXQiOjEuNjA4NDE2NjExNjA5MTQ0NzMyZTksImFjY291bnRJZCI6MTc2LCJzZXJ2aWNlVHlwZSI6IlNUQU5EQVJEIn0.ndtf8V_FJTvhXeemVLlORyDev6RJaSPhZ2djkMVK9SvXD0srR_qlYJATPjC4NljkS71nXMGVDov5uCTuUL97x6FGQEKDruA-z24x_2Zr8kof4LfBb3HUHudCR8QvE--I"),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
DeleteSecretMock = func(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error {
|
||||
return errors.New("something went wrong")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "error because unable to create new subnet license",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
clientSet: k8sClient,
|
||||
license: "",
|
||||
namespace: "",
|
||||
tenantName: "",
|
||||
secretName: OperatorSubnetLicenseSecretName,
|
||||
},
|
||||
wantErr: true,
|
||||
mockFunc: func() {
|
||||
k8sclientGetSecretMock = func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
imm := true
|
||||
return &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: OperatorSubnetLicenseSecretName,
|
||||
},
|
||||
Immutable: &imm,
|
||||
Data: map[string][]byte{
|
||||
ConsoleSubnetLicense: []byte("eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZW5pbitjMUBtaW5pby5pbyIsInRlYW1OYW1lIjoiY29uc29sZS1jdXN0b21lciIsImV4cCI6MS42Mzk5NTI2MTE2MDkxNDQ3MzJlOSwiaXNzIjoic3VibmV0QG1pbmlvLmlvIiwiY2FwYWNpdHkiOjI1LCJpYXQiOjEuNjA4NDE2NjExNjA5MTQ0NzMyZTksImFjY291bnRJZCI6MTc2LCJzZXJ2aWNlVHlwZSI6IlNUQU5EQVJEIn0.ndtf8V_FJTvhXeemVLlORyDev6RJaSPhZ2djkMVK9SvXD0srR_qlYJATPjC4NljkS71nXMGVDov5uCTuUL97x6FGQEKDruA-z24x_2Zr8kof4LfBb3HUHudCR8QvE--I"),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
DeleteSecretMock = func(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error {
|
||||
return nil
|
||||
}
|
||||
CreateSecretMock = func(ctx context.Context, namespace string, secret *corev1.Secret, opts metav1.CreateOptions) (*corev1.Secret, error) {
|
||||
return nil, errors.New("something went wrong")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "error because unable to delete pod collection",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
clientSet: k8sClient,
|
||||
license: "",
|
||||
namespace: "",
|
||||
tenantName: "",
|
||||
secretName: OperatorSubnetLicenseSecretName,
|
||||
},
|
||||
wantErr: true,
|
||||
mockFunc: func() {
|
||||
k8sclientGetSecretMock = func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
imm := true
|
||||
return &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: OperatorSubnetLicenseSecretName,
|
||||
},
|
||||
Immutable: &imm,
|
||||
Data: map[string][]byte{
|
||||
ConsoleSubnetLicense: []byte("eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZW5pbitjMUBtaW5pby5pbyIsInRlYW1OYW1lIjoiY29uc29sZS1jdXN0b21lciIsImV4cCI6MS42Mzk5NTI2MTE2MDkxNDQ3MzJlOSwiaXNzIjoic3VibmV0QG1pbmlvLmlvIiwiY2FwYWNpdHkiOjI1LCJpYXQiOjEuNjA4NDE2NjExNjA5MTQ0NzMyZTksImFjY291bnRJZCI6MTc2LCJzZXJ2aWNlVHlwZSI6IlNUQU5EQVJEIn0.ndtf8V_FJTvhXeemVLlORyDev6RJaSPhZ2djkMVK9SvXD0srR_qlYJATPjC4NljkS71nXMGVDov5uCTuUL97x6FGQEKDruA-z24x_2Zr8kof4LfBb3HUHudCR8QvE--I"),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
DeleteSecretMock = func(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error {
|
||||
return nil
|
||||
}
|
||||
CreateSecretMock = func(ctx context.Context, namespace string, secret *corev1.Secret, opts metav1.CreateOptions) (*corev1.Secret, error) {
|
||||
return nil, nil
|
||||
}
|
||||
DeletePodCollectionMock = func(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
|
||||
return errors.New("something went wrong")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "subscription updated successfully",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
clientSet: k8sClient,
|
||||
license: "",
|
||||
namespace: "",
|
||||
tenantName: "",
|
||||
secretName: OperatorSubnetLicenseSecretName,
|
||||
ctx: context.Background(),
|
||||
clientSet: k8sClient,
|
||||
opClient: opClient,
|
||||
license: "",
|
||||
tenant: tenant,
|
||||
},
|
||||
wantErr: false,
|
||||
mockFunc: func() {
|
||||
tenant.Spec.Configuration = &corev1.LocalObjectReference{
|
||||
Name: "minio-configuration",
|
||||
}
|
||||
k8sclientGetSecretMock = func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
imm := true
|
||||
return &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: OperatorSubnetLicenseSecretName,
|
||||
Name: "minio-configuration",
|
||||
},
|
||||
Immutable: &imm,
|
||||
Data: map[string][]byte{
|
||||
ConsoleSubnetLicense: []byte("eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZW5pbitjMUBtaW5pby5pbyIsInRlYW1OYW1lIjoiY29uc29sZS1jdXN0b21lciIsImV4cCI6MS42Mzk5NTI2MTE2MDkxNDQ3MzJlOSwiaXNzIjoic3VibmV0QG1pbmlvLmlvIiwiY2FwYWNpdHkiOjI1LCJpYXQiOjEuNjA4NDE2NjExNjA5MTQ0NzMyZTksImFjY291bnRJZCI6MTc2LCJzZXJ2aWNlVHlwZSI6IlNUQU5EQVJEIn0.ndtf8V_FJTvhXeemVLlORyDev6RJaSPhZ2djkMVK9SvXD0srR_qlYJATPjC4NljkS71nXMGVDov5uCTuUL97x6FGQEKDruA-z24x_2Zr8kof4LfBb3HUHudCR8QvE--I"),
|
||||
"config.env": []byte("export MINIO_SUBNET_LICENSE=\"eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZW5pbitjMUBtaW5pby5pbyIsInRlYW1OYW1lIjoiY29uc29sZS1jdXN0b21lciIsImV4cCI6MS42Mzk5NTI2MTE2MDkxNDQ3MzJlOSwiaXNzIjoic3VibmV0QG1pbmlvLmlvIiwiY2FwYWNpdHkiOjI1LCJpYXQiOjEuNjA4NDE2NjExNjA5MTQ0NzMyZTksImFjY291bnRJZCI6MTc2LCJzZXJ2aWNlVHlwZSI6IlNUQU5EQVJEIn0.ndtf8V_FJTvhXeemVLlORyDev6RJaSPhZ2djkMVK9SvXD0srR_qlYJATPjC4NljkS71nXMGVDov5uCTuUL97x6FGQEKDruA-z24x_2Zr8kof4LfBb3HUHudCR8QvE--I\""),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
DeleteSecretMock = func(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error {
|
||||
return nil
|
||||
}
|
||||
CreateSecretMock = func(ctx context.Context, namespace string, secret *corev1.Secret, opts metav1.CreateOptions) (*corev1.Secret, error) {
|
||||
UpdateSecretMock = func(ctx context.Context, namespace string, secret *corev1.Secret, opts metav1.UpdateOptions) (*corev1.Secret, error) {
|
||||
return nil, nil
|
||||
}
|
||||
DeletePodCollectionMock = func(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "error updating subscription for tenant because cannot get configuration file",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
clientSet: k8sClient,
|
||||
opClient: opClient,
|
||||
license: "",
|
||||
tenant: tenant,
|
||||
},
|
||||
wantErr: true,
|
||||
mockFunc: func() {
|
||||
tenant.Spec.Configuration = &corev1.LocalObjectReference{
|
||||
Name: "minio-configuration",
|
||||
}
|
||||
k8sclientGetSecretMock = func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
return nil, errors.New("something wrong happened")
|
||||
}
|
||||
UpdateSecretMock = func(ctx context.Context, namespace string, secret *corev1.Secret, opts metav1.UpdateOptions) (*corev1.Secret, error) {
|
||||
return nil, nil
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "error updating subscription for tenant because configuration file has wrong format",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
clientSet: k8sClient,
|
||||
opClient: opClient,
|
||||
license: "",
|
||||
tenant: tenant,
|
||||
},
|
||||
wantErr: true,
|
||||
mockFunc: func() {
|
||||
tenant.Spec.Configuration = &corev1.LocalObjectReference{
|
||||
Name: "minio-configuration",
|
||||
}
|
||||
k8sclientGetSecretMock = func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
return &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "minio-configuration",
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"aaaaa": []byte("export MINIO_SUBNET_LICENSE=\"eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZW5pbitjMUBtaW5pby5pbyIsInRlYW1OYW1lIjoiY29uc29sZS1jdXN0b21lciIsImV4cCI6MS42Mzk5NTI2MTE2MDkxNDQ3MzJlOSwiaXNzIjoic3VibmV0QG1pbmlvLmlvIiwiY2FwYWNpdHkiOjI1LCJpYXQiOjEuNjA4NDE2NjExNjA5MTQ0NzMyZTksImFjY291bnRJZCI6MTc2LCJzZXJ2aWNlVHlwZSI6IlNUQU5EQVJEIn0.ndtf8V_FJTvhXeemVLlORyDev6RJaSPhZ2djkMVK9SvXD0srR_qlYJATPjC4NljkS71nXMGVDov5uCTuUL97x6FGQEKDruA-z24x_2Zr8kof4LfBb3HUHudCR8QvE--I\""),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
UpdateSecretMock = func(ctx context.Context, namespace string, secret *corev1.Secret, opts metav1.UpdateOptions) (*corev1.Secret, error) {
|
||||
return nil, nil
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "error updating subscription for tenant because cannot update configuration file",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
clientSet: k8sClient,
|
||||
opClient: opClient,
|
||||
license: "",
|
||||
tenant: tenant,
|
||||
},
|
||||
wantErr: true,
|
||||
mockFunc: func() {
|
||||
tenant.Spec.Configuration = &corev1.LocalObjectReference{
|
||||
Name: "minio-configuration",
|
||||
}
|
||||
k8sclientGetSecretMock = func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
return &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "minio-configuration",
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"config.env": []byte("export MINIO_SUBNET_LICENSE=\"eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZW5pbitjMUBtaW5pby5pbyIsInRlYW1OYW1lIjoiY29uc29sZS1jdXN0b21lciIsImV4cCI6MS42Mzk5NTI2MTE2MDkxNDQ3MzJlOSwiaXNzIjoic3VibmV0QG1pbmlvLmlvIiwiY2FwYWNpdHkiOjI1LCJpYXQiOjEuNjA4NDE2NjExNjA5MTQ0NzMyZTksImFjY291bnRJZCI6MTc2LCJzZXJ2aWNlVHlwZSI6IlNUQU5EQVJEIn0.ndtf8V_FJTvhXeemVLlORyDev6RJaSPhZ2djkMVK9SvXD0srR_qlYJATPjC4NljkS71nXMGVDov5uCTuUL97x6FGQEKDruA-z24x_2Zr8kof4LfBb3HUHudCR8QvE--I\""),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
UpdateSecretMock = func(ctx context.Context, namespace string, secret *corev1.Secret, opts metav1.UpdateOptions) (*corev1.Secret, error) {
|
||||
return nil, errors.New("something wrong happened")
|
||||
}
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "success updating subscription for tenant with env variable",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
clientSet: k8sClient,
|
||||
opClient: opClient,
|
||||
license: "",
|
||||
tenant: tenant,
|
||||
},
|
||||
wantErr: false,
|
||||
mockFunc: func() {
|
||||
tenant.Spec.Env = []corev1.EnvVar{
|
||||
{
|
||||
Name: "MINIO_SUBNET_LICENSE",
|
||||
Value: "",
|
||||
ValueFrom: nil,
|
||||
},
|
||||
}
|
||||
opClientTenantUpdateMock = func(ctx context.Context, tenant *v2.Tenant, opts metav1.UpdateOptions) (*v2.Tenant, error) {
|
||||
return nil, nil
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "error updating subscription for tenant with env variable because of update tenant error",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
clientSet: k8sClient,
|
||||
opClient: opClient,
|
||||
license: "",
|
||||
tenant: tenant,
|
||||
},
|
||||
wantErr: true,
|
||||
mockFunc: func() {
|
||||
tenant.Spec.Env = []corev1.EnvVar{
|
||||
{
|
||||
Name: "MINIO_SUBNET_LICENSE",
|
||||
Value: "",
|
||||
ValueFrom: nil,
|
||||
},
|
||||
}
|
||||
opClientTenantUpdateMock = func(ctx context.Context, tenant *v2.Tenant, opts metav1.UpdateOptions) (*v2.Tenant, error) {
|
||||
return nil, errors.New("something wrong happened")
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -196,7 +210,7 @@ func Test_addSubscriptionLicenseToTenant(t *testing.T) {
|
||||
if tt.mockFunc != nil {
|
||||
tt.mockFunc()
|
||||
}
|
||||
if err := addSubscriptionLicenseToTenant(tt.args.ctx, tt.args.clientSet, tt.args.license, tt.args.namespace, tt.args.tenantName, tt.args.secretName); (err != nil) != tt.wantErr {
|
||||
if err := addSubscriptionLicenseToTenant(tt.args.ctx, tt.args.clientSet, tt.args.opClient, tt.args.license, tt.args.tenant); (err != nil) != tt.wantErr {
|
||||
t.Errorf("addSubscriptionLicenseToTenant() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -33,10 +33,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/minio/console/pkg/auth/ldap"
|
||||
|
||||
"github.com/minio/console/pkg/auth/idp/oauth2"
|
||||
|
||||
"github.com/dustin/go-humanize"
|
||||
|
||||
"github.com/minio/console/restapi"
|
||||
@@ -268,7 +264,14 @@ func getDeleteTenantResponse(session *models.Principal, params operator_api.Dele
|
||||
if params.Body != nil {
|
||||
deleteTenantPVCs = params.Body.DeletePvcs
|
||||
}
|
||||
if err = deleteTenantAction(context.Background(), opClient, clientset.CoreV1(), params.Namespace, params.Tenant, deleteTenantPVCs); err != nil {
|
||||
|
||||
tenant, err := opClient.TenantGet(params.HTTPRequest.Context(), params.Namespace, params.Tenant, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return prepareError(err)
|
||||
}
|
||||
tenant.EnsureDefaults()
|
||||
|
||||
if err = deleteTenantAction(params.HTTPRequest.Context(), opClient, clientset.CoreV1(), tenant, deleteTenantPVCs); err != nil {
|
||||
return prepareError(err)
|
||||
}
|
||||
return nil
|
||||
@@ -281,10 +284,10 @@ func deleteTenantAction(
|
||||
ctx context.Context,
|
||||
operatorClient OperatorClientI,
|
||||
clientset v1.CoreV1Interface,
|
||||
namespace, tenantName string,
|
||||
tenant *miniov2.Tenant,
|
||||
deletePvcs bool) error {
|
||||
|
||||
err := operatorClient.TenantDelete(ctx, namespace, tenantName, metav1.DeleteOptions{})
|
||||
err := operatorClient.TenantDelete(ctx, tenant.Namespace, tenant.Name, metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
// try to delete pvc even if the tenant doesn't exist anymore but only if deletePvcs is set to true,
|
||||
// else, we return the error
|
||||
@@ -294,15 +297,37 @@ func deleteTenantAction(
|
||||
}
|
||||
|
||||
if deletePvcs {
|
||||
|
||||
// delete MinIO PVCs
|
||||
opts := metav1.ListOptions{
|
||||
LabelSelector: fmt.Sprintf("%s=%s", miniov2.TenantLabel, tenantName),
|
||||
LabelSelector: fmt.Sprintf("%s=%s", miniov2.TenantLabel, tenant.Name),
|
||||
}
|
||||
err = clientset.PersistentVolumeClaims(namespace).DeleteCollection(ctx, metav1.DeleteOptions{}, opts)
|
||||
err = clientset.PersistentVolumeClaims(tenant.Namespace).DeleteCollection(ctx, metav1.DeleteOptions{}, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// delete postgres PVCs
|
||||
|
||||
logOpts := metav1.ListOptions{
|
||||
LabelSelector: fmt.Sprintf("%s=%s", miniov2.LogDBInstanceLabel, tenant.LogStatefulsetName()),
|
||||
}
|
||||
err := clientset.PersistentVolumeClaims(tenant.Namespace).DeleteCollection(ctx, metav1.DeleteOptions{}, logOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// delete prometheus PVCs
|
||||
|
||||
promOpts := metav1.ListOptions{
|
||||
LabelSelector: fmt.Sprintf("%s=%s", miniov2.PrometheusInstanceLabel, tenant.PrometheusStatefulsetName()),
|
||||
}
|
||||
|
||||
if err := clientset.PersistentVolumeClaims(tenant.Namespace).DeleteCollection(ctx, metav1.DeleteOptions{}, promOpts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// delete all tenant's secrets only if deletePvcs = true
|
||||
return clientset.Secrets(namespace).DeleteCollection(ctx, metav1.DeleteOptions{}, opts)
|
||||
return clientset.Secrets(tenant.Namespace).DeleteCollection(ctx, metav1.DeleteOptions{}, opts)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -342,7 +367,7 @@ func getTenantAdminClient(ctx context.Context, client K8sClientI, tenant *miniov
|
||||
return nil, err
|
||||
}
|
||||
sessionToken := ""
|
||||
mAdmin, pErr := restapi.NewAdminClientWithInsecure(svcURL, tenantCreds.accessKey, tenantCreds.secretKey, sessionToken, false)
|
||||
mAdmin, pErr := restapi.NewAdminClientWithInsecure(svcURL, tenantCreds.accessKey, tenantCreds.secretKey, sessionToken, true)
|
||||
if pErr != nil {
|
||||
return nil, pErr.Cause
|
||||
}
|
||||
@@ -355,36 +380,29 @@ type tenantKeys struct {
|
||||
}
|
||||
|
||||
func getTenantCreds(ctx context.Context, client K8sClientI, tenant *miniov2.Tenant) (*tenantKeys, error) {
|
||||
if tenant == nil || tenant.Spec.CredsSecret == nil {
|
||||
return nil, errors.New("invalid arguments")
|
||||
}
|
||||
// get admin credentials from secret
|
||||
creds, err := client.getSecret(ctx, tenant.Namespace, tenant.Spec.CredsSecret.Name, metav1.GetOptions{})
|
||||
tenantConfiguration, err := GetTenantConfiguration(ctx, client, tenant)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tenantAccessKey, ok := creds.Data["accesskey"]
|
||||
tenantAccessKey, ok := tenantConfiguration["accesskey"]
|
||||
if !ok {
|
||||
restapi.LogError("tenant's secret doesn't contain accesskey")
|
||||
return nil, restapi.ErrorGeneric
|
||||
}
|
||||
tenantSecretKey, ok := creds.Data["secretkey"]
|
||||
tenantSecretKey, ok := tenantConfiguration["secretkey"]
|
||||
if !ok {
|
||||
restapi.LogError("tenant's secret doesn't contain secretkey")
|
||||
return nil, restapi.ErrorGeneric
|
||||
}
|
||||
// TODO:
|
||||
// We need to avoid using minio root credentials to talk to tenants, and instead use a different user credentials
|
||||
// when that its implemented we also need to check here if the tenant has LDAP enabled so we authenticate first against AD
|
||||
return &tenantKeys{accessKey: string(tenantAccessKey), secretKey: string(tenantSecretKey)}, nil
|
||||
return &tenantKeys{accessKey: tenantAccessKey, secretKey: tenantSecretKey}, nil
|
||||
}
|
||||
|
||||
func getTenant(ctx context.Context, operatorClient OperatorClientI, namespace, tenantName string) (*miniov2.Tenant, error) {
|
||||
minInst, err := operatorClient.TenantGet(ctx, namespace, tenantName, metav1.GetOptions{})
|
||||
tenant, err := operatorClient.TenantGet(ctx, namespace, tenantName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return minInst, nil
|
||||
return tenant, nil
|
||||
}
|
||||
|
||||
func isPrometheusEnabled(annotations map[string]string) bool {
|
||||
@@ -407,7 +425,6 @@ func isPrometheusEnabled(annotations map[string]string) bool {
|
||||
|
||||
func getTenantInfo(tenant *miniov2.Tenant) *models.Tenant {
|
||||
var pools []*models.Pool
|
||||
consoleImage := ""
|
||||
var totalSize int64
|
||||
for _, p := range tenant.Spec.Pools {
|
||||
pools = append(pools, parseTenantPool(&p))
|
||||
@@ -419,10 +436,6 @@ func getTenantInfo(tenant *miniov2.Tenant) *models.Tenant {
|
||||
deletion = tenant.ObjectMeta.DeletionTimestamp.Format(time.RFC3339)
|
||||
}
|
||||
|
||||
if tenant.HasConsoleEnabled() {
|
||||
consoleImage = tenant.Spec.Console.Image
|
||||
}
|
||||
|
||||
return &models.Tenant{
|
||||
CreationDate: tenant.ObjectMeta.CreationTimestamp.Format(time.RFC3339),
|
||||
DeletionDate: deletion,
|
||||
@@ -432,16 +445,14 @@ func getTenantInfo(tenant *miniov2.Tenant) *models.Tenant {
|
||||
Pools: pools,
|
||||
Namespace: tenant.ObjectMeta.Namespace,
|
||||
Image: tenant.Spec.Image,
|
||||
ConsoleImage: consoleImage,
|
||||
EnablePrometheus: isPrometheusEnabled(tenant.Annotations),
|
||||
}
|
||||
}
|
||||
|
||||
func getTenantDetailsResponse(session *models.Principal, params operator_api.TenantDetailsParams) (*models.Tenant, *models.Error) {
|
||||
// 5 seconds timeout
|
||||
//ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
//defer cancel()
|
||||
ctx := context.Background()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
opClientClientSet, err := cluster.OperatorClient(session.STSSessionToken)
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
@@ -468,32 +479,9 @@ func getTenantDetailsResponse(session *models.Principal, params operator_api.Ten
|
||||
client: clientSet,
|
||||
}
|
||||
|
||||
tenantConfiguration := map[string][]byte{}
|
||||
|
||||
for _, config := range minTenant.GetEnvVars() {
|
||||
tenantConfiguration[config.Name] = []byte(config.Value)
|
||||
}
|
||||
|
||||
if minTenant.HasCredsSecret() {
|
||||
minioSecret, err := clientSet.CoreV1().Secrets(minTenant.Namespace).Get(ctx, minTenant.Spec.CredsSecret.Name, metav1.GetOptions{})
|
||||
// we can tolerate not getting this secret
|
||||
if err != nil {
|
||||
restapi.LogError("unable to fetch existing secrets for %s: %v", minTenant.Name, err)
|
||||
}
|
||||
configFromCredsSecret := minioSecret.Data
|
||||
for key, val := range configFromCredsSecret {
|
||||
tenantConfiguration[key] = val
|
||||
}
|
||||
}
|
||||
|
||||
if minTenant.HasConfigurationSecret() {
|
||||
minioConfigurationSecret, err := clientSet.CoreV1().Secrets(minTenant.Namespace).Get(ctx, minTenant.Spec.Configuration.Name, metav1.GetOptions{})
|
||||
if err == nil {
|
||||
configFromFile := miniov2.ParseRawConfiguration(minioConfigurationSecret.Data["config.env"])
|
||||
for key, val := range configFromFile {
|
||||
tenantConfiguration[key] = val
|
||||
}
|
||||
}
|
||||
tenantConfiguration, err := GetTenantConfiguration(ctx, &k8sClient, minTenant)
|
||||
if err != nil {
|
||||
restapi.LogError("unable to fetch configuration for tenant %s: %v", minTenant.Name, err)
|
||||
}
|
||||
|
||||
// detect if AD/LDAP is enabled
|
||||
@@ -508,27 +496,26 @@ func getTenantDetailsResponse(session *models.Principal, params operator_api.Ten
|
||||
oidcEnabled = true
|
||||
}
|
||||
|
||||
// detect if encryption is enabled
|
||||
if minTenant.HasKESEnabled() || string(tenantConfiguration["MINIO_KMS_SECRET_KEY"]) != "" {
|
||||
info.EncryptionEnabled = true
|
||||
}
|
||||
|
||||
info.LogEnabled = minTenant.HasLogEnabled()
|
||||
info.MonitoringEnabled = minTenant.HasPrometheusEnabled()
|
||||
info.EncryptionEnabled = minTenant.HasKESEnabled()
|
||||
info.IdpAdEnabled = ldapEnabled
|
||||
info.IdpOidcEnabled = oidcEnabled
|
||||
info.MinioTLS = minTenant.TLS()
|
||||
info.ConsoleTLS = minTenant.AutoCert() || minTenant.ConsoleExternalCert()
|
||||
info.ConsoleEnabled = minTenant.HasConsoleEnabled()
|
||||
|
||||
if minTenant.Spec.Console != nil {
|
||||
// obtain current subnet license for tenant (if exists)
|
||||
license, _ := getSubscriptionLicense(context.Background(), &k8sClient, params.Namespace, minTenant.Spec.Console.ConsoleSecret.Name)
|
||||
if license != "" {
|
||||
client := &cluster.HTTPClient{
|
||||
Client: restapi.GetConsoleSTSClient(),
|
||||
}
|
||||
licenseInfo, _, _ := subscriptionValidate(client, license, "", "")
|
||||
// if licenseInfo is present attach it to the tenantInfo response
|
||||
if licenseInfo != nil {
|
||||
info.SubnetLicense = licenseInfo
|
||||
}
|
||||
// obtain current subnet license for tenant (if exists)
|
||||
if license, ok := tenantConfiguration[MinIOSubnetLicense]; ok {
|
||||
client := &cluster.HTTPClient{
|
||||
Client: restapi.GetConsoleHTTPClient(),
|
||||
}
|
||||
licenseInfo, _, _ := subscriptionValidate(client, string(license), "", "")
|
||||
// if licenseInfo is present attach it to the tenantInfo response
|
||||
if licenseInfo != nil {
|
||||
info.SubnetLicense = licenseInfo
|
||||
}
|
||||
}
|
||||
|
||||
@@ -558,13 +545,11 @@ func getTenantDetailsResponse(session *models.Principal, params operator_api.Ten
|
||||
|
||||
schema := "http"
|
||||
consoleSchema := "http"
|
||||
consolePort := ":9090"
|
||||
consolePort := fmt.Sprintf(":%d", miniov2.ConsolePort)
|
||||
if minTenant.TLS() {
|
||||
schema = "https"
|
||||
}
|
||||
if minTenant.AutoCert() || minTenant.ConsoleExternalCert() {
|
||||
consoleSchema = "https"
|
||||
consolePort = ":9443"
|
||||
consolePort = fmt.Sprintf(":%d", miniov2.ConsoleTLSPort)
|
||||
}
|
||||
var minioEndpoint string
|
||||
var consoleEndpoint string
|
||||
@@ -646,8 +631,6 @@ func parseTenantCertificates(ctx context.Context, clientSet K8sClientI, namespac
|
||||
func getTenantSecurity(ctx context.Context, clientSet K8sClientI, tenant *miniov2.Tenant) (response *models.TenantSecurityResponse, err error) {
|
||||
var minioExternalCertificates []*models.CertificateInfo
|
||||
var minioExternalCaCertificates []*models.CertificateInfo
|
||||
var consoleExternalCertificates []*models.CertificateInfo
|
||||
var consoleExternalCaCertificates []*models.CertificateInfo
|
||||
// Certificates used by MinIO server
|
||||
if minioExternalCertificates, err = parseTenantCertificates(ctx, clientSet, tenant.Namespace, tenant.Spec.ExternalCertSecret); err != nil {
|
||||
return nil, err
|
||||
@@ -656,25 +639,11 @@ func getTenantSecurity(ctx context.Context, clientSet K8sClientI, tenant *miniov
|
||||
if minioExternalCaCertificates, err = parseTenantCertificates(ctx, clientSet, tenant.Namespace, tenant.Spec.ExternalCaCertSecret); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if tenant.HasConsoleEnabled() {
|
||||
// Certificate used by Console server
|
||||
if tenant.Spec.Console.ExternalCertSecret != nil {
|
||||
if consoleExternalCertificates, err = parseTenantCertificates(ctx, clientSet, tenant.Namespace, []*miniov2.LocalCertificateReference{tenant.Spec.Console.ExternalCertSecret}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// CA Certificates used by Console server
|
||||
if consoleExternalCaCertificates, err = parseTenantCertificates(ctx, clientSet, tenant.Namespace, tenant.Spec.Console.ExternalCaCertSecret); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return &models.TenantSecurityResponse{
|
||||
AutoCert: tenant.AutoCert(),
|
||||
CustomCertificates: &models.TenantSecurityResponseCustomCertificates{
|
||||
Minio: minioExternalCertificates,
|
||||
MinioCAs: minioExternalCaCertificates,
|
||||
Console: consoleExternalCertificates,
|
||||
ConsoleCAs: consoleExternalCaCertificates,
|
||||
Minio: minioExternalCertificates,
|
||||
MinioCAs: minioExternalCaCertificates,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
@@ -746,8 +715,6 @@ func updateTenantSecurity(ctx context.Context, operatorClient OperatorClientI, c
|
||||
minInst.Spec.RequestAutoCert = ¶ms.Body.AutoCert
|
||||
var newMinIOExternalCertSecret []*miniov2.LocalCertificateReference
|
||||
var newMinIOExternalCaCertSecret []*miniov2.LocalCertificateReference
|
||||
var newConsoleExternalCertSecret *miniov2.LocalCertificateReference
|
||||
var newConsoleExternalCaCertSecret []*miniov2.LocalCertificateReference
|
||||
// Remove Certificate Secrets from MinIO (Tenant.Spec.ExternalCertSecret)
|
||||
for _, certificate := range minInst.Spec.ExternalCertSecret {
|
||||
skip := false
|
||||
@@ -776,33 +743,6 @@ func updateTenantSecurity(ctx context.Context, operatorClient OperatorClientI, c
|
||||
}
|
||||
newMinIOExternalCaCertSecret = append(newMinIOExternalCaCertSecret, certificate)
|
||||
}
|
||||
if minInst.HasConsoleEnabled() {
|
||||
// Remove Certificate Secrets from Console (Tenant.Spec.Console.ExternalCertSecret)
|
||||
if minInst.ConsoleExternalCert() {
|
||||
newConsoleExternalCertSecret = minInst.Spec.Console.ExternalCertSecret
|
||||
for _, certificateToBeDeleted := range params.Body.CustomCertificates.SecretsToBeDeleted {
|
||||
if newConsoleExternalCertSecret.Name == certificateToBeDeleted {
|
||||
newConsoleExternalCertSecret = nil
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// Remove Certificate Secrets from Console CAs (Tenant.Spec.Console.ExternalCaCertSecret)
|
||||
for _, certificate := range minInst.Spec.Console.ExternalCaCertSecret {
|
||||
skip := false
|
||||
for _, certificateToBeDeleted := range params.Body.CustomCertificates.SecretsToBeDeleted {
|
||||
if certificate.Name == certificateToBeDeleted {
|
||||
skip = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if skip {
|
||||
continue
|
||||
}
|
||||
newConsoleExternalCaCertSecret = append(newConsoleExternalCaCertSecret, certificate)
|
||||
}
|
||||
}
|
||||
|
||||
//Create new Certificate Secrets for MinIO
|
||||
secretName := fmt.Sprintf("%s-%s", minInst.Name, strings.ToLower(utils.RandomCharString(5)))
|
||||
externalCertSecretName := fmt.Sprintf("%s-external-certificates", secretName)
|
||||
@@ -811,7 +751,6 @@ func updateTenantSecurity(ctx context.Context, operatorClient OperatorClientI, c
|
||||
return err
|
||||
}
|
||||
newMinIOExternalCertSecret = append(newMinIOExternalCertSecret, externalCertSecrets...)
|
||||
|
||||
// Create new CAs Certificate Secrets for MinIO
|
||||
var caCertificates []tenantSecret
|
||||
for i, caCertificate := range params.Body.CustomCertificates.MinioCAs {
|
||||
@@ -833,46 +772,9 @@ func updateTenantSecurity(ctx context.Context, operatorClient OperatorClientI, c
|
||||
}
|
||||
newMinIOExternalCaCertSecret = append(newMinIOExternalCaCertSecret, certificateSecrets...)
|
||||
}
|
||||
|
||||
// Create new Certificate Secrets for Console
|
||||
consoleExternalCertSecretName := fmt.Sprintf("%s-console-external-certificates", secretName)
|
||||
consoleExternalCertSecrets, err := createOrReplaceExternalCertSecrets(ctx, client, minInst.Namespace, params.Body.CustomCertificates.Console, consoleExternalCertSecretName, minInst.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(consoleExternalCertSecrets) > 0 {
|
||||
newConsoleExternalCertSecret = consoleExternalCertSecrets[0]
|
||||
}
|
||||
|
||||
// Create new CAs Certificate Secrets for Console
|
||||
var consoleCaCertificates []tenantSecret
|
||||
for i, caCertificate := range params.Body.CustomCertificates.ConsoleCAs {
|
||||
certificateContent, err := base64.StdEncoding.DecodeString(caCertificate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
consoleCaCertificates = append(consoleCaCertificates, tenantSecret{
|
||||
Name: fmt.Sprintf("%s-console-ca-certificate-%d", secretName, i),
|
||||
Content: map[string][]byte{
|
||||
"public.crt": certificateContent,
|
||||
},
|
||||
})
|
||||
}
|
||||
if len(consoleCaCertificates) > 0 {
|
||||
certificateSecrets, err := createOrReplaceSecrets(ctx, client, minInst.Namespace, consoleCaCertificates, minInst.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newConsoleExternalCaCertSecret = append(newConsoleExternalCaCertSecret, certificateSecrets...)
|
||||
}
|
||||
|
||||
// Update External Certificates
|
||||
minInst.Spec.ExternalCertSecret = newMinIOExternalCertSecret
|
||||
minInst.Spec.ExternalCaCertSecret = newMinIOExternalCaCertSecret
|
||||
if minInst.HasConsoleEnabled() {
|
||||
minInst.Spec.Console.ExternalCertSecret = newConsoleExternalCertSecret
|
||||
minInst.Spec.Console.ExternalCaCertSecret = newConsoleExternalCaCertSecret
|
||||
}
|
||||
_, err = operatorClient.TenantUpdate(ctx, minInst, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -978,8 +880,6 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
tenantReq := params.Body
|
||||
minioImage := tenantReq.Image
|
||||
ctx := context.Background()
|
||||
consoleHasTLS := false
|
||||
|
||||
if minioImage == "" {
|
||||
minImg, err := cluster.GetMinioImage()
|
||||
// we can live without figuring out the latest version of MinIO, Operator will use a hardcoded value
|
||||
@@ -1015,9 +915,9 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
var instanceSecret corev1.Secret
|
||||
var users []*corev1.LocalObjectReference
|
||||
|
||||
var tenantConfigurationENV string
|
||||
tenantConfigurationENV := map[string]string{}
|
||||
|
||||
// Create the secret for the root credentials
|
||||
// Create the secret for the root credentials (deprecated)
|
||||
secretName := fmt.Sprintf("%s-secret", tenantName)
|
||||
instanceSecret = corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@@ -1033,8 +933,14 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
},
|
||||
}
|
||||
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_ROOT_USER=\"%s\"\n", accessKey)
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_ROOT_PASSWORD=\"%s\"\n", secretKey)
|
||||
// Enable/Disable console object browser for MinIO tenant (default is on)
|
||||
enabledConsole := "on"
|
||||
if tenantReq.EnableConsole != nil && !*tenantReq.EnableConsole {
|
||||
enabledConsole = "off"
|
||||
}
|
||||
tenantConfigurationENV["MINIO_BROWSER"] = enabledConsole
|
||||
tenantConfigurationENV["MINIO_ROOT_USER"] = accessKey
|
||||
tenantConfigurationENV["MINIO_ROOT_PASSWORD"] = secretKey
|
||||
|
||||
_, err = clientSet.CoreV1().Secrets(ns).Create(ctx, &instanceSecret, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
@@ -1060,7 +966,7 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
if tenantReq.ErasureCodingParity < 2 || tenantReq.ErasureCodingParity > 8 {
|
||||
return nil, prepareError(errorInvalidErasureCodingValue)
|
||||
}
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_STORAGE_CLASS_STANDARD=\"%s\"\n", fmt.Sprintf("EC:%d", tenantReq.ErasureCodingParity))
|
||||
tenantConfigurationENV["MINIO_STORAGE_CLASS_STANDARD"] = fmt.Sprintf("EC:%d", tenantReq.ErasureCodingParity)
|
||||
}
|
||||
|
||||
//Construct a MinIO Instance with everything we are getting from parameters
|
||||
@@ -1077,10 +983,11 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var tenantExternalIDPConfigured bool
|
||||
if tenantReq.Idp != nil {
|
||||
// Enable IDP (Active Directory) for MinIO
|
||||
if tenantReq.Idp.ActiveDirectory != nil {
|
||||
tenantExternalIDPConfigured = true
|
||||
serverAddress := *tenantReq.Idp.ActiveDirectory.URL
|
||||
userNameFormat := tenantReq.Idp.ActiveDirectory.UsernameFormat
|
||||
userNameSearchFilter := tenantReq.Idp.ActiveDirectory.UsernameSearchFilter
|
||||
@@ -1096,33 +1003,33 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
serverStartTLS := tenantReq.Idp.ActiveDirectory.ServerStartTLS
|
||||
|
||||
// LDAP Server
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_LDAP_SERVER_ADDR=\"%s\"\n", serverAddress)
|
||||
tenantConfigurationENV["MINIO_IDENTITY_LDAP_SERVER_ADDR"] = serverAddress
|
||||
if tlsSkipVerify {
|
||||
tenantConfigurationENV += "export MINIO_IDENTITY_LDAP_TLS_SKIP_VERIFY=on\n"
|
||||
tenantConfigurationENV["MINIO_IDENTITY_LDAP_TLS_SKIP_VERIFY"] = "on"
|
||||
}
|
||||
if serverInsecure {
|
||||
tenantConfigurationENV += "export MINIO_IDENTITY_LDAP_SERVER_INSECURE=on\n"
|
||||
tenantConfigurationENV["MINIO_IDENTITY_LDAP_SERVER_INSECURE"] = "on"
|
||||
}
|
||||
if serverStartTLS {
|
||||
tenantConfigurationENV += "export MINIO_IDENTITY_LDAP_SERVER_STARTTLS=on\n"
|
||||
tenantConfigurationENV["MINIO_IDENTITY_LDAP_SERVER_STARTTLS"] = "on"
|
||||
}
|
||||
|
||||
// LDAP Username
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_LDAP_USERNAME_FORMAT=\"%s\"\n", userNameFormat)
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_LDAP_USERNAME_SEARCH_FILTER=\"%s\"\n", userNameSearchFilter)
|
||||
tenantConfigurationENV["MINIO_IDENTITY_LDAP_USERNAME_FORMAT"] = userNameFormat
|
||||
tenantConfigurationENV["MINIO_IDENTITY_LDAP_USERNAME_SEARCH_FILTER"] = userNameSearchFilter
|
||||
|
||||
// LDAP Lookup
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_LDAP_LOOKUP_BIND_DN=\"%s\"\n", lookupBindDN)
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_LDAP_LOOKUP_BIND_PASSWORD=\"%s\"\n", lookupBindPassword)
|
||||
tenantConfigurationENV["MINIO_IDENTITY_LDAP_LOOKUP_BIND_DN"] = lookupBindDN
|
||||
tenantConfigurationENV["MINIO_IDENTITY_LDAP_LOOKUP_BIND_PASSWORD"] = lookupBindPassword
|
||||
|
||||
// LDAP User DN
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_LDAP_USER_DN_SEARCH_BASE_DN=\"%s\"\n", userDNSearchBaseDN)
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_LDAP_USER_DN_SEARCH_FILTER=\"%s\"\n", userDNSearchFilter)
|
||||
tenantConfigurationENV["MINIO_IDENTITY_LDAP_USER_DN_SEARCH_BASE_DN"] = userDNSearchBaseDN
|
||||
tenantConfigurationENV["MINIO_IDENTITY_LDAP_USER_DN_SEARCH_FILTER"] = userDNSearchFilter
|
||||
|
||||
// LDAP Group
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_LDAP_GROUP_NAME_ATTRIBUTE=\"%s\"\n", groupNameAttribute)
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_LDAP_GROUP_SEARCH_BASE_DN=\"%s\"\n", groupSearchBaseDN)
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_LDAP_GROUP_SEARCH_FILTER=\"%s\"\n", groupSearchFilter)
|
||||
tenantConfigurationENV["MINIO_IDENTITY_LDAP_GROUP_NAME_ATTRIBUTE"] = groupNameAttribute
|
||||
tenantConfigurationENV["MINIO_IDENTITY_LDAP_GROUP_SEARCH_BASE_DN"] = groupSearchBaseDN
|
||||
tenantConfigurationENV["MINIO_IDENTITY_LDAP_GROUP_SEARCH_FILTER"] = groupSearchFilter
|
||||
|
||||
// Attach the list of LDAP user DNs that will be administrator for the Tenant
|
||||
for i, userDN := range tenantReq.Idp.ActiveDirectory.UserDNS {
|
||||
@@ -1149,20 +1056,23 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
minInst.Spec.Users = users
|
||||
|
||||
} else if tenantReq.Idp.Oidc != nil {
|
||||
tenantExternalIDPConfigured = true
|
||||
// Enable IDP (OIDC) for MinIO
|
||||
url := *tenantReq.Idp.Oidc.ConfigurationURL
|
||||
configurationURL := *tenantReq.Idp.Oidc.ConfigurationURL
|
||||
clientID := *tenantReq.Idp.Oidc.ClientID
|
||||
secretID := *tenantReq.Idp.Oidc.SecretID
|
||||
claimName := *tenantReq.Idp.Oidc.ClaimName
|
||||
scopes := tenantReq.Idp.Oidc.Scopes
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_OPENID_CONFIG_URL=\"%s\"\n", url)
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_OPENID_CLIENT_ID=\"%s\"\n", clientID)
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_OPENID_CLIENT_SECRET=\"%s\"\n", secretID)
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_OPENID_CLAIM_NAME=\"%s\"\n", claimName)
|
||||
callbackURL := tenantReq.Idp.Oidc.CallbackURL
|
||||
tenantConfigurationENV["MINIO_IDENTITY_OPENID_CONFIG_URL"] = configurationURL
|
||||
tenantConfigurationENV["MINIO_IDENTITY_OPENID_CLIENT_ID"] = clientID
|
||||
tenantConfigurationENV["MINIO_IDENTITY_OPENID_CLIENT_SECRET"] = secretID
|
||||
tenantConfigurationENV["MINIO_IDENTITY_OPENID_CLAIM_NAME"] = claimName
|
||||
tenantConfigurationENV["MINIO_IDENTITY_OPENID_REDIRECT_URI"] = callbackURL
|
||||
if scopes == "" {
|
||||
scopes = "openid,profile,email"
|
||||
}
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_OPENID_SCOPES=\"%s\"\n", scopes)
|
||||
tenantConfigurationENV["MINIO_IDENTITY_OPENID_SCOPES"] = scopes
|
||||
} else if len(tenantReq.Idp.Keys) > 0 {
|
||||
// Create the secret any built-in user passed if no external IDP was configured
|
||||
for i := 0; i < len(tenantReq.Idp.Keys); i++ {
|
||||
@@ -1200,7 +1110,6 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
if *tenantReq.EnableTLS {
|
||||
// requestAutoCert is enabled, MinIO will be deployed with TLS enabled and encryption can be enabled
|
||||
isEncryptionEnabled = true
|
||||
consoleHasTLS = true
|
||||
}
|
||||
}
|
||||
// External TLS certificates for MinIO
|
||||
@@ -1238,6 +1147,14 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
minInst.Spec.KES.Labels = tenantReq.Encryption.Labels
|
||||
minInst.Spec.KES.Annotations = tenantReq.Encryption.Annotations
|
||||
minInst.Spec.KES.NodeSelector = tenantReq.Encryption.NodeSelector
|
||||
|
||||
if tenantReq.Encryption.SecurityContext != nil {
|
||||
sc, err := parseSecurityContext(tenantReq.Encryption.SecurityContext)
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
minInst.Spec.KES.SecurityContext = sc
|
||||
}
|
||||
}
|
||||
// External TLS CA certificates for MinIO
|
||||
if tenantReq.TLS != nil && len(tenantReq.TLS.CaCertificates) > 0 {
|
||||
@@ -1262,130 +1179,12 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
minInst.Spec.ExternalCaCertSecret = certificateSecrets
|
||||
}
|
||||
}
|
||||
// optionals are set below
|
||||
var tenantUserAccessKey string
|
||||
var tenantUserSecretKey string
|
||||
keyElementEmpty := len(tenantReq.Idp.Keys) == 1 && (*tenantReq.Idp.Keys[0].AccessKey == "" && *tenantReq.Idp.Keys[0].SecretKey == "")
|
||||
|
||||
enableConsole := true
|
||||
if tenantReq.EnableConsole != nil && *tenantReq.EnableConsole {
|
||||
enableConsole = *tenantReq.EnableConsole
|
||||
}
|
||||
|
||||
if enableConsole {
|
||||
consoleSelector := fmt.Sprintf("%s-console", tenantName)
|
||||
consoleSecretName := fmt.Sprintf("%s-secret", consoleSelector)
|
||||
consoleSecretData := map[string][]byte{
|
||||
"CONSOLE_PBKDF_PASSPHRASE": []byte(restapi.RandomCharString(16)),
|
||||
"CONSOLE_PBKDF_SALT": []byte(restapi.RandomCharString(8)),
|
||||
}
|
||||
// If Subnet License is present in k8s secrets, copy that to the CONSOLE_SUBNET_LICENSE env variable
|
||||
// of the console tenant
|
||||
license, _ := getSubscriptionLicense(ctx, &k8sClient, cluster.Namespace, OperatorSubnetLicenseSecretName)
|
||||
if license != "" {
|
||||
consoleSecretData[restapi.ConsoleSubnetLicense] = []byte(license)
|
||||
}
|
||||
imm := true
|
||||
consoleSecret := corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: consoleSecretName,
|
||||
Labels: map[string]string{
|
||||
miniov2.TenantLabel: tenantName,
|
||||
},
|
||||
},
|
||||
Immutable: &imm,
|
||||
Data: consoleSecretData,
|
||||
}
|
||||
|
||||
minInst.Spec.Console = &miniov2.ConsoleConfiguration{
|
||||
Replicas: 1,
|
||||
Image: getConsoleImage(),
|
||||
ConsoleSecret: &corev1.LocalObjectReference{Name: consoleSecretName},
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Requests: map[corev1.ResourceName]resource.Quantity{
|
||||
"memory": resource.MustParse("64Mi"),
|
||||
},
|
||||
},
|
||||
}
|
||||
if tenantReq.TLS != nil && tenantReq.TLS.Console != nil {
|
||||
consoleHasTLS = true
|
||||
// Certificates used by the console instance
|
||||
externalCertSecretName := fmt.Sprintf("%s-console-external-certificates", secretName)
|
||||
certificates := []*models.KeyPairConfiguration{tenantReq.TLS.Console}
|
||||
externalCertSecret, err := createOrReplaceExternalCertSecrets(ctx, &k8sClient, ns, certificates, externalCertSecretName, tenantName)
|
||||
if err != nil {
|
||||
return nil, prepareError(restapi.ErrorGeneric)
|
||||
}
|
||||
if len(externalCertSecret) > 0 {
|
||||
minInst.Spec.Console.ExternalCertSecret = externalCertSecret[0]
|
||||
}
|
||||
}
|
||||
|
||||
// If IDP is not already enabled via LDAP (Active Directory) and OIDC configuration is present then
|
||||
// enable oidc for console
|
||||
if tenantReq.Idp != nil {
|
||||
if tenantReq.Idp.ActiveDirectory != nil {
|
||||
consoleSecret.Data[ldap.ConsoleLDAPEnabled] = []byte("on")
|
||||
} else if tenantReq.Idp.Oidc != nil {
|
||||
url := *tenantReq.Idp.Oidc.URL
|
||||
clientID := *tenantReq.Idp.Oidc.ClientID
|
||||
secretID := *tenantReq.Idp.Oidc.SecretID
|
||||
callbackURL := tenantReq.Idp.Oidc.CallbackURL
|
||||
if url != "" && clientID != "" && secretID != "" {
|
||||
consoleSecret.Data[oauth2.ConsoleIdpURL] = []byte(url)
|
||||
consoleSecret.Data[oauth2.ConsoleIdpClientID] = []byte(clientID)
|
||||
consoleSecret.Data[oauth2.ConsoleIdpSecret] = []byte(secretID)
|
||||
consoleScheme := "http"
|
||||
consolePort := miniov2.ConsolePort
|
||||
// If Console will be deployed with TLS enabled (using AutoCert or External certificates)
|
||||
if consoleHasTLS {
|
||||
consoleScheme = "https"
|
||||
consolePort = miniov2.ConsoleTLSPort
|
||||
}
|
||||
// default callback url is https://localhost:9443/oauth_callback
|
||||
consoleSecret.Data[oauth2.ConsoleIdpCallbackURL] = []byte(fmt.Sprintf("%s://localhost:%d/oauth_callback", consoleScheme, consolePort))
|
||||
if callbackURL != "" {
|
||||
consoleSecret.Data[oauth2.ConsoleIdpCallbackURL] = []byte(callbackURL)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_, err = clientSet.CoreV1().Secrets(ns).Create(ctx, &consoleSecret, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return nil, prepareError(restapi.ErrorGeneric)
|
||||
}
|
||||
|
||||
// Set Labels, Annotations and Node Selector for Console
|
||||
if tenantReq.Console != nil {
|
||||
minInst.Spec.Console.Annotations = tenantReq.Console.Annotations
|
||||
minInst.Spec.Console.Labels = tenantReq.Console.Labels
|
||||
minInst.Spec.Console.NodeSelector = tenantReq.Console.NodeSelector
|
||||
}
|
||||
|
||||
// External TLS CA certificates for Console
|
||||
if tenantReq.TLS != nil && len(tenantReq.TLS.ConsoleCaCertificates) > 0 {
|
||||
var caCertificates []tenantSecret
|
||||
for i, caCertificate := range tenantReq.TLS.ConsoleCaCertificates {
|
||||
certificateContent, err := base64.StdEncoding.DecodeString(caCertificate)
|
||||
if err != nil {
|
||||
return nil, prepareError(restapi.ErrorGeneric, nil, err)
|
||||
}
|
||||
caCertificates = append(caCertificates, tenantSecret{
|
||||
Name: fmt.Sprintf("console-ca-certificate-%d", i),
|
||||
Content: map[string][]byte{
|
||||
"public.crt": certificateContent,
|
||||
},
|
||||
})
|
||||
}
|
||||
if len(caCertificates) > 0 {
|
||||
certificateSecrets, err := createOrReplaceSecrets(ctx, &k8sClient, ns, caCertificates, tenantName)
|
||||
if err != nil {
|
||||
return nil, prepareError(restapi.ErrorGeneric, nil, err)
|
||||
}
|
||||
minInst.Spec.Console.ExternalCaCertSecret = certificateSecrets
|
||||
}
|
||||
}
|
||||
// If Subnet License is present in k8s secrets, copy that to the MINIO_SUBNET_LICENSE env variable
|
||||
// of the console tenant
|
||||
license, _ := getSubscriptionLicense(ctx, &k8sClient, cluster.Namespace, OperatorSubnetLicenseSecretName)
|
||||
if license != "" {
|
||||
tenantConfigurationENV[MinIOSubnetLicense] = license
|
||||
}
|
||||
|
||||
// add annotations
|
||||
@@ -1432,16 +1231,14 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
minInst.Annotations[prometheusScrape] = "true"
|
||||
}
|
||||
|
||||
// set console image if provided
|
||||
if tenantReq.ConsoleImage != "" {
|
||||
minInst.Spec.Console.Image = tenantReq.ConsoleImage
|
||||
}
|
||||
|
||||
//Default class name for Log search
|
||||
diskSpaceFromAPI := int64(5) * humanize.GiByte // Default is 5Gi
|
||||
logSearchStorageClass := "" // Default is ""
|
||||
logSearchImage := ""
|
||||
logSearchPgImage := ""
|
||||
logSearchPgInitImage := ""
|
||||
var logSearchSecurityContext *corev1.PodSecurityContext
|
||||
var logSearchPgSecurityContext *corev1.PodSecurityContext
|
||||
|
||||
if tenantReq.LogSearchConfiguration != nil {
|
||||
if tenantReq.LogSearchConfiguration.StorageSize != nil {
|
||||
@@ -1450,18 +1247,34 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
if tenantReq.LogSearchConfiguration.StorageClass != "" {
|
||||
logSearchStorageClass = tenantReq.LogSearchConfiguration.StorageClass
|
||||
}
|
||||
|
||||
if tenantReq.LogSearchConfiguration.StorageClass == "" && len(tenantReq.Pools) > 0 {
|
||||
logSearchStorageClass = tenantReq.Pools[0].VolumeConfiguration.StorageClassName
|
||||
}
|
||||
|
||||
if tenantReq.LogSearchConfiguration.Image != "" {
|
||||
logSearchImage = tenantReq.LogSearchConfiguration.Image
|
||||
}
|
||||
if tenantReq.LogSearchConfiguration.PostgresImage != "" {
|
||||
logSearchPgImage = tenantReq.LogSearchConfiguration.PostgresImage
|
||||
}
|
||||
|
||||
if tenantReq.LogSearchConfiguration.PostgresInitImage != "" {
|
||||
logSearchPgInitImage = tenantReq.LogSearchConfiguration.PostgresInitImage
|
||||
}
|
||||
// if security context for logSearch is present, configure it.
|
||||
if tenantReq.LogSearchConfiguration.SecurityContext != nil {
|
||||
sc, err := parseSecurityContext(tenantReq.LogSearchConfiguration.SecurityContext)
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
logSearchSecurityContext = sc
|
||||
}
|
||||
// if security context for logSearch is present, configure it.
|
||||
if tenantReq.LogSearchConfiguration.PostgresSecurityContext != nil {
|
||||
sc, err := parseSecurityContext(tenantReq.LogSearchConfiguration.PostgresSecurityContext)
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
logSearchPgSecurityContext = sc
|
||||
}
|
||||
}
|
||||
|
||||
logSearchDiskSpace := resource.NewQuantity(diskSpaceFromAPI, resource.DecimalExponent)
|
||||
@@ -1493,16 +1306,28 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
},
|
||||
},
|
||||
}
|
||||
// set log search images if any
|
||||
if logSearchImage != "" {
|
||||
minInst.Spec.Log.Image = logSearchImage
|
||||
}
|
||||
if logSearchPgImage != "" {
|
||||
minInst.Spec.Log.Db.Image = logSearchPgImage
|
||||
}
|
||||
if logSearchPgInitImage != "" {
|
||||
minInst.Spec.Log.Db.InitImage = logSearchPgInitImage
|
||||
}
|
||||
if logSearchSecurityContext != nil {
|
||||
minInst.Spec.Log.SecurityContext = logSearchSecurityContext
|
||||
}
|
||||
if logSearchPgSecurityContext != nil {
|
||||
minInst.Spec.Log.Db.SecurityContext = logSearchPgSecurityContext
|
||||
}
|
||||
|
||||
prometheusDiskSpace := 5 // Default is 5 by API
|
||||
prometheusStorageClass := "" // Default is ""
|
||||
prometheusImage := "" // Default is ""
|
||||
prometheusDiskSpace := 5 // Default is 5 by API
|
||||
prometheusStorageClass := "" // Default is ""
|
||||
prometheusImage := "" // Default is ""
|
||||
prometheusSidecardImage := "" // Default is ""
|
||||
prometheusInitImage := "" // Default is ""
|
||||
|
||||
if tenantReq.PrometheusConfiguration != nil {
|
||||
if tenantReq.PrometheusConfiguration.StorageSize != nil {
|
||||
@@ -1520,6 +1345,12 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
if tenantReq.PrometheusConfiguration.Image != "" {
|
||||
prometheusImage = tenantReq.PrometheusConfiguration.Image
|
||||
}
|
||||
if tenantReq.PrometheusConfiguration.SidecarImage != "" {
|
||||
prometheusSidecardImage = tenantReq.PrometheusConfiguration.SidecarImage
|
||||
}
|
||||
if tenantReq.PrometheusConfiguration.InitImage != "" {
|
||||
prometheusInitImage = tenantReq.PrometheusConfiguration.InitImage
|
||||
}
|
||||
}
|
||||
|
||||
minInst.Spec.Prometheus = &miniov2.PrometheusConfig{
|
||||
@@ -1529,6 +1360,20 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
if prometheusImage != "" {
|
||||
minInst.Spec.Prometheus.Image = prometheusImage
|
||||
}
|
||||
if prometheusSidecardImage != "" {
|
||||
minInst.Spec.Prometheus.SideCarImage = prometheusSidecardImage
|
||||
}
|
||||
if prometheusInitImage != "" {
|
||||
minInst.Spec.Prometheus.InitImage = prometheusInitImage
|
||||
}
|
||||
// if security context for prometheus is present, configure it.
|
||||
if tenantReq.PrometheusConfiguration != nil && tenantReq.PrometheusConfiguration.SecurityContext != nil {
|
||||
sc, err := parseSecurityContext(tenantReq.PrometheusConfiguration.SecurityContext)
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
minInst.Spec.Prometheus.SecurityContext = sc
|
||||
}
|
||||
|
||||
// expose services
|
||||
minInst.Spec.ExposeServices = &miniov2.ExposeServices{
|
||||
@@ -1542,7 +1387,7 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
{
|
||||
Name: tenantConfigurationName,
|
||||
Content: map[string][]byte{
|
||||
"config.env": []byte(tenantConfigurationENV),
|
||||
"config.env": []byte(GenerateTenantConfigurationFile(tenantConfigurationENV)),
|
||||
},
|
||||
},
|
||||
}, tenantName)
|
||||
@@ -1569,20 +1414,16 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
}
|
||||
response = &models.CreateTenantResponse{}
|
||||
// Attach Console Credentials
|
||||
if enableConsole {
|
||||
var itemsToReturn []*models.TenantResponseItem
|
||||
|
||||
if len(tenantReq.Idp.Keys) == 0 || keyElementEmpty {
|
||||
itemsToReturn = append(itemsToReturn, &models.TenantResponseItem{AccessKey: tenantUserAccessKey, SecretKey: tenantUserSecretKey})
|
||||
} else { // IDP Keys
|
||||
for _, item := range tenantReq.Idp.Keys {
|
||||
itemsToReturn = append(itemsToReturn, &models.TenantResponseItem{AccessKey: *item.AccessKey, SecretKey: *item.SecretKey})
|
||||
}
|
||||
response = &models.CreateTenantResponse{
|
||||
ExternalIDP: tenantExternalIDPConfigured,
|
||||
}
|
||||
if tenantReq.Idp != nil && !tenantExternalIDPConfigured {
|
||||
for _, credential := range tenantReq.Idp.Keys {
|
||||
response.Console = append(response.Console, &models.TenantResponseItem{
|
||||
AccessKey: *credential.AccessKey,
|
||||
SecretKey: *credential.SecretKey,
|
||||
})
|
||||
}
|
||||
|
||||
response.Console = itemsToReturn
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
@@ -1666,11 +1507,6 @@ func updateTenantAction(ctx context.Context, operatorClient OperatorClientI, cli
|
||||
}
|
||||
}
|
||||
|
||||
// update the console image
|
||||
if strings.TrimSpace(params.Body.ConsoleImage) != "" && minInst.Spec.Console != nil {
|
||||
minInst.Spec.Console.Image = params.Body.ConsoleImage
|
||||
}
|
||||
|
||||
// if image to update is empty we'll use the latest image by default
|
||||
if strings.TrimSpace(imageToUpdate) != "" {
|
||||
minInst.Spec.Image = imageToUpdate
|
||||
@@ -1811,8 +1647,8 @@ func getTenantAddPoolResponse(session *models.Principal, params operator_api.Ten
|
||||
|
||||
// getTenantUsageResponse returns the usage of a tenant
|
||||
func getTenantUsageResponse(session *models.Principal, params operator_api.GetTenantUsageParams) (*models.TenantUsage, *models.Error) {
|
||||
// 5 seconds timeout
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
// 30 seconds timeout
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
opClientClientSet, err := cluster.OperatorClient(session.STSSessionToken)
|
||||
@@ -2106,6 +1942,14 @@ func parseTenantPoolRequest(poolParams *models.Pool) (*miniov2.Pool, error) {
|
||||
Affinity: affinity,
|
||||
Tolerations: tolerations,
|
||||
}
|
||||
// if security context for Tenant is present, configure it.
|
||||
if poolParams.SecurityContext != nil {
|
||||
sc, err := parseSecurityContext(poolParams.SecurityContext)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pool.SecurityContext = sc
|
||||
}
|
||||
return pool, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,31 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// parseSecurityContext validate and return securityContext for pods
|
||||
func parseSecurityContext(sc *models.SecurityContext) (*corev1.PodSecurityContext, error) {
|
||||
if sc == nil {
|
||||
return nil, errors.New("invalid security context")
|
||||
}
|
||||
runAsUser, err := strconv.ParseInt(*sc.RunAsUser, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
RunAsGroup, err := strconv.ParseInt(*sc.RunAsGroup, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
FsGroup, err := strconv.ParseInt(*sc.FsGroup, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &corev1.PodSecurityContext{
|
||||
RunAsUser: &runAsUser,
|
||||
RunAsGroup: &RunAsGroup,
|
||||
RunAsNonRoot: sc.RunAsNonRoot,
|
||||
FSGroup: &FsGroup,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// tenantUpdateCertificates receives the keyPair certificates (public and private keys) for Minio and Console and will try
|
||||
// to replace the existing kubernetes secrets with the new values, then will restart the affected pods so the new volumes can be mounted
|
||||
func tenantUpdateCertificates(ctx context.Context, operatorClient OperatorClientI, clientSet K8sClientI, namespace string, params operator_api.TenantUpdateCertificateParams) error {
|
||||
@@ -63,22 +88,6 @@ func tenantUpdateCertificates(ctx context.Context, operatorClient OperatorClient
|
||||
return err
|
||||
}
|
||||
}
|
||||
// check if Console is deployed with external certs and user provided new Console keypair
|
||||
if tenant.ConsoleExternalCert() && tenant.HasConsoleEnabled() && body.Console != nil {
|
||||
consoleCertSecretName := fmt.Sprintf("%s-console-external-certificates", secretName)
|
||||
// update certificates
|
||||
certificates := []*models.KeyPairConfiguration{body.Console}
|
||||
if _, err := createOrReplaceExternalCertSecrets(ctx, clientSet, namespace, certificates, consoleCertSecretName, tenantName); err != nil {
|
||||
return err
|
||||
}
|
||||
// restart Console pods
|
||||
err := clientSet.deletePodCollection(ctx, namespace, metav1.DeleteOptions{}, metav1.ListOptions{
|
||||
LabelSelector: fmt.Sprintf("%s=%s", miniov2.ConsoleTenantLabel, fmt.Sprintf("%s-console", tenantName)),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -251,7 +260,6 @@ func createOrReplaceSecrets(ctx context.Context, clientSet K8sClientI, ns string
|
||||
// log the error if any and continue
|
||||
LogError("deleting secret name %s failed: %v, continuing..", secret.Name, err)
|
||||
}
|
||||
imm := true
|
||||
k8sSecret := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: secret.Name,
|
||||
@@ -259,9 +267,8 @@ func createOrReplaceSecrets(ctx context.Context, clientSet K8sClientI, ns string
|
||||
miniov2.TenantLabel: tenantName,
|
||||
},
|
||||
},
|
||||
Type: corev1.SecretTypeOpaque,
|
||||
Immutable: &imm,
|
||||
Data: secret.Content,
|
||||
Type: corev1.SecretTypeOpaque,
|
||||
Data: secret.Content,
|
||||
}
|
||||
_, err = clientSet.createSecret(ctx, ns, k8sSecret, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
@@ -516,6 +523,21 @@ func createOrReplaceKesConfigurationSecrets(ctx context.Context, clientSet K8sCl
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if encryptionCfg.Azure != nil {
|
||||
// Initialize Azure
|
||||
kesConfig.Keys.Azure = &kes.Azure{
|
||||
KeyVault: &kes.AzureKeyVault{},
|
||||
}
|
||||
if encryptionCfg.Azure.Keyvault != nil {
|
||||
kesConfig.Keys.Azure.KeyVault.Endpoint = *encryptionCfg.Azure.Keyvault.Endpoint
|
||||
if encryptionCfg.Azure.Keyvault.Credentials != nil {
|
||||
kesConfig.Keys.Azure.KeyVault.Credentials = &kes.AzureCredentials{
|
||||
TenantID: *encryptionCfg.Azure.Keyvault.Credentials.TenantID,
|
||||
ClientID: *encryptionCfg.Azure.Keyvault.Credentials.ClientID,
|
||||
ClientSecret: *encryptionCfg.Azure.Keyvault.Credentials.ClientSecret,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
imm := true
|
||||
// if mTLSCertificates contains elements we create the kubernetes secret
|
||||
|
||||
@@ -33,6 +33,7 @@ import (
|
||||
var DeletePodCollectionMock func(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error
|
||||
var DeleteSecretMock func(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error
|
||||
var CreateSecretMock func(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.CreateOptions) (*v1.Secret, error)
|
||||
var UpdateSecretMock func(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.UpdateOptions) (*v1.Secret, error)
|
||||
|
||||
func (c k8sClientMock) deletePodCollection(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
|
||||
return DeletePodCollectionMock(ctx, namespace, opts, listOpts)
|
||||
@@ -46,6 +47,10 @@ func (c k8sClientMock) createSecret(ctx context.Context, namespace string, secre
|
||||
return CreateSecretMock(ctx, namespace, secret, opts)
|
||||
}
|
||||
|
||||
func (c k8sClientMock) updateSecret(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.UpdateOptions) (*v1.Secret, error) {
|
||||
return UpdateSecretMock(ctx, namespace, secret, opts)
|
||||
}
|
||||
|
||||
func Test_tenantUpdateCertificates(t *testing.T) {
|
||||
k8sClient := k8sClientMock{}
|
||||
opClient := opClientMock{}
|
||||
@@ -228,70 +233,6 @@ func Test_tenantUpdateCertificates(t *testing.T) {
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "error replacing external certs for console because of missing keypair",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
opClient: opClient,
|
||||
clientSet: k8sClient,
|
||||
namespace: "",
|
||||
params: operator_api.TenantUpdateCertificateParams{
|
||||
Body: &models.TLSConfiguration{
|
||||
Console: &models.KeyPairConfiguration{},
|
||||
},
|
||||
},
|
||||
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*miniov2.Tenant, error) {
|
||||
return &miniov2.Tenant{
|
||||
Spec: miniov2.TenantSpec{
|
||||
Console: &miniov2.ConsoleConfiguration{
|
||||
ExternalCertSecret: &miniov2.LocalCertificateReference{
|
||||
Name: "secret",
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "certificates replaced but error during deleting existing tenant pods",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
opClient: opClient,
|
||||
clientSet: k8sClient,
|
||||
namespace: "",
|
||||
params: operator_api.TenantUpdateCertificateParams{
|
||||
Body: &models.TLSConfiguration{
|
||||
Console: &models.KeyPairConfiguration{
|
||||
Crt: &crt,
|
||||
Key: &key,
|
||||
},
|
||||
},
|
||||
},
|
||||
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*miniov2.Tenant, error) {
|
||||
return &miniov2.Tenant{
|
||||
Spec: miniov2.TenantSpec{
|
||||
Console: &miniov2.ConsoleConfiguration{
|
||||
ExternalCertSecret: &miniov2.LocalCertificateReference{
|
||||
Name: "secret",
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
mockDeleteSecret: func(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error {
|
||||
return nil
|
||||
},
|
||||
mockCreateSecret: func(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.CreateOptions) (*v1.Secret, error) {
|
||||
return &v1.Secret{}, nil
|
||||
},
|
||||
mockDeletePodCollection: func(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
|
||||
return errors.New("error deleting console pods")
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
opClientTenantGetMock = tt.args.mockTenantGet
|
||||
|
||||
@@ -468,9 +468,6 @@ func Test_TenantInfo(t *testing.T) {
|
||||
Spec: miniov2.TenantSpec{
|
||||
Pools: []miniov2.Pool{},
|
||||
Image: "minio/minio:RELEASE.2020-06-14T18-32-17Z",
|
||||
Console: &miniov2.ConsoleConfiguration{
|
||||
Image: "minio/console:master",
|
||||
},
|
||||
},
|
||||
Status: miniov2.TenantStatus{
|
||||
CurrentState: "ready",
|
||||
@@ -484,7 +481,6 @@ func Test_TenantInfo(t *testing.T) {
|
||||
Namespace: "minio-ns",
|
||||
Image: "minio/minio:RELEASE.2020-06-14T18-32-17Z",
|
||||
EnablePrometheus: false,
|
||||
ConsoleImage: "minio/console:master",
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -505,8 +501,7 @@ func Test_deleteTenantAction(t *testing.T) {
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
operatorClient OperatorClientI
|
||||
nameSpace string
|
||||
tenantName string
|
||||
tenant *miniov2.Tenant
|
||||
deletePvcs bool
|
||||
objs []runtime.Object
|
||||
mockTenantDelete func(ctx context.Context, namespace string, tenantName string, options metav1.DeleteOptions) error
|
||||
@@ -521,9 +516,13 @@ func Test_deleteTenantAction(t *testing.T) {
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
operatorClient: opClient,
|
||||
nameSpace: "default",
|
||||
tenantName: "minio-tenant",
|
||||
deletePvcs: false,
|
||||
tenant: &miniov2.Tenant{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "default",
|
||||
Namespace: "minio-tenant",
|
||||
},
|
||||
},
|
||||
deletePvcs: false,
|
||||
mockTenantDelete: func(ctx context.Context, namespace string, tenantName string, options metav1.DeleteOptions) error {
|
||||
return nil
|
||||
},
|
||||
@@ -535,9 +534,13 @@ func Test_deleteTenantAction(t *testing.T) {
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
operatorClient: opClient,
|
||||
nameSpace: "default",
|
||||
tenantName: "minio-tenant",
|
||||
deletePvcs: false,
|
||||
tenant: &miniov2.Tenant{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "default",
|
||||
Namespace: "minio-tenant",
|
||||
},
|
||||
},
|
||||
deletePvcs: false,
|
||||
mockTenantDelete: func(ctx context.Context, namespace string, tenantName string, options metav1.DeleteOptions) error {
|
||||
return errors.New("something happened")
|
||||
},
|
||||
@@ -550,9 +553,13 @@ func Test_deleteTenantAction(t *testing.T) {
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
operatorClient: opClient,
|
||||
nameSpace: "minio-tenant",
|
||||
tenantName: "tenant1",
|
||||
deletePvcs: true,
|
||||
tenant: &miniov2.Tenant{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "tenant1",
|
||||
Namespace: "minio-tenant",
|
||||
},
|
||||
},
|
||||
deletePvcs: true,
|
||||
objs: []runtime.Object{
|
||||
&corev1.PersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@@ -577,9 +584,13 @@ func Test_deleteTenantAction(t *testing.T) {
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
operatorClient: opClient,
|
||||
nameSpace: "minio-tenant",
|
||||
tenantName: "tenant1",
|
||||
deletePvcs: false,
|
||||
tenant: &miniov2.Tenant{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "tenant1",
|
||||
Namespace: "minio-tenant",
|
||||
},
|
||||
},
|
||||
deletePvcs: false,
|
||||
objs: []runtime.Object{
|
||||
&corev1.PersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@@ -604,9 +615,13 @@ func Test_deleteTenantAction(t *testing.T) {
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
operatorClient: opClient,
|
||||
nameSpace: "minio-tenant",
|
||||
tenantName: "tenant1",
|
||||
deletePvcs: true,
|
||||
tenant: &miniov2.Tenant{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "tenant1",
|
||||
Namespace: "minio-tenant",
|
||||
},
|
||||
},
|
||||
deletePvcs: true,
|
||||
objs: []runtime.Object{
|
||||
&corev1.PersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@@ -631,9 +646,13 @@ func Test_deleteTenantAction(t *testing.T) {
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
operatorClient: opClient,
|
||||
nameSpace: "minio-tenant",
|
||||
tenantName: "tenant1",
|
||||
deletePvcs: true,
|
||||
tenant: &miniov2.Tenant{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "tenant1",
|
||||
Namespace: "minio-tenant",
|
||||
},
|
||||
},
|
||||
deletePvcs: true,
|
||||
objs: []runtime.Object{
|
||||
&corev1.PersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@@ -659,9 +678,13 @@ func Test_deleteTenantAction(t *testing.T) {
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
operatorClient: opClient,
|
||||
nameSpace: "minio-tenant",
|
||||
tenantName: "tenant1",
|
||||
deletePvcs: false,
|
||||
tenant: &miniov2.Tenant{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "tenant1",
|
||||
Namespace: "minio-tenant",
|
||||
},
|
||||
},
|
||||
deletePvcs: false,
|
||||
objs: []runtime.Object{
|
||||
&corev1.PersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@@ -685,7 +708,7 @@ func Test_deleteTenantAction(t *testing.T) {
|
||||
opClientTenantDeleteMock = tt.args.mockTenantDelete
|
||||
kubeClient := fake.NewSimpleClientset(tt.args.objs...)
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if err := deleteTenantAction(tt.args.ctx, tt.args.operatorClient, kubeClient.CoreV1(), tt.args.nameSpace, tt.args.tenantName, tt.args.deletePvcs); (err != nil) != tt.wantErr {
|
||||
if err := deleteTenantAction(tt.args.ctx, tt.args.operatorClient, kubeClient.CoreV1(), tt.args.tenant, tt.args.deletePvcs); (err != nil) != tt.wantErr {
|
||||
t.Errorf("deleteTenantAction() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
@@ -1017,31 +1040,6 @@ func Test_UpdateTenantAction(t *testing.T) {
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "Update minio console version no errors",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
operatorClient: opClient,
|
||||
httpCl: httpClientM,
|
||||
nameSpace: "default",
|
||||
tenantName: "minio-tenant",
|
||||
mockTenantPatch: func(ctx context.Context, namespace string, tenantName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*miniov2.Tenant, error) {
|
||||
return &miniov2.Tenant{}, nil
|
||||
},
|
||||
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*miniov2.Tenant, error) {
|
||||
return &miniov2.Tenant{}, nil
|
||||
},
|
||||
mockHTTPClientGet: func(url string) (resp *http.Response, err error) {
|
||||
return nil, errors.New("use default minio")
|
||||
},
|
||||
params: operator_api.UpdateTenantParams{
|
||||
Body: &models.UpdateTenantRequest{
|
||||
ConsoleImage: "minio/console:v0.8.3",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "Update minio image pull secrets no errors",
|
||||
args: args{
|
||||
|
||||
@@ -18,6 +18,7 @@ package operatorapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
miniov1 "github.com/minio/operator/pkg/apis/minio.min.io/v1"
|
||||
|
||||
@@ -39,6 +40,16 @@ func registerVolumesHandlers(api *operations.OperatorAPI) {
|
||||
|
||||
return operator_api.NewListPVCsOK().WithPayload(payload)
|
||||
})
|
||||
|
||||
api.OperatorAPIListPVCsForTenantHandler = operator_api.ListPVCsForTenantHandlerFunc(func(params operator_api.ListPVCsForTenantParams, session *models.Principal) middleware.Responder {
|
||||
payload, err := getPVCsForTenantResponse(session, params)
|
||||
|
||||
if err != nil {
|
||||
return operator_api.NewListPVCsForTenantDefault(int(err.Code)).WithPayload(err)
|
||||
}
|
||||
|
||||
return operator_api.NewListPVCsForTenantOK().WithPayload(payload)
|
||||
})
|
||||
}
|
||||
|
||||
func getPVCsResponse(session *models.Principal) (*models.ListPVCsResponse, *models.Error) {
|
||||
@@ -83,3 +94,46 @@ func getPVCsResponse(session *models.Principal) (*models.ListPVCsResponse, *mode
|
||||
|
||||
return &PVCsResponse, nil
|
||||
}
|
||||
|
||||
func getPVCsForTenantResponse(session *models.Principal, params operator_api.ListPVCsForTenantParams) (*models.ListPVCsResponse, *models.Error) {
|
||||
ctx := context.Background()
|
||||
clientset, err := cluster.K8sClient(session.STSSessionToken)
|
||||
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
|
||||
// Filter Tenant PVCs. They keep their v1 tenant annotation
|
||||
listOpts := metav1.ListOptions{
|
||||
LabelSelector: fmt.Sprintf("v1.min.io/tenant=%s", params.Tenant),
|
||||
}
|
||||
|
||||
// List all PVCs
|
||||
listAllPvcs, err2 := clientset.CoreV1().PersistentVolumeClaims(params.Namespace).List(ctx, listOpts)
|
||||
|
||||
if err2 != nil {
|
||||
return nil, prepareError(err2)
|
||||
}
|
||||
|
||||
var ListPVCs []*models.PvcsListResponse
|
||||
|
||||
for _, pvc := range listAllPvcs.Items {
|
||||
pvcResponse := models.PvcsListResponse{
|
||||
Name: pvc.Name,
|
||||
Age: pvc.CreationTimestamp.String(),
|
||||
Capacity: pvc.Status.Capacity.Storage().String(),
|
||||
Namespace: pvc.Namespace,
|
||||
Status: string(pvc.Status.Phase),
|
||||
StorageClass: *pvc.Spec.StorageClassName,
|
||||
Volume: pvc.Spec.VolumeName,
|
||||
Tenant: pvc.Labels["v1.min.io/tenant"],
|
||||
}
|
||||
ListPVCs = append(ListPVCs, &pvcResponse)
|
||||
}
|
||||
|
||||
PVCsResponse := models.ListPVCsResponse{
|
||||
Pvcs: ListPVCs,
|
||||
}
|
||||
|
||||
return &PVCsResponse, nil
|
||||
}
|
||||
|
||||
@@ -86,11 +86,12 @@ func serveProxy(responseWriter http.ResponseWriter, req *http.Request) {
|
||||
nsTenant := fmt.Sprintf("%s/%s", tenant.Namespace, tenant.Name)
|
||||
|
||||
tenantSchema := "http"
|
||||
tenantPort := ":9090"
|
||||
if tenant.AutoCert() || tenant.ConsoleExternalCert() {
|
||||
tenantPort := fmt.Sprintf(":%d", v2.ConsolePort)
|
||||
if tenant.AutoCert() || tenant.ExternalCert() {
|
||||
tenantSchema = "https"
|
||||
tenantPort = ":9443"
|
||||
tenantPort = fmt.Sprintf(":%d", v2.ConsoleTLSPort)
|
||||
}
|
||||
|
||||
tenantURL := fmt.Sprintf("%s://%s.%s.svc.%s%s", tenantSchema, tenant.ConsoleCIServiceName(), tenant.Namespace, v2.GetClusterDomain(), tenantPort)
|
||||
// for development
|
||||
//tenantURL = "http://localhost:9091"
|
||||
@@ -112,7 +113,10 @@ func serveProxy(responseWriter http.ResponseWriter, req *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
currentSecret, err := clientSet.CoreV1().Secrets(tenant.Namespace).Get(req.Context(), tenant.Spec.CredsSecret.Name, metav1.GetOptions{})
|
||||
k8sClient := k8sClient{
|
||||
client: clientSet,
|
||||
}
|
||||
tenantConfiguration, err := GetTenantConfiguration(req.Context(), &k8sClient, tenant)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
responseWriter.WriteHeader(500)
|
||||
@@ -120,8 +124,8 @@ func serveProxy(responseWriter http.ResponseWriter, req *http.Request) {
|
||||
}
|
||||
|
||||
data := map[string]string{
|
||||
"accessKey": string(currentSecret.Data["accesskey"]),
|
||||
"secretKey": string(currentSecret.Data["secretkey"]),
|
||||
"accessKey": string(tenantConfiguration["accesskey"]),
|
||||
"secretKey": string(tenantConfiguration["secretkey"]),
|
||||
}
|
||||
payload, _ := json.Marshal(data)
|
||||
|
||||
@@ -133,7 +137,7 @@ func serveProxy(responseWriter http.ResponseWriter, req *http.Request) {
|
||||
}
|
||||
loginReq.Header.Add("Content-Type", "application/json")
|
||||
|
||||
// FIXME: in the future we should use restapi.GetConsoleSTSClient()
|
||||
// FIXME: in the future we should use restapi.GetConsoleHTTPClient()
|
||||
tr := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}
|
||||
@@ -195,7 +199,7 @@ func serveProxy(responseWriter http.ResponseWriter, req *http.Request) {
|
||||
proxyCookieJar.SetCookies(targetURL, []*http.Cookie{proxiedCookie})
|
||||
|
||||
tr := &http.Transport{
|
||||
// FIXME: use restapi.GetConsoleSTSClient()
|
||||
// FIXME: use restapi.GetConsoleHTTPClient()
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}
|
||||
client := &http.Client{Transport: tr,
|
||||
|
||||
65
operatorapi/utils.go
Normal file
@@ -0,0 +1,65 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package operatorapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
miniov2 "github.com/minio/operator/pkg/apis/minio.min.io/v2"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func GetTenantConfiguration(ctx context.Context, clientSet K8sClientI, tenant *miniov2.Tenant) (map[string]string, error) {
|
||||
if tenant == nil {
|
||||
return nil, errors.New("tenant cannot be nil")
|
||||
}
|
||||
tenantConfiguration := map[string]string{}
|
||||
for _, config := range tenant.GetEnvVars() {
|
||||
tenantConfiguration[config.Name] = config.Value
|
||||
}
|
||||
// legacy support for tenants with tenant.spec.credsSecret
|
||||
if tenant.HasCredsSecret() {
|
||||
minioSecret, err := clientSet.getSecret(ctx, tenant.Namespace, tenant.Spec.CredsSecret.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
configFromCredsSecret := minioSecret.Data
|
||||
for key, val := range configFromCredsSecret {
|
||||
tenantConfiguration[key] = string(val)
|
||||
}
|
||||
}
|
||||
if tenant.HasConfigurationSecret() {
|
||||
minioConfigurationSecret, err := clientSet.getSecret(ctx, tenant.Namespace, tenant.Spec.Configuration.Name, metav1.GetOptions{})
|
||||
if err == nil {
|
||||
configFromFile := miniov2.ParseRawConfiguration(minioConfigurationSecret.Data["config.env"])
|
||||
for key, val := range configFromFile {
|
||||
tenantConfiguration[key] = string(val)
|
||||
}
|
||||
}
|
||||
}
|
||||
return tenantConfiguration, nil
|
||||
}
|
||||
|
||||
func GenerateTenantConfigurationFile(configuration map[string]string) string {
|
||||
var rawConfiguration string
|
||||
for key, val := range configuration {
|
||||
rawConfiguration += fmt.Sprintf("export %s=\"%s\"\n", key, val)
|
||||
}
|
||||
return rawConfiguration
|
||||
}
|
||||
@@ -22,43 +22,55 @@ import (
|
||||
|
||||
// endpoints definition
|
||||
var (
|
||||
configuration = "/settings"
|
||||
users = "/users"
|
||||
usersDetail = "/users/:userName+"
|
||||
groups = "/groups"
|
||||
iamPolicies = "/policies"
|
||||
policiesDetail = "/policies/:policyName"
|
||||
dashboard = "/dashboard"
|
||||
metrics = "/metrics"
|
||||
profiling = "/profiling"
|
||||
buckets = "/buckets"
|
||||
bucketsDetail = "/buckets/*"
|
||||
serviceAccounts = "/account"
|
||||
changePassword = "/account/change-password"
|
||||
tenants = "/tenants"
|
||||
tenantsDetail = "/namespaces/:tenantNamespace/tenants/:tenantName"
|
||||
tenantHop = "/namespaces/:tenantNamespace/tenants/:tenantName/hop"
|
||||
podsDetail = "/namespaces/:tenantNamespace/tenants/:tenantName/pods/:podName"
|
||||
tenantsDetailSummary = "/namespaces/:tenantNamespace/tenants/:tenantName/summary"
|
||||
tenantsDetailMetrics = "/namespaces/:tenantNamespace/tenants/:tenantName/metrics"
|
||||
tenantsDetailPods = "/namespaces/:tenantNamespace/tenants/:tenantName/pods"
|
||||
tenantsDetailPools = "/namespaces/:tenantNamespace/tenants/:tenantName/pools"
|
||||
tenantsDetailLicense = "/namespaces/:tenantNamespace/tenants/:tenantName/license"
|
||||
tenantsDetailSecurity = "/namespaces/:tenantNamespace/tenants/:tenantName/security"
|
||||
storage = "/storage"
|
||||
storageVolumes = "/storage/volumes"
|
||||
storageDrives = "/storage/drives"
|
||||
remoteBuckets = "/remote-buckets"
|
||||
replication = "/replication"
|
||||
objectBrowser = "/object-browser/:bucket/*"
|
||||
objectBrowserBucket = "/object-browser/:bucket"
|
||||
mainObjectBrowser = "/object-browser"
|
||||
license = "/license"
|
||||
watch = "/watch"
|
||||
heal = "/heal"
|
||||
trace = "/trace"
|
||||
logs = "/logs"
|
||||
healthInfo = "/health-info"
|
||||
configuration = "/settings"
|
||||
notificationEndpoints = "/notification-endpoints"
|
||||
notificationEndpointsAddAny = "/notification-endpoints/add/:service"
|
||||
notificationEndpointsAdd = "/notification-endpoints/add"
|
||||
tiers = "/tiers"
|
||||
tiersAddAny = "/tiers/add/:service"
|
||||
tiersAdd = "/tiers/add"
|
||||
users = "/users"
|
||||
usersDetail = "/users/:userName+"
|
||||
groups = "/groups"
|
||||
iamPolicies = "/policies"
|
||||
policiesDetail = "/policies/*"
|
||||
dashboard = "/dashboard"
|
||||
metrics = "/metrics"
|
||||
profiling = "/profiling"
|
||||
buckets = "/buckets"
|
||||
bucketsGeneral = "/buckets/*"
|
||||
bucketsAdmin = "/buckets/:bucketName/admin/*"
|
||||
bucketsAdminMain = "/buckets/:bucketName/admin"
|
||||
bucketsBrowserMenu = "/buckets"
|
||||
bucketsBrowserList = "/buckets/*"
|
||||
bucketsBrowser = "/buckets/:bucketName/browse/*"
|
||||
bucketsBrowserMain = "/buckets/:bucketName/browse"
|
||||
serviceAccounts = "/account"
|
||||
changePassword = "/account/change-password"
|
||||
tenants = "/tenants"
|
||||
tenantsAdd = "/tenants/add"
|
||||
tenantsAddSub = "/tenants/add/*"
|
||||
tenantsDetail = "/namespaces/:tenantNamespace/tenants/:tenantName"
|
||||
tenantHop = "/namespaces/:tenantNamespace/tenants/:tenantName/hop"
|
||||
podsDetail = "/namespaces/:tenantNamespace/tenants/:tenantName/pods/:podName"
|
||||
tenantsDetailSummary = "/namespaces/:tenantNamespace/tenants/:tenantName/summary"
|
||||
tenantsDetailMetrics = "/namespaces/:tenantNamespace/tenants/:tenantName/metrics"
|
||||
tenantsDetailPods = "/namespaces/:tenantNamespace/tenants/:tenantName/pods"
|
||||
tenantsDetailPools = "/namespaces/:tenantNamespace/tenants/:tenantName/pools"
|
||||
tenantsDetailVolumes = "/namespaces/:tenantNamespace/tenants/:tenantName/volumes"
|
||||
tenantsDetailLicense = "/namespaces/:tenantNamespace/tenants/:tenantName/license"
|
||||
tenantsDetailSecurity = "/namespaces/:tenantNamespace/tenants/:tenantName/security"
|
||||
storage = "/storage"
|
||||
storageVolumes = "/storage/volumes"
|
||||
storageDrives = "/storage/drives"
|
||||
remoteBuckets = "/remote-buckets"
|
||||
replication = "/replication"
|
||||
license = "/license"
|
||||
watch = "/watch"
|
||||
heal = "/heal"
|
||||
trace = "/trace"
|
||||
logs = "/logs"
|
||||
healthInfo = "/health-info"
|
||||
)
|
||||
|
||||
type ConfigurationActionSet struct {
|
||||
@@ -281,41 +293,53 @@ var displayRules = map[string]func() bool{
|
||||
|
||||
// endpointRules contains the mapping between endpoints and ActionSets, additional rules can be added here
|
||||
var endpointRules = map[string]ConfigurationActionSet{
|
||||
configuration: configurationActionSet,
|
||||
users: usersActionSet,
|
||||
usersDetail: usersActionSet,
|
||||
groups: groupsActionSet,
|
||||
iamPolicies: iamPoliciesActionSet,
|
||||
policiesDetail: iamPoliciesActionSet,
|
||||
dashboard: dashboardActionSet,
|
||||
metrics: dashboardActionSet,
|
||||
profiling: profilingActionSet,
|
||||
buckets: bucketsActionSet,
|
||||
bucketsDetail: bucketsActionSet,
|
||||
serviceAccounts: serviceAccountsActionSet,
|
||||
changePassword: changePasswordActionSet,
|
||||
remoteBuckets: remoteBucketsActionSet,
|
||||
replication: replicationActionSet,
|
||||
objectBrowser: objectBrowserActionSet,
|
||||
mainObjectBrowser: objectBrowserActionSet,
|
||||
objectBrowserBucket: objectBrowserActionSet,
|
||||
license: licenseActionSet,
|
||||
watch: watchActionSet,
|
||||
heal: healActionSet,
|
||||
trace: traceActionSet,
|
||||
logs: logsActionSet,
|
||||
healthInfo: healthInfoActionSet,
|
||||
configuration: configurationActionSet,
|
||||
notificationEndpoints: configurationActionSet,
|
||||
notificationEndpointsAdd: configurationActionSet,
|
||||
notificationEndpointsAddAny: configurationActionSet,
|
||||
tiers: configurationActionSet,
|
||||
tiersAdd: configurationActionSet,
|
||||
tiersAddAny: configurationActionSet,
|
||||
users: usersActionSet,
|
||||
usersDetail: usersActionSet,
|
||||
groups: groupsActionSet,
|
||||
iamPolicies: iamPoliciesActionSet,
|
||||
policiesDetail: iamPoliciesActionSet,
|
||||
dashboard: dashboardActionSet,
|
||||
metrics: dashboardActionSet,
|
||||
profiling: profilingActionSet,
|
||||
buckets: bucketsActionSet,
|
||||
bucketsGeneral: bucketsActionSet,
|
||||
bucketsAdmin: bucketsActionSet,
|
||||
bucketsAdminMain: bucketsActionSet,
|
||||
serviceAccounts: serviceAccountsActionSet,
|
||||
changePassword: changePasswordActionSet,
|
||||
remoteBuckets: remoteBucketsActionSet,
|
||||
replication: replicationActionSet,
|
||||
bucketsBrowser: objectBrowserActionSet,
|
||||
bucketsBrowserMenu: objectBrowserActionSet,
|
||||
bucketsBrowserList: objectBrowserActionSet,
|
||||
bucketsBrowserMain: objectBrowserActionSet,
|
||||
license: licenseActionSet,
|
||||
watch: watchActionSet,
|
||||
heal: healActionSet,
|
||||
trace: traceActionSet,
|
||||
logs: logsActionSet,
|
||||
healthInfo: healthInfoActionSet,
|
||||
}
|
||||
|
||||
// operatorRules contains the mapping between endpoints and ActionSets for operator only mode
|
||||
var operatorRules = map[string]ConfigurationActionSet{
|
||||
tenants: tenantsActionSet,
|
||||
tenantsAdd: tenantsActionSet,
|
||||
tenantsAddSub: tenantsActionSet,
|
||||
tenantsDetail: tenantsActionSet,
|
||||
tenantHop: tenantsActionSet,
|
||||
tenantsDetailSummary: tenantsActionSet,
|
||||
tenantsDetailMetrics: tenantsActionSet,
|
||||
tenantsDetailPods: tenantsActionSet,
|
||||
tenantsDetailPools: tenantsActionSet,
|
||||
tenantsDetailVolumes: tenantsActionSet,
|
||||
tenantsDetailLicense: tenantsActionSet,
|
||||
tenantsDetailSecurity: tenantsActionSet,
|
||||
podsDetail: tenantsActionSet,
|
||||
@@ -382,7 +406,6 @@ func GetAuthorizedEndpoints(actions []string) []string {
|
||||
if operatorOnly {
|
||||
rangeTake = operatorRules
|
||||
}
|
||||
|
||||
// Prepare new ActionSet structure that will hold all the user actions
|
||||
userAllowedAction := actionsStringToActionSet(actions)
|
||||
var allowedEndpoints []string
|
||||
|
||||
@@ -19,8 +19,6 @@ package acl
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
iampolicy "github.com/minio/pkg/iam/policy"
|
||||
)
|
||||
|
||||
type args struct {
|
||||
@@ -50,7 +48,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
|
||||
args: args{
|
||||
[]string{"admin:ServerInfo"},
|
||||
},
|
||||
want: 8,
|
||||
want: 9,
|
||||
},
|
||||
{
|
||||
name: "policies endpoint",
|
||||
@@ -63,7 +61,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
|
||||
"admin:ListUserPolicies",
|
||||
},
|
||||
},
|
||||
want: 8,
|
||||
want: 9,
|
||||
},
|
||||
{
|
||||
name: "all admin endpoints",
|
||||
@@ -72,7 +70,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
|
||||
"admin:*",
|
||||
},
|
||||
},
|
||||
want: 22,
|
||||
want: 29,
|
||||
},
|
||||
{
|
||||
name: "all s3 endpoints",
|
||||
@@ -81,7 +79,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
|
||||
"s3:*",
|
||||
},
|
||||
},
|
||||
want: 8,
|
||||
want: 9,
|
||||
},
|
||||
{
|
||||
name: "all admin and s3 endpoints",
|
||||
@@ -91,14 +89,14 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
|
||||
"s3:*",
|
||||
},
|
||||
},
|
||||
want: 24,
|
||||
want: 31,
|
||||
},
|
||||
{
|
||||
name: "Console User - default endpoints",
|
||||
args: args{
|
||||
[]string{},
|
||||
},
|
||||
want: 6,
|
||||
want: 7,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -111,80 +109,10 @@ func TestOperatorOnlyEndpoints(t *testing.T) {
|
||||
tests := []endpoint{
|
||||
{
|
||||
name: "Operator Only - all admin endpoints",
|
||||
args: args{
|
||||
[]string{
|
||||
"admin:*",
|
||||
},
|
||||
},
|
||||
want: 14,
|
||||
},
|
||||
{
|
||||
name: "Operator Only - all s3 endpoints",
|
||||
args: args{
|
||||
[]string{
|
||||
"s3:*",
|
||||
},
|
||||
},
|
||||
want: 14,
|
||||
},
|
||||
{
|
||||
name: "Operator Only - all admin and s3 endpoints",
|
||||
args: args{
|
||||
[]string{
|
||||
"admin:*",
|
||||
"s3:*",
|
||||
},
|
||||
},
|
||||
want: 14,
|
||||
},
|
||||
{
|
||||
name: "Operator Only - default endpoints",
|
||||
args: args{
|
||||
[]string{},
|
||||
},
|
||||
want: 14,
|
||||
args: args{},
|
||||
want: 17,
|
||||
},
|
||||
}
|
||||
|
||||
validateEndpoints(t, tests)
|
||||
}
|
||||
|
||||
func TestGetActionsStringFromPolicy(t *testing.T) {
|
||||
type args struct {
|
||||
policy *iampolicy.Policy
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want int
|
||||
}{
|
||||
{
|
||||
name: "parse ReadOnly policy",
|
||||
args: args{
|
||||
policy: &iampolicy.ReadOnly,
|
||||
},
|
||||
want: 2,
|
||||
},
|
||||
{
|
||||
name: "parse WriteOnly policy",
|
||||
args: args{
|
||||
policy: &iampolicy.WriteOnly,
|
||||
},
|
||||
want: 1,
|
||||
},
|
||||
{
|
||||
name: "parse AdminDiagnostics policy",
|
||||
args: args{
|
||||
policy: &iampolicy.AdminDiagnostics,
|
||||
},
|
||||
want: 8,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := GetActionsStringFromPolicy(tt.args.policy); !reflect.DeepEqual(len(got), tt.want) {
|
||||
t.Errorf("GetActionsStringFromPolicy() = %v, want %v", len(got), tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,49 +29,53 @@ func GetSTSEndpoint() string {
|
||||
return strings.TrimSpace(env.Get(ConsoleMinIOServer, "http://localhost:9000"))
|
||||
}
|
||||
|
||||
func GetIdpURL() string {
|
||||
return env.Get(ConsoleIdpURL, "")
|
||||
func GetIDPURL() string {
|
||||
return env.Get(ConsoleIDPURL, "")
|
||||
}
|
||||
|
||||
func GetIdpClientID() string {
|
||||
return env.Get(ConsoleIdpClientID, "")
|
||||
func GetIDPClientID() string {
|
||||
return env.Get(ConsoleIDPClientID, "")
|
||||
}
|
||||
|
||||
func GetIdpSecret() string {
|
||||
return env.Get(ConsoleIdpSecret, "")
|
||||
func GetIDPUserInfo() bool {
|
||||
return env.Get(ConsoleIDPUserInfo, "") == "on"
|
||||
}
|
||||
|
||||
func GetIDPSecret() string {
|
||||
return env.Get(ConsoleIDPSecret, "")
|
||||
}
|
||||
|
||||
// Public endpoint used by the identity oidcProvider when redirecting the user after identity verification
|
||||
func GetIdpCallbackURL() string {
|
||||
return env.Get(ConsoleIdpCallbackURL, "")
|
||||
func GetIDPCallbackURL() string {
|
||||
return env.Get(ConsoleIDPCallbackURL, "")
|
||||
}
|
||||
|
||||
func IsIdpEnabled() bool {
|
||||
return GetIdpURL() != "" &&
|
||||
GetIdpClientID() != "" &&
|
||||
GetIdpCallbackURL() != ""
|
||||
func IsIDPEnabled() bool {
|
||||
return GetIDPURL() != "" &&
|
||||
GetIDPClientID() != "" &&
|
||||
GetIDPCallbackURL() != ""
|
||||
}
|
||||
|
||||
var defaultPassphraseForIdpHmac = utils.RandomCharString(64)
|
||||
var defaultPassphraseForIDPHmac = utils.RandomCharString(64)
|
||||
|
||||
// GetPassphraseForIdpHmac returns passphrase for the pbkdf2 function used to sign the oauth2 state parameter
|
||||
func getPassphraseForIdpHmac() string {
|
||||
return env.Get(ConsoleIdpHmacPassphrase, defaultPassphraseForIdpHmac)
|
||||
// GetPassphraseForIDPHmac returns passphrase for the pbkdf2 function used to sign the oauth2 state parameter
|
||||
func getPassphraseForIDPHmac() string {
|
||||
return env.Get(ConsoleIDPHmacPassphrase, defaultPassphraseForIDPHmac)
|
||||
}
|
||||
|
||||
var defaultSaltForIdpHmac = utils.RandomCharString(64)
|
||||
var defaultSaltForIDPHmac = utils.RandomCharString(64)
|
||||
|
||||
// GetSaltForIdpHmac returns salt for the pbkdf2 function used to sign the oauth2 state parameter
|
||||
func getSaltForIdpHmac() string {
|
||||
return env.Get(ConsoleIdpHmacSalt, defaultSaltForIdpHmac)
|
||||
// GetSaltForIDPHmac returns salt for the pbkdf2 function used to sign the oauth2 state parameter
|
||||
func getSaltForIDPHmac() string {
|
||||
return env.Get(ConsoleIDPHmacSalt, defaultSaltForIDPHmac)
|
||||
}
|
||||
|
||||
// getIdpScopes return default scopes during the IDP login request
|
||||
func getIdpScopes() string {
|
||||
// getIDPScopes return default scopes during the IDP login request
|
||||
func getIDPScopes() string {
|
||||
return env.Get(ConsoleIDPScopes, "openid,profile,email")
|
||||
}
|
||||
|
||||
// getIdpTokenExpiration return default token expiration for access token (in seconds)
|
||||
func getIdpTokenExpiration() string {
|
||||
// getIDPTokenExpiration return default token expiration for access token (in seconds)
|
||||
func getIDPTokenExpiration() string {
|
||||
return env.Get(ConsoleIDPTokenExpiration, "3600")
|
||||
}
|
||||
|
||||
@@ -16,15 +16,16 @@
|
||||
|
||||
package oauth2
|
||||
|
||||
// Environment constants for console IDP/SSO configuration
|
||||
const (
|
||||
// const for idp configuration
|
||||
ConsoleMinIOServer = "CONSOLE_MINIO_SERVER"
|
||||
ConsoleIdpURL = "CONSOLE_IDP_URL"
|
||||
ConsoleIdpClientID = "CONSOLE_IDP_CLIENT_ID"
|
||||
ConsoleIdpSecret = "CONSOLE_IDP_SECRET"
|
||||
ConsoleIdpCallbackURL = "CONSOLE_IDP_CALLBACK"
|
||||
ConsoleIdpHmacPassphrase = "CONSOLE_IDP_HMAC_PASSPHRASE"
|
||||
ConsoleIdpHmacSalt = "CONSOLE_IDP_HMAC_SALT"
|
||||
ConsoleIDPURL = "CONSOLE_IDP_URL"
|
||||
ConsoleIDPClientID = "CONSOLE_IDP_CLIENT_ID"
|
||||
ConsoleIDPSecret = "CONSOLE_IDP_SECRET"
|
||||
ConsoleIDPCallbackURL = "CONSOLE_IDP_CALLBACK"
|
||||
ConsoleIDPHmacPassphrase = "CONSOLE_IDP_HMAC_PASSPHRASE"
|
||||
ConsoleIDPHmacSalt = "CONSOLE_IDP_HMAC_SALT"
|
||||
ConsoleIDPScopes = "CONSOLE_IDP_SCOPES"
|
||||
ConsoleIDPUserInfo = "CONSOLE_IDP_USERINFO"
|
||||
ConsoleIDPTokenExpiration = "CONSOLE_IDP_TOKEN_EXPIRATION"
|
||||
)
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"context"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
@@ -30,7 +31,6 @@ import (
|
||||
|
||||
"github.com/minio/minio-go/v7/pkg/credentials"
|
||||
|
||||
"github.com/coreos/go-oidc"
|
||||
"github.com/minio/console/pkg/auth/utils"
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
"golang.org/x/oauth2"
|
||||
@@ -49,6 +49,24 @@ type Config struct {
|
||||
xoauth2.Config
|
||||
}
|
||||
|
||||
// DiscoveryDoc - parses the output from openid-configuration
|
||||
// for example https://accounts.google.com/.well-known/openid-configuration
|
||||
type DiscoveryDoc struct {
|
||||
Issuer string `json:"issuer,omitempty"`
|
||||
AuthEndpoint string `json:"authorization_endpoint,omitempty"`
|
||||
TokenEndpoint string `json:"token_endpoint,omitempty"`
|
||||
UserInfoEndpoint string `json:"userinfo_endpoint,omitempty"`
|
||||
RevocationEndpoint string `json:"revocation_endpoint,omitempty"`
|
||||
JwksURI string `json:"jwks_uri,omitempty"`
|
||||
ResponseTypesSupported []string `json:"response_types_supported,omitempty"`
|
||||
SubjectTypesSupported []string `json:"subject_types_supported,omitempty"`
|
||||
IDTokenSigningAlgValuesSupported []string `json:"id_token_signing_alg_values_supported,omitempty"`
|
||||
ScopesSupported []string `json:"scopes_supported,omitempty"`
|
||||
TokenEndpointAuthMethods []string `json:"token_endpoint_auth_methods_supported,omitempty"`
|
||||
ClaimsSupported []string `json:"claims_supported,omitempty"`
|
||||
CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported,omitempty"`
|
||||
}
|
||||
|
||||
func (ac Config) Exchange(ctx context.Context, code string, opts ...xoauth2.AuthCodeOption) (*xoauth2.Token, error) {
|
||||
return ac.Exchange(ctx, code, opts...)
|
||||
}
|
||||
@@ -88,51 +106,51 @@ type Provider struct {
|
||||
// often available via site-specific packages, such as
|
||||
// google.Endpoint or github.Endpoint.
|
||||
// - Scopes specifies optional requested permissions.
|
||||
ClientID string
|
||||
ClientID string
|
||||
// if enabled means that we need extrace access_token as well
|
||||
UserInfo bool
|
||||
oauth2Config Configuration
|
||||
oidcProvider *oidc.Provider
|
||||
provHTTPClient *http.Client
|
||||
}
|
||||
|
||||
// derivedKey is the key used to compute the HMAC for signing the oauth state parameter
|
||||
// its derived using pbkdf on CONSOLE_IDP_HMAC_PASSPHRASE with CONSOLE_IDP_HMAC_SALT
|
||||
var derivedKey = func() []byte {
|
||||
return pbkdf2.Key([]byte(getPassphraseForIdpHmac()), []byte(getSaltForIdpHmac()), 4096, 32, sha1.New)
|
||||
return pbkdf2.Key([]byte(getPassphraseForIDPHmac()), []byte(getSaltForIDPHmac()), 4096, 32, sha1.New)
|
||||
}
|
||||
|
||||
// NewOauth2ProviderClient instantiates a new oauth2 client using the configured credentials
|
||||
// it returns a *Provider object that contains the necessary configuration to initiate an
|
||||
// oauth2 authentication flow
|
||||
func NewOauth2ProviderClient(ctx context.Context, scopes []string, httpClient *http.Client) (*Provider, error) {
|
||||
customCtx := oidc.ClientContext(ctx, httpClient)
|
||||
provider, err := oidc.NewProvider(customCtx, GetIdpURL())
|
||||
func NewOauth2ProviderClient(scopes []string, httpClient *http.Client) (*Provider, error) {
|
||||
|
||||
ddoc, err := parseDiscoveryDoc(GetIDPURL(), httpClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// if google, change scopes
|
||||
u, err := url.Parse(GetIdpURL())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// below verification should not be necessary if the user configure exactly the
|
||||
// scopes he need, will be removed on a future release
|
||||
if u.Host == "google.com" {
|
||||
scopes = []string{oidc.ScopeOpenID}
|
||||
}
|
||||
|
||||
// If provided scopes are empty we use a default list or the user configured list
|
||||
if len(scopes) == 0 {
|
||||
scopes = strings.Split(getIdpScopes(), ",")
|
||||
scopes = strings.Split(getIDPScopes(), ",")
|
||||
}
|
||||
|
||||
// add "openid" scope always.
|
||||
scopes = append(scopes, "openid")
|
||||
|
||||
client := new(Provider)
|
||||
client.oauth2Config = &xoauth2.Config{
|
||||
ClientID: GetIdpClientID(),
|
||||
ClientSecret: GetIdpSecret(),
|
||||
RedirectURL: GetIdpCallbackURL(),
|
||||
Endpoint: provider.Endpoint(),
|
||||
Scopes: scopes,
|
||||
ClientID: GetIDPClientID(),
|
||||
ClientSecret: GetIDPSecret(),
|
||||
RedirectURL: GetIDPCallbackURL(),
|
||||
Endpoint: oauth2.Endpoint{
|
||||
AuthURL: ddoc.AuthEndpoint,
|
||||
TokenURL: ddoc.TokenEndpoint,
|
||||
},
|
||||
Scopes: scopes,
|
||||
}
|
||||
client.oidcProvider = provider
|
||||
client.ClientID = GetIdpClientID()
|
||||
|
||||
client.ClientID = GetIDPClientID()
|
||||
client.UserInfo = GetIDPUserInfo()
|
||||
client.provHTTPClient = httpClient
|
||||
|
||||
return client, nil
|
||||
@@ -184,18 +202,26 @@ func (client *Provider) VerifyIdentity(ctx context.Context, code, state string)
|
||||
|
||||
// check if user configured a hardcoded expiration for console via env variables
|
||||
// and override the incoming expiration
|
||||
userConfiguredExpiration := getIdpTokenExpiration()
|
||||
userConfiguredExpiration := getIDPTokenExpiration()
|
||||
if userConfiguredExpiration != "" {
|
||||
expiration, _ = strconv.Atoi(userConfiguredExpiration)
|
||||
}
|
||||
idToken := oauth2Token.Extra("id_token")
|
||||
if idToken == nil {
|
||||
return nil, errors.New("returned token is missing id_token claim")
|
||||
return nil, errors.New("missing id_token")
|
||||
}
|
||||
return &credentials.WebIdentityToken{
|
||||
token := &credentials.WebIdentityToken{
|
||||
Token: idToken.(string),
|
||||
Expiry: expiration,
|
||||
}, nil
|
||||
}
|
||||
if client.UserInfo { // look for access_token only if userinfo is requested.
|
||||
accessToken := oauth2Token.Extra("access_token")
|
||||
if accessToken == nil {
|
||||
return nil, errors.New("missing access_token")
|
||||
}
|
||||
token.AccessToken = accessToken.(string)
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
stsEndpoint := GetSTSEndpoint()
|
||||
sts := credentials.New(&credentials.STSWebIdentity{
|
||||
@@ -235,6 +261,32 @@ func validateOauth2State(state string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// parseDiscoveryDoc parses a discovery doc from an OAuth provider
|
||||
// into a DiscoveryDoc struct that have the correct endpoints
|
||||
func parseDiscoveryDoc(ustr string, httpClient *http.Client) (DiscoveryDoc, error) {
|
||||
d := DiscoveryDoc{}
|
||||
req, err := http.NewRequest(http.MethodGet, ustr, nil)
|
||||
if err != nil {
|
||||
return d, err
|
||||
}
|
||||
clnt := http.Client{
|
||||
Transport: httpClient.Transport,
|
||||
}
|
||||
resp, err := clnt.Do(req)
|
||||
if err != nil {
|
||||
return d, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return d, err
|
||||
}
|
||||
dec := json.NewDecoder(resp.Body)
|
||||
if err = dec.Decode(&d); err != nil {
|
||||
return d, err
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// GetRandomStateWithHMAC computes message + hmac(message, pbkdf2(key, salt)) to be used as state during the oauth authorization
|
||||
func GetRandomStateWithHMAC(length int) string {
|
||||
state := utils.RandomCharString(length)
|
||||
|
||||
@@ -21,7 +21,6 @@ import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/coreos/go-oidc"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
@@ -58,7 +57,6 @@ func TestGenerateLoginURL(t *testing.T) {
|
||||
funcAssert := assert.New(t)
|
||||
oauth2Provider := Provider{
|
||||
oauth2Config: Oauth2configMock{},
|
||||
oidcProvider: &oidc.Provider{},
|
||||
}
|
||||
// Test-1 : GenerateLoginURL() generates URL correctly with provided state
|
||||
oauth2ConfigAuthCodeURLMock = func(state string, opts ...oauth2.AuthCodeOption) string {
|
||||
|
||||
@@ -62,11 +62,10 @@ func IsSessionTokenValid(token string) bool {
|
||||
|
||||
// TokenClaims claims struct for decrypted credentials
|
||||
type TokenClaims struct {
|
||||
STSAccessKeyID string `json:"stsAccessKeyID,omitempty"`
|
||||
STSSecretAccessKey string `json:"stsSecretAccessKey,omitempty"`
|
||||
STSSessionToken string `json:"stsSessionToken,omitempty"`
|
||||
AccountAccessKey string `json:"accountAccessKey,omitempty"`
|
||||
Actions []string `json:"actions,omitempty"`
|
||||
STSAccessKeyID string `json:"stsAccessKeyID,omitempty"`
|
||||
STSSecretAccessKey string `json:"stsSecretAccessKey,omitempty"`
|
||||
STSSessionToken string `json:"stsSessionToken,omitempty"`
|
||||
AccountAccessKey string `json:"accountAccessKey,omitempty"`
|
||||
}
|
||||
|
||||
// SessionTokenAuthenticate takes a session token, decode it, extract claims and validate the signature
|
||||
@@ -79,7 +78,6 @@ type TokenClaims struct {
|
||||
// STSSecretAccessKey
|
||||
// STSSessionToken
|
||||
// AccountAccessKey
|
||||
// Actions
|
||||
// }
|
||||
func SessionTokenAuthenticate(token string) (*TokenClaims, error) {
|
||||
if token == "" {
|
||||
@@ -98,14 +96,13 @@ func SessionTokenAuthenticate(token string) (*TokenClaims, error) {
|
||||
|
||||
// NewEncryptedTokenForClient generates a new session token with claims based on the provided STS credentials, first
|
||||
// encrypts the claims and the sign them
|
||||
func NewEncryptedTokenForClient(credentials *credentials.Value, accountAccessKey string, actions []string) (string, error) {
|
||||
func NewEncryptedTokenForClient(credentials *credentials.Value, accountAccessKey string) (string, error) {
|
||||
if credentials != nil {
|
||||
encryptedClaims, err := encryptClaims(&TokenClaims{
|
||||
STSAccessKeyID: credentials.AccessKeyID,
|
||||
STSSecretAccessKey: credentials.SecretAccessKey,
|
||||
STSSessionToken: credentials.SessionToken,
|
||||
AccountAccessKey: accountAccessKey,
|
||||
Actions: actions,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -311,7 +308,6 @@ func GetClaimsFromTokenInRequest(req *http.Request) (*models.Principal, error) {
|
||||
}
|
||||
return &models.Principal{
|
||||
STSAccessKeyID: claims.STSAccessKeyID,
|
||||
Actions: claims.Actions,
|
||||
STSSecretAccessKey: claims.STSSecretAccessKey,
|
||||
STSSessionToken: claims.STSSessionToken,
|
||||
AccountAccessKey: claims.AccountAccessKey,
|
||||
|
||||
@@ -36,14 +36,14 @@ func TestNewJWTWithClaimsForClient(t *testing.T) {
|
||||
funcAssert := assert.New(t)
|
||||
// Test-1 : NewEncryptedTokenForClient() is generated correctly without errors
|
||||
function := "NewEncryptedTokenForClient()"
|
||||
token, err := NewEncryptedTokenForClient(creds, "", []string{""})
|
||||
token, err := NewEncryptedTokenForClient(creds, "")
|
||||
if err != nil || token == "" {
|
||||
t.Errorf("Failed on %s:, error occurred: %s", function, err)
|
||||
}
|
||||
// saving token for future tests
|
||||
goodToken = token
|
||||
// Test-2 : NewEncryptedTokenForClient() throws error because of empty credentials
|
||||
if _, err = NewEncryptedTokenForClient(nil, "", []string{""}); err != nil {
|
||||
if _, err = NewEncryptedTokenForClient(nil, ""); err != nil {
|
||||
funcAssert.Equal("provided credentials are empty", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,12 +130,28 @@ type Gcp struct {
|
||||
SecretManager *GcpSecretManager `yaml:"secretmanager,omitempty"`
|
||||
}
|
||||
|
||||
type AzureCredentials struct {
|
||||
TenantID string `yaml:"tenant_id"`
|
||||
ClientID string `yaml:"client_id"`
|
||||
ClientSecret string `yaml:"client_secret"`
|
||||
}
|
||||
|
||||
type AzureKeyVault struct {
|
||||
Endpoint string `yaml:"endpoint,omitempty"`
|
||||
Credentials *AzureCredentials `yaml:"credentials,omitempty"`
|
||||
}
|
||||
|
||||
type Azure struct {
|
||||
KeyVault *AzureKeyVault `yaml:"keyvault,omitempty"`
|
||||
}
|
||||
|
||||
type Keys struct {
|
||||
Fs *Fs `yaml:"fs,omitempty"`
|
||||
Vault *Vault `yaml:"vault,omitempty"`
|
||||
Aws *Aws `yaml:"aws,omitempty"`
|
||||
Gemalto *Gemalto `yaml:"gemalto,omitempty"`
|
||||
Gcp *Gcp `yaml:"gcp,omitempty"`
|
||||
Azure *Azure `yaml:"azure,omitempty"`
|
||||
}
|
||||
|
||||
type ServerConfig struct {
|
||||
|
||||
@@ -150,6 +150,9 @@ func getLicenseFromCredentials(client cluster.HTTPClientI, username, password st
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
return "", fmt.Errorf("subnet served returned status %d code", resp.StatusCode)
|
||||
}
|
||||
userLicense := &subnetLicenseResponse{}
|
||||
// Parse subnet license response
|
||||
err = json.Unmarshal(bodyBytes, userLicense)
|
||||
|
||||
@@ -144,11 +144,17 @@ func Test_getLicenseFromCredentials(t *testing.T) {
|
||||
mockFunc: func() {
|
||||
HTTPPostMock = func(url, contentType string, body io.Reader) (resp *http.Response, err error) {
|
||||
// returning test jwt token
|
||||
return &http.Response{Body: ioutil.NopCloser(bytes.NewReader([]byte("{\"has_memberships\":true,\"token_info\":{\"access_token\":\"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik4wRXdOa1V5UXpORU1UUkNOekU0UmpSR1JVWkJSa1UxUmtZNE9EY3lOekZHTXpjNU1qZ3hNZyJ9.eyJodHRwczovL2lkLnN1Ym5ldC5taW4uaW8vY2xhaW1zL2dyb3VwcyI6W10sImh0dHBzOi8vaWQuc3VibmV0Lm1pbi5pby9jbGFpbXMvcm9sZXMiOltdLCJodHRwczovL2lkLnN1Ym5ldC5taW4uaW8vY2xhaW1zL2VtYWlsIjoibGVuaW4rYzFAbWluaW8uaW8iLCJpc3MiOiJodHRwczovL2lkLnN1Ym5ldC5taW4uaW8vIiwic3ViIjoiYXV0aDB8NWZjZWFlYTMyNTNhZjEwMDc3NDZkMDM0IiwiYXVkIjoiaHR0cHM6Ly9zdWJuZXQubWluLmlvL2FwaSIsImlhdCI6MTYwODQxNjE5NiwiZXhwIjoxNjExMDA4MTk2LCJhenAiOiI1WTA0eVZlejNiOFgxUFVzRHVqSmxuZXVuY3ExVjZxaiIsInNjb3BlIjoib2ZmbGluZV9hY2Nlc3MiLCJndHkiOiJwYXNzd29yZCJ9.GC8DRLT0jUEteuBZBmyMXMswLSblCr_89Gu5NcVRUzKSYAaZ5VFW4UFgo1BpiC0sePuWJ0Vykitphx7znTfZfj5B3mZbOw3ejG6kxz7nm9DuYMmySJFYnwroZ9EP02vkW7-n_-YvEg8le1wXfkJ3lTUzO3aWddS4rfQRsZ2YJJUj61GiNyEK_QNP4PrYOuzLyD1wV75NejFqfcFoj7nRkT1K2BM0-89-_f2AFDGTjov6Ig6s1s-zLC9wxcYSmubNwpCJytZmQgPqIepOr065Y6OB4n0n0B5sXguuGuzb8VAkECrHhHPz8ta926fc0jC4XxVCNKdbV1_qC3-1yY7AJA\",\"expires_in\":2592000.0,\"token_type\":\"Bearer\"}}")))}, nil
|
||||
return &http.Response{
|
||||
StatusCode: 200,
|
||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("{\"has_memberships\":true,\"token_info\":{\"access_token\":\"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik4wRXdOa1V5UXpORU1UUkNOekU0UmpSR1JVWkJSa1UxUmtZNE9EY3lOekZHTXpjNU1qZ3hNZyJ9.eyJodHRwczovL2lkLnN1Ym5ldC5taW4uaW8vY2xhaW1zL2dyb3VwcyI6W10sImh0dHBzOi8vaWQuc3VibmV0Lm1pbi5pby9jbGFpbXMvcm9sZXMiOltdLCJodHRwczovL2lkLnN1Ym5ldC5taW4uaW8vY2xhaW1zL2VtYWlsIjoibGVuaW4rYzFAbWluaW8uaW8iLCJpc3MiOiJodHRwczovL2lkLnN1Ym5ldC5taW4uaW8vIiwic3ViIjoiYXV0aDB8NWZjZWFlYTMyNTNhZjEwMDc3NDZkMDM0IiwiYXVkIjoiaHR0cHM6Ly9zdWJuZXQubWluLmlvL2FwaSIsImlhdCI6MTYwODQxNjE5NiwiZXhwIjoxNjExMDA4MTk2LCJhenAiOiI1WTA0eVZlejNiOFgxUFVzRHVqSmxuZXVuY3ExVjZxaiIsInNjb3BlIjoib2ZmbGluZV9hY2Nlc3MiLCJndHkiOiJwYXNzd29yZCJ9.GC8DRLT0jUEteuBZBmyMXMswLSblCr_89Gu5NcVRUzKSYAaZ5VFW4UFgo1BpiC0sePuWJ0Vykitphx7znTfZfj5B3mZbOw3ejG6kxz7nm9DuYMmySJFYnwroZ9EP02vkW7-n_-YvEg8le1wXfkJ3lTUzO3aWddS4rfQRsZ2YJJUj61GiNyEK_QNP4PrYOuzLyD1wV75NejFqfcFoj7nRkT1K2BM0-89-_f2AFDGTjov6Ig6s1s-zLC9wxcYSmubNwpCJytZmQgPqIepOr065Y6OB4n0n0B5sXguuGuzb8VAkECrHhHPz8ta926fc0jC4XxVCNKdbV1_qC3-1yY7AJA\",\"expires_in\":2592000.0,\"token_type\":\"Bearer\"}}"))),
|
||||
}, nil
|
||||
}
|
||||
HTTPDoMock = func(req *http.Request) (*http.Response, error) {
|
||||
// returning test jwt license
|
||||
return &http.Response{Body: ioutil.NopCloser(bytes.NewReader([]byte("{\"license\":\"" + license + "\",\"metadata\":{\"email\":\"lenin+c1@minio.io\",\"issuer\":\"subnet@minio.io\",\"accountId\":176,\"teamName\":\"console-customer\",\"serviceType\":\"STANDARD\",\"capacity\":25,\"requestedAt\":\"2020-12-19T22:23:31.609144732Z\",\"expiresAt\":\"2021-12-19T22:23:31.609144732Z\"}}")))}, nil
|
||||
return &http.Response{
|
||||
StatusCode: 200,
|
||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("{\"license\":\"" + license + "\",\"metadata\":{\"email\":\"lenin+c1@minio.io\",\"issuer\":\"subnet@minio.io\",\"accountId\":176,\"teamName\":\"console-customer\",\"serviceType\":\"STANDARD\",\"capacity\":25,\"requestedAt\":\"2020-12-19T22:23:31.609144732Z\",\"expiresAt\":\"2021-12-19T22:23:31.609144732Z\"}}"))),
|
||||
}, nil
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
1
portal-ui/build/amqp-logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="49.035" height="47.998" viewBox="0 0 49.035 47.998"><defs><style>.a{fill:#d0d2d4;}.b{fill:#0e2d90;}.c{fill:#adb9de;}</style></defs><path d="M89.091,200.387,75.719,187.176H40.056v13.211Z" transform="translate(-40.056 -152.389)"/><path class="a" d="M201.19,90.4V42.416H187.662V77.244Z" transform="translate(-152.155 -42.401)"/><path class="b" d="M57.736,114.687v.1H40.056V128H71.42Z" transform="translate(-40.056 -97.312)"/><path class="c" d="M127.346,73.042h.008V42.354H113.662V59.728Z" transform="translate(-96.074 -42.354)"/><path d="M53.434,56.086,40.056,43.069V56.276H53.434Z" transform="translate(-40.056 -42.897)"/><path class="a" d="M53.434,55.543V42.354H40.056v.172Z" transform="translate(-40.056 -42.354)"/></svg>
|
||||
|
After Width: | Height: | Size: 768 B |
@@ -1,25 +1,23 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "./static/css/main.8cfac526.chunk.css",
|
||||
"main.js": "./static/js/main.30880e75.chunk.js",
|
||||
"main.js.map": "./static/js/main.30880e75.chunk.js.map",
|
||||
"runtime-main.js": "./static/js/runtime-main.3fe0c1ac.js",
|
||||
"runtime-main.js.map": "./static/js/runtime-main.3fe0c1ac.js.map",
|
||||
"static/css/2.60e04a19.chunk.css": "./static/css/2.60e04a19.chunk.css",
|
||||
"static/js/2.147ecdb8.chunk.js": "./static/js/2.147ecdb8.chunk.js",
|
||||
"static/js/2.147ecdb8.chunk.js.map": "./static/js/2.147ecdb8.chunk.js.map",
|
||||
"main.css": "./static/css/main.e33a67ba.chunk.css",
|
||||
"main.js": "./static/js/main.0d2bb0ae.chunk.js",
|
||||
"main.js.map": "./static/js/main.0d2bb0ae.chunk.js.map",
|
||||
"runtime-main.js": "./static/js/runtime-main.30f8243a.js",
|
||||
"runtime-main.js.map": "./static/js/runtime-main.30f8243a.js.map",
|
||||
"static/css/2.5c96c0d7.chunk.css": "./static/css/2.5c96c0d7.chunk.css",
|
||||
"static/js/2.edb168ed.chunk.js": "./static/js/2.edb168ed.chunk.js",
|
||||
"static/js/2.edb168ed.chunk.js.map": "./static/js/2.edb168ed.chunk.js.map",
|
||||
"index.html": "./index.html",
|
||||
"static/css/2.60e04a19.chunk.css.map": "./static/css/2.60e04a19.chunk.css.map",
|
||||
"static/css/main.8cfac526.chunk.css.map": "./static/css/main.8cfac526.chunk.css.map",
|
||||
"static/js/2.147ecdb8.chunk.js.LICENSE.txt": "./static/js/2.147ecdb8.chunk.js.LICENSE.txt",
|
||||
"static/media/minio_console_logo.0837460e.svg": "./static/media/minio_console_logo.0837460e.svg",
|
||||
"static/media/minio_operator_logo.1312b7c9.svg": "./static/media/minio_operator_logo.1312b7c9.svg"
|
||||
"static/css/2.5c96c0d7.chunk.css.map": "./static/css/2.5c96c0d7.chunk.css.map",
|
||||
"static/css/main.e33a67ba.chunk.css.map": "./static/css/main.e33a67ba.chunk.css.map",
|
||||
"static/js/2.edb168ed.chunk.js.LICENSE.txt": "./static/js/2.edb168ed.chunk.js.LICENSE.txt"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/js/runtime-main.3fe0c1ac.js",
|
||||
"static/css/2.60e04a19.chunk.css",
|
||||
"static/js/2.147ecdb8.chunk.js",
|
||||
"static/css/main.8cfac526.chunk.css",
|
||||
"static/js/main.30880e75.chunk.js"
|
||||
"static/js/runtime-main.30f8243a.js",
|
||||
"static/css/2.5c96c0d7.chunk.css",
|
||||
"static/js/2.edb168ed.chunk.js",
|
||||
"static/css/main.e33a67ba.chunk.css",
|
||||
"static/js/main.0d2bb0ae.chunk.js"
|
||||
]
|
||||
}
|
||||
38
portal-ui/build/aws-logo.svg
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 304 182" style="enable-background:new 0 0 304 182;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#252F3E;}
|
||||
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:#FF9900;}
|
||||
</style>
|
||||
<g>
|
||||
<path class="st0" d="M86.4,66.4c0,3.7,0.4,6.7,1.1,8.9c0.8,2.2,1.8,4.6,3.2,7.2c0.5,0.8,0.7,1.6,0.7,2.3c0,1-0.6,2-1.9,3l-6.3,4.2
|
||||
c-0.9,0.6-1.8,0.9-2.6,0.9c-1,0-2-0.5-3-1.4C76.2,90,75,88.4,74,86.8c-1-1.7-2-3.6-3.1-5.9c-7.8,9.2-17.6,13.8-29.4,13.8
|
||||
c-8.4,0-15.1-2.4-20-7.2c-4.9-4.8-7.4-11.2-7.4-19.2c0-8.5,3-15.4,9.1-20.6c6.1-5.2,14.2-7.8,24.5-7.8c3.4,0,6.9,0.3,10.6,0.8
|
||||
c3.7,0.5,7.5,1.3,11.5,2.2v-7.3c0-7.6-1.6-12.9-4.7-16c-3.2-3.1-8.6-4.6-16.3-4.6c-3.5,0-7.1,0.4-10.8,1.3c-3.7,0.9-7.3,2-10.8,3.4
|
||||
c-1.6,0.7-2.8,1.1-3.5,1.3c-0.7,0.2-1.2,0.3-1.6,0.3c-1.4,0-2.1-1-2.1-3.1v-4.9c0-1.6,0.2-2.8,0.7-3.5c0.5-0.7,1.4-1.4,2.8-2.1
|
||||
c3.5-1.8,7.7-3.3,12.6-4.5c4.9-1.3,10.1-1.9,15.6-1.9c11.9,0,20.6,2.7,26.2,8.1c5.5,5.4,8.3,13.6,8.3,24.6V66.4z M45.8,81.6
|
||||
c3.3,0,6.7-0.6,10.3-1.8c3.6-1.2,6.8-3.4,9.5-6.4c1.6-1.9,2.8-4,3.4-6.4c0.6-2.4,1-5.3,1-8.7v-4.2c-2.9-0.7-6-1.3-9.2-1.7
|
||||
c-3.2-0.4-6.3-0.6-9.4-0.6c-6.7,0-11.6,1.3-14.9,4c-3.3,2.7-4.9,6.5-4.9,11.5c0,4.7,1.2,8.2,3.7,10.6
|
||||
C37.7,80.4,41.2,81.6,45.8,81.6z M126.1,92.4c-1.8,0-3-0.3-3.8-1c-0.8-0.6-1.5-2-2.1-3.9L96.7,10.2c-0.6-2-0.9-3.3-0.9-4
|
||||
c0-1.6,0.8-2.5,2.4-2.5h9.8c1.9,0,3.2,0.3,3.9,1c0.8,0.6,1.4,2,2,3.9l16.8,66.2l15.6-66.2c0.5-2,1.1-3.3,1.9-3.9c0.8-0.6,2.2-1,4-1
|
||||
h8c1.9,0,3.2,0.3,4,1c0.8,0.6,1.5,2,1.9,3.9l15.8,67l17.3-67c0.6-2,1.3-3.3,2-3.9c0.8-0.6,2.1-1,3.9-1h9.3c1.6,0,2.5,0.8,2.5,2.5
|
||||
c0,0.5-0.1,1-0.2,1.6c-0.1,0.6-0.3,1.4-0.7,2.5l-24.1,77.3c-0.6,2-1.3,3.3-2.1,3.9c-0.8,0.6-2.1,1-3.8,1h-8.6c-1.9,0-3.2-0.3-4-1
|
||||
c-0.8-0.7-1.5-2-1.9-4L156,23l-15.4,64.4c-0.5,2-1.1,3.3-1.9,4c-0.8,0.7-2.2,1-4,1H126.1z M254.6,95.1c-5.2,0-10.4-0.6-15.4-1.8
|
||||
c-5-1.2-8.9-2.5-11.5-4c-1.6-0.9-2.7-1.9-3.1-2.8c-0.4-0.9-0.6-1.9-0.6-2.8v-5.1c0-2.1,0.8-3.1,2.3-3.1c0.6,0,1.2,0.1,1.8,0.3
|
||||
c0.6,0.2,1.5,0.6,2.5,1c3.4,1.5,7.1,2.7,11,3.5c4,0.8,7.9,1.2,11.9,1.2c6.3,0,11.2-1.1,14.6-3.3c3.4-2.2,5.2-5.4,5.2-9.5
|
||||
c0-2.8-0.9-5.1-2.7-7c-1.8-1.9-5.2-3.6-10.1-5.2L246,52c-7.3-2.3-12.7-5.7-16-10.2c-3.3-4.4-5-9.3-5-14.5c0-4.2,0.9-7.9,2.7-11.1
|
||||
c1.8-3.2,4.2-6,7.2-8.2c3-2.3,6.4-4,10.4-5.2c4-1.2,8.2-1.7,12.6-1.7c2.2,0,4.5,0.1,6.7,0.4c2.3,0.3,4.4,0.7,6.5,1.1
|
||||
c2,0.5,3.9,1,5.7,1.6c1.8,0.6,3.2,1.2,4.2,1.8c1.4,0.8,2.4,1.6,3,2.5c0.6,0.8,0.9,1.9,0.9,3.3v4.7c0,2.1-0.8,3.2-2.3,3.2
|
||||
c-0.8,0-2.1-0.4-3.8-1.2c-5.7-2.6-12.1-3.9-19.2-3.9c-5.7,0-10.2,0.9-13.3,2.8c-3.1,1.9-4.7,4.8-4.7,8.9c0,2.8,1,5.2,3,7.1
|
||||
c2,1.9,5.7,3.8,11,5.5l14.2,4.5c7.2,2.3,12.4,5.5,15.5,9.6c3.1,4.1,4.6,8.8,4.6,14c0,4.3-0.9,8.2-2.6,11.6
|
||||
c-1.8,3.4-4.2,6.4-7.3,8.8c-3.1,2.5-6.8,4.3-11.1,5.6C264.4,94.4,259.7,95.1,254.6,95.1z"/>
|
||||
<g>
|
||||
<path class="st1" d="M273.5,143.7c-32.9,24.3-80.7,37.2-121.8,37.2c-57.6,0-109.5-21.3-148.7-56.7c-3.1-2.8-0.3-6.6,3.4-4.4
|
||||
c42.4,24.6,94.7,39.5,148.8,39.5c36.5,0,76.6-7.6,113.5-23.2C274.2,133.6,278.9,139.7,273.5,143.7z"/>
|
||||
<path class="st1" d="M287.2,128.1c-4.2-5.4-27.8-2.6-38.5-1.3c-3.2,0.4-3.7-2.4-0.8-4.5c18.8-13.2,49.7-9.4,53.3-5
|
||||
c3.6,4.5-1,35.4-18.6,50.2c-2.7,2.3-5.3,1.1-4.1-1.9C282.5,155.7,291.4,133.4,287.2,128.1z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
1
portal-ui/build/azure-logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="77.43" viewBox="0 0 19.68 15.24"><path d="M9.105 14.43l4.642-.82.043-.01-2.387-2.84a403.945 403.945 0 0 1-2.387-2.853c0-.014 2.465-6.802 2.479-6.826.004-.008 1.682 2.888 4.066 7.02l4.09 7.09.031.054-7.587-.001-7.587-.001 4.597-.812zM0 13.566c0-.004 1.125-1.957 2.5-4.34L5 4.893l2.913-2.445C9.515 1.104 10.83.002 10.836 0a.512.512 0 0 1-.047.118L7.625 6.903l-3.107 6.663-2.259.003c-1.242.002-2.259 0-2.259-.004z" fill="#0089d6"/></svg>
|
||||
|
After Width: | Height: | Size: 494 B |
1
portal-ui/build/elasticsearch-logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="42.034" height="45.939" viewBox="0 0 42.034 45.939"><defs><style>.a{fill:#00a9e5;}.b{fill:#353535;}.c{fill:#00bfb3;}.d{fill:#019b8f;}.e{fill:#f9b110;}.f{fill:#fed10a;}</style></defs><path class="a" d="M132.9,115.5h-12c.057.287.172.574.23.8a21.107,21.107,0,0,1,.747,4.307c.057.574.057,1.206.057,1.78s0,1.206-.057,1.78a21.106,21.106,0,0,1-.747,4.307c-.057.287-.172.574-.23.8h12a6.891,6.891,0,0,0,0-13.782Z" transform="translate(-101.318 -99.421)"/><path class="b" d="M107.358,124.171c.057-.574.057-1.206.057-1.78s0-1.206-.057-1.78a21.106,21.106,0,0,0-.747-4.307c-.057-.287-.172-.574-.23-.8H87.834a23.487,23.487,0,0,0,0,13.782h18.548c.057-.287.172-.574.23-.8A21.107,21.107,0,0,0,107.358,124.171Z" transform="translate(-86.8 -99.421)"/><path class="c" d="M128.072,143.5h-14.93a23.6,23.6,0,0,1-1.55,2.929,22.29,22.29,0,0,1-3.043,3.9c-.4.4-.8.747-1.206,1.148a22.846,22.846,0,0,1-2.642,2.01,22.725,22.725,0,0,0,12.633,3.79,23.018,23.018,0,0,0,19.122-10.221A11.712,11.712,0,0,0,128.072,143.5Z" transform="translate(-94.421 -111.343)"/><path class="d" d="M105.375,146.429a23.6,23.6,0,0,0,1.55-2.929H90.1a22.705,22.705,0,0,0,8.441,9.992,29.127,29.127,0,0,0,2.641-2.01c.4-.345.8-.747,1.206-1.148a22.635,22.635,0,0,0,2.986-3.9Z" transform="translate(-88.205 -111.343)"/><path class="e" d="M102.289,97.258c-.4-.4-.8-.747-1.206-1.148a22.847,22.847,0,0,0-2.641-2.01A23.475,23.475,0,0,0,90,104.092h16.825a23.6,23.6,0,0,0-1.55-2.929A18.059,18.059,0,0,0,102.289,97.258Z" transform="translate(-88.162 -90.31)"/><path class="f" d="M117.333,87.5A22.725,22.725,0,0,0,104.7,91.29a29.13,29.13,0,0,1,2.642,2.01c.4.345.8.747,1.206,1.148a22.29,22.29,0,0,1,3.043,3.9,23.605,23.605,0,0,1,1.55,2.929h14.93a11.712,11.712,0,0,0,8.384-3.56A23.018,23.018,0,0,0,117.333,87.5Z" transform="translate(-94.421 -87.5)"/></svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
1
portal-ui/build/gcs-logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64"><path d="M40.728 20.488l2.05.035 5.57-5.57.27-2.36C44.2 8.657 38.367 6.26 31.993 6.26c-11.54 0-21.28 7.852-24.163 18.488.608-.424 1.908-.106 1.908-.106l11.13-1.83s.572-.947.862-.9A13.88 13.88 0 0 1 32 17.375c3.3.007 6.34 1.173 8.728 3.102z" fill="#ea4335"/><path d="M56.17 24.77c-1.293-4.77-3.958-8.982-7.555-12.177l-7.887 7.887c3.16 2.55 5.187 6.452 5.187 10.82v1.392c3.837 0 6.954 3.124 6.954 6.954 0 3.837-3.124 6.954-6.954 6.954H32.007L30.615 48v8.346l1.392 1.385h13.908A18.11 18.11 0 0 0 64 39.647c-.007-6.155-3.1-11.6-7.83-14.876z" fill="#4285f4"/><path d="M18.085 57.74h13.9V46.6h-13.9a6.89 6.89 0 0 1-2.862-.622l-2.007.615-5.57 5.57-.488 1.88a18 18 0 0 0 10.926 3.689z" fill="#34a853"/><path d="M18.085 21.57A18.11 18.11 0 0 0 0 39.654c0 5.873 2.813 11.095 7.166 14.403l8.064-8.064a6.96 6.96 0 0 1-4.099-6.339c0-3.837 3.124-6.954 6.954-6.954 2.82 0 5.244 1.7 6.34 4.1l8.064-8.064c-3.307-4.353-8.53-7.166-14.403-7.166z" fill="#fbbc05"/></svg>
|
||||
|
After Width: | Height: | Size: 1012 B |
11
portal-ui/build/images/object-browser-folder-icn.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="28.141" height="23.33" viewBox="0 0 28.141 23.33">
|
||||
<g id="object-browser-folder-icn" transform="translate(3875.698 1391.955)">
|
||||
<g id="Grupo_1541" data-name="Grupo 1541" transform="translate(-3866.02 -1382.94)">
|
||||
<circle id="Elipse_57" data-name="Elipse 57" cx="1.268" cy="1.268" r="1.268" transform="translate(4.275 5.49) rotate(-10.901)"/>
|
||||
<rect id="Rectángulo_805" data-name="Rectángulo 805" width="2.707" height="2.295" rx="1.148" transform="translate(1.601 2.812)"/>
|
||||
<path id="Trazado_365" data-name="Trazado 365" d="M-3848.674-1356.694a.267.267,0,0,0-.463,0l-1,1.735a.267.267,0,0,0,.231.4h2a.267.267,0,0,0,.232-.4Z" transform="translate(3851.773 1363.331)"/>
|
||||
<path id="Trazado_366" data-name="Trazado 366" d="M-3845.066-1368.444a16.588,16.588,0,0,0-.021-1.927,1.119,1.119,0,0,0-.717-1.042,1.734,1.734,0,0,0-.2-.058,4.224,4.224,0,0,0-.807-.073c-.472-.014-.943.015-1.415.013-.945,0-1.889.013-2.834.017h-2.037a.694.694,0,0,0-.693.693v8.874a.694.694,0,0,0,.693.693h7.34a.694.694,0,0,0,.693-.693v-4.421C-3845.065-1367.059-3845.083-1367.754-3845.066-1368.444Zm-.842,5.871a.6.6,0,0,1-.6.6h-5.967a.6.6,0,0,1-.6-.6v-7.621a.6.6,0,0,1,.6-.6h4v1.024a1.52,1.52,0,0,0,1.518,1.518h1.043Zm0-6.34h-1.043a.857.857,0,0,1-.856-.856v-1.024h1.3a.6.6,0,0,1,.6.6Z" transform="translate(3853.792 1371.548)"/>
|
||||
</g>
|
||||
<path id="Trazado_367" data-name="Trazado 367" d="M-3864.516-1389.746c.726,0,1.5,2.076,2.283,2.076h9.68a1.041,1.041,0,0,1,1.038,1.038v.519h-19.748v-2.595h-.026a1.041,1.041,0,0,1,1.038-1.038h5.735m13.674,4.9a1.079,1.079,0,0,1,1.076,1.076l-1.1,11.862a1.079,1.079,0,0,1-1.076,1.076h-19.393a1.079,1.079,0,0,1-1.076-1.076l-1.076-11.862a1.079,1.079,0,0,1,1.076-1.076h21.571m-13.674-7.108h-5.735a3.25,3.25,0,0,0-3.247,3.247,2.22,2.22,0,0,0,.026.339v1.487a3.291,3.291,0,0,0-2.227,3.11c0,.067,0,.133.009.2l1.069,11.788a3.288,3.288,0,0,0,3.282,3.158h19.393a3.288,3.288,0,0,0,3.282-3.155l1.1-11.786c.006-.068.009-.136.009-.2a3.288,3.288,0,0,0-1.749-2.9,3.251,3.251,0,0,0-3.247-3.2h-8.959l-.124-.167a3.694,3.694,0,0,0-2.88-1.909Z" transform="translate(0 0)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
6
portal-ui/build/images/object-browser-icn.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg id="object-browser-icn" xmlns="http://www.w3.org/2000/svg" width="11.502" height="13.542" viewBox="0 0 11.502 13.542">
|
||||
<circle id="Elipse_55" data-name="Elipse 55" cx="1.667" cy="1.667" r="1.667" transform="translate(5.623 7.221) rotate(-10.901)"/>
|
||||
<rect id="Rectángulo_797" data-name="Rectángulo 797" width="3.561" height="3.019" rx="1.51" transform="translate(2.105 3.699)"/>
|
||||
<path id="Trazado_322" data-name="Trazado 322" d="M-4332.738-1202.411a.352.352,0,0,0-.609,0l-1.317,2.282a.352.352,0,0,0,.3.527h2.635a.352.352,0,0,0,.3-.527Z" transform="translate(4336.814 1211.141)"/>
|
||||
<path id="Trazado_323" data-name="Trazado 323" d="M-4328.313-1219.174a22.083,22.083,0,0,0-.027-2.536,1.472,1.472,0,0,0-.943-1.371,2.294,2.294,0,0,0-.266-.077,5.586,5.586,0,0,0-1.063-.095c-.62-.018-1.24.019-1.86.017-1.243-.005-2.486.017-3.729.022h-2.68a.913.913,0,0,0-.912.912v11.674a.913.913,0,0,0,.912.912h9.656a.912.912,0,0,0,.912-.912v-5.816C-4328.312-1217.353-4328.335-1218.266-4328.313-1219.174Zm-1.107,7.722a.788.788,0,0,1-.787.788h-7.849a.787.787,0,0,1-.787-.788v-10.025a.787.787,0,0,1,.787-.788h5.266v1.347a2,2,0,0,0,2,2h1.373Zm0-8.339h-1.373a1.128,1.128,0,0,1-1.126-1.127v-1.347h1.712a.788.788,0,0,1,.787.788Z" transform="translate(4339.792 1223.257)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
6
portal-ui/build/images/trash-icn.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="9.836" height="12.646" viewBox="0 0 9.836 12.646">
|
||||
<g id="trash-icn" transform="translate(2222 1227)">
|
||||
<path id="Trazado_359" data-name="Trazado 359" d="M-2212.473-1226.3h-2.5v-.395a.308.308,0,0,0-.308-.308h-3.6a.308.308,0,0,0-.308.308v.395h-2.5a.309.309,0,0,0-.309.309v.787a.309.309,0,0,0,.309.309h9.218a.309.309,0,0,0,.309-.309v-.787A.309.309,0,0,0-2212.473-1226.3Z"/>
|
||||
<path id="Trazado_360" data-name="Trazado 360" d="M-2221-1214.585a1.425,1.425,0,0,0,1.42,1.421h5.59a1.425,1.425,0,0,0,1.42-1.421V-1223H-2221Z" transform="translate(-0.297 -1.19)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 623 B |
@@ -1 +1 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="MinIO Console"/><link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700;900&display=swap" rel="stylesheet"/><link href="./styles/root-styles.css" rel="stylesheet"/><link rel="apple-touch-icon" sizes="180x180" href="./apple-icon-180x180.png"/><link rel="icon" type="image/png" sizes="32x32" href="./favicon-32x32.png"/><link rel="icon" type="image/png" sizes="96x96" href="./favicon-96x96.png"/><link rel="icon" type="image/png" sizes="16x16" href="./favicon-16x16.png"/><link rel="manifest" href="./manifest.json"/><link rel="mask-icon" href="./safari-pinned-tab.svg" color="#3a4e54"/><title>MinIO Console</title><link href="./static/css/2.60e04a19.chunk.css" rel="stylesheet"><link href="./static/css/main.8cfac526.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"><div id="loader-block"><svg class="loader-svg-container" viewBox="22 22 44 44"><circle class="loader-style MuiCircularProgress-circle MuiCircularProgress-circleIndeterminate" cx="44" cy="44" r="20.2" fill="none" stroke-width="3.6"></circle></svg></div></div><script>!function(e){function r(r){for(var n,l,i=r[0],a=r[1],p=r[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var a=t[i];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="./";var i=this["webpackJsonpportal-ui"]=this["webpackJsonpportal-ui"]||[],a=i.push.bind(i);i.push=r,i=i.slice();for(var p=0;p<i.length;p++)r(i[p]);var f=a;t()}([])</script><script src="./static/js/2.147ecdb8.chunk.js"></script><script src="./static/js/main.30880e75.chunk.js"></script></body></html>
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#081C42" media="(prefers-color-scheme: light)"/><meta name="theme-color" content="#081C42" media="(prefers-color-scheme: dark)"/><meta name="description" content="MinIO Console"/><link href="./styles/root-styles.css" rel="stylesheet"/><link rel="apple-touch-icon" sizes="180x180" href="./apple-icon-180x180.png"/><link rel="icon" type="image/png" sizes="32x32" href="./favicon-32x32.png"/><link rel="icon" type="image/png" sizes="96x96" href="./favicon-96x96.png"/><link rel="icon" type="image/png" sizes="16x16" href="./favicon-16x16.png"/><link rel="manifest" href="./manifest.json"/><link rel="mask-icon" href="./safari-pinned-tab.svg" color="#3a4e54"/><title>MinIO Console</title><link href="./static/css/2.5c96c0d7.chunk.css" rel="stylesheet"><link href="./static/css/main.e33a67ba.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"><div id="loader-block"><svg class="loader-svg-container" viewBox="22 22 44 44"><circle class="loader-style MuiCircularProgress-circle MuiCircularProgress-circleIndeterminate" cx="44" cy="44" r="20.2" fill="none" stroke-width="3.6"></circle></svg></div></div><script>!function(e){function r(r){for(var n,l,i=r[0],a=r[1],p=r[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var a=t[i];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="./";var i=this["webpackJsonpportal-ui"]=this["webpackJsonpportal-ui"]||[],a=i.push.bind(i);i.push=r,i=i.slice();for(var p=0;p<i.length;p++)r(i[p]);var f=a;t()}([])</script><script src="./static/js/2.edb168ed.chunk.js"></script><script src="./static/js/main.0d2bb0ae.chunk.js"></script></body></html>
|
||||
1
portal-ui/build/kafka-logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32.752" height="53.177" viewBox="0 0 32.752 53.177"><defs><style>.a{fill:#2a2a2a;}</style></defs><path class="a" d="M25.82,29.454a6.911,6.911,0,0,0-5.2,2.362l-3.258-2.306a8.786,8.786,0,0,0,.018-6.039l3.25-2.282a6.915,6.915,0,1,0-1.456-2.614l-3.253,2.283a8.948,8.948,0,0,0-5.544-3.222v-3.92A6.943,6.943,0,1,0,7.4,13.683v3.971a8.943,8.943,0,0,0,.062,17.63v4.193a6.932,6.932,0,1,0,2.976,0V35.285a8.951,8.951,0,0,0,5.45-3.17l3.279,2.321a6.93,6.93,0,1,0,6.648-4.982Zm0-16.209a3.361,3.361,0,1,1-3.361,3.361,3.365,3.365,0,0,1,3.361-3.361ZM5.593,6.932a3.361,3.361,0,1,1,3.361,3.361A3.365,3.365,0,0,1,5.593,6.932Zm6.722,39.313a3.361,3.361,0,1,1-3.361-3.361A3.365,3.365,0,0,1,12.315,46.245ZM8.954,31.152a4.688,4.688,0,1,1,4.688-4.687A4.693,4.693,0,0,1,8.954,31.152ZM25.82,39.747a3.361,3.361,0,1,1,3.361-3.361A3.365,3.365,0,0,1,25.82,39.747Z"/></svg>
|
||||
|
After Width: | Height: | Size: 886 B |
1
portal-ui/build/lambda-rect.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="229" height="80" viewBox="0 0 229 80"><defs><style>.a,.c{fill:none;}.a{stroke:#e5e5e5;}.b{stroke:none;}</style></defs><g class="a"><rect class="b" width="229" height="80" rx="10"/><rect class="c" x="0.5" y="0.5" width="228" height="79" rx="9.5"/></g></svg>
|
||||
|
After Width: | Height: | Size: 303 B |
1
portal-ui/build/minio-logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 162.612 24.465" xmlns:v="https://vecta.io/nano"><path d="M52.751.414h9.108v23.63h-9.108zM41.711.74l-18.488 9.92a.919.919 0 0 1-.856 0L3.879.74A2.808 2.808 0 0 0 2.558.414h-.023A2.4 2.4 0 0 0 0 2.641v21.376h9.1V13.842a.918.918 0 0 1 1.385-.682l10.361 5.568a3.634 3.634 0 0 0 3.336.028l10.933-5.634a.917.917 0 0 1 1.371.69v10.205h9.1V2.641A2.4 2.4 0 0 0 43.055.414h-.023a2.808 2.808 0 0 0-1.321.326zm65.564-.326h-9.237v10.755a.913.913 0 0 1-1.338.706L72.762.675a2.824 2.824 0 0 0-1.191-.261h-.016a2.4 2.4 0 0 0-2.535 2.227v21.377h9.163V13.275a.914.914 0 0 1 1.337-.707l24.032 11.2a2.813 2.813 0 0 0 1.188.26 2.4 2.4 0 0 0 2.535-2.227zm7.161 23.63V.414h4.191v23.63zm28.856.421c-11.274 0-19.272-4.7-19.272-12.232C124.02 4.741 132.066 0 143.292 0s19.32 4.7 19.32 12.233-7.902 12.232-19.32 12.232zm0-21.333c-8.383 0-14.84 3.217-14.84 9.1 0 5.926 6.457 9.1 14.84 9.1s14.887-3.174 14.887-9.1c0-5.883-6.504-9.1-14.887-9.1z" fill="#c72c48"/></svg>
|
||||
|
After Width: | Height: | Size: 990 B |
1
portal-ui/build/mqtt-logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="45.923" height="45.923" viewBox="0 0 45.923 45.923"><defs><style>.a{fill:#fff;}.b{fill:#606;}</style></defs><path class="a" d="M46,25.927v7.016h.136A34.792,34.792,0,0,1,80.969,67.3h6.813A41.859,41.859,0,0,0,46,25.927Zm0,14.485v7.016h.136A20.246,20.246,0,0,1,66.393,67.3h6.813A27.3,27.3,0,0,0,46,40.412Zm45.9,8.737V35a60.59,60.59,0,0,0-6.043-7.2A59.1,59.1,0,0,0,77.936,21.4H62.907A49.439,49.439,0,0,1,91.9,49.149Z" transform="translate(-45.977 -21.4)"/><path class="b" d="M46.036,47.428H45.9V64.992A2.318,2.318,0,0,0,48.209,67.3H66.293A20.231,20.231,0,0,0,46.036,47.428Zm0-14.485H45.9v7.469A27.283,27.283,0,0,1,73.105,67.3h7.741a34.743,34.743,0,0,0-34.81-34.358ZM91.823,65.015V49.149A49.463,49.463,0,0,0,62.852,21.4H48.209A2.318,2.318,0,0,0,45.9,23.709v2.241A41.8,41.8,0,0,1,87.659,67.323h1.856a2.318,2.318,0,0,0,2.309-2.309ZM85.78,27.805A64.821,64.821,0,0,1,91.823,35V23.686A2.279,2.279,0,0,0,89.537,21.4H77.881A57.512,57.512,0,0,1,85.78,27.805Z" transform="translate(-45.9 -21.4)"/></svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
1
portal-ui/build/mysql-logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="50.771" height="49.812" viewBox="0 0 50.771 49.812"><defs><style>.a,.b{fill:#0e698f;}.b{fill-rule:evenodd;}</style></defs><path class="a" d="M289.628,38.55a15.85,15.85,0,0,0-6.693.945c-.514.217-1.333.222-1.417.867.282.3.326.738.551,1.1a8.687,8.687,0,0,0,1.811,2.126c.711.537,1.443,1.11,2.205,1.575,1.355.826,2.868,1.3,4.174,2.126.769.488,1.533,1.1,2.284,1.653.371.272.62.7,1.1.867v-.079c-.253-.322-.319-.766-.551-1.1l-1.024-1.024a16.8,16.8,0,0,0-3.622-3.465c-1.077-.773-3.488-1.817-3.937-3.071l-.079-.079a17.361,17.361,0,0,0,2.363-.551c1.184-.318,2.242-.236,3.465-.552l1.654-.473V39.1c-.618-.634-1.059-1.474-1.733-2.047a50.482,50.482,0,0,0-5.669-4.253c-1.1-.694-2.458-1.145-3.622-1.733-.392-.2-1.081-.3-1.339-.63a16.691,16.691,0,0,1-1.417-2.678c-.988-1.9-1.959-3.982-2.835-5.985a32.281,32.281,0,0,0-1.732-3.937A34.779,34.779,0,0,0,260.176,4.923a16.041,16.041,0,0,0-4.41-1.417l-2.6-.158a13.841,13.841,0,0,1-1.575-1.181c-1.975-1.248-7.041-3.962-8.5-.394-.924,2.252,1.381,4.45,2.2,5.592a16.886,16.886,0,0,1,1.732,2.6c.272.592.319,1.185.551,1.811a41.587,41.587,0,0,0,1.811,4.646,16.425,16.425,0,0,0,1.26,2.126c.29.4.787.57.866,1.182a9.624,9.624,0,0,0-.787,2.6c-1.231,3.881-.767,8.7,1.024,11.577.549.882,1.843,2.773,3.622,2.047,1.556-.634,1.209-2.6,1.654-4.331.1-.393.039-.682.236-.945v.079l1.417,2.835a19.3,19.3,0,0,0,4.489,4.646c.818.618,1.462,1.686,2.52,2.047V40.2h-.079c-.2-.319-.526-.452-.787-.709a18.044,18.044,0,0,1-1.811-2.047,47.913,47.913,0,0,1-3.859-6.3c-.552-1.06-1.031-2.229-1.5-3.308-.179-.416-.177-1.044-.551-1.26a15.749,15.749,0,0,0-1.654,2.363,20.226,20.226,0,0,0-.945,5.2c-.138.049-.077.015-.158.079-1.1-.265-1.482-1.394-1.89-2.362a14.886,14.886,0,0,1-.316-9.214c.235-.73,1.3-3.028.867-3.7-.2-.673-.881-1.062-1.26-1.575a12.4,12.4,0,0,1-1.26-2.205c-.844-1.91-1.238-4.054-2.126-5.985A17.477,17.477,0,0,0,246.631,6.5a15.612,15.612,0,0,1-1.89-2.678c-.18-.39-.425-1.016-.158-1.417a.625.625,0,0,1,.473-.473c.457-.352,1.729.117,2.2.315a19.2,19.2,0,0,1,3.387,1.732c.514.341,1.033,1,1.654,1.182h.709c1.109.255,2.351.079,3.386.394a20.465,20.465,0,0,1,4.961,2.363,30.711,30.711,0,0,1,10.789,11.813c.408.783.585,1.531.945,2.363.726,1.676,1.64,3.4,2.362,5.04a23.549,23.549,0,0,0,2.441,4.646c.536.715,2.6,1.1,3.543,1.5a20.859,20.859,0,0,1,2.363.945c1.192.719,2.347,1.575,3.465,2.363.559.394,2.277,1.257,2.362,1.969Z" transform="translate(-242.873 0)"/><path class="b" d="M273.184,24.357a5.649,5.649,0,0,0-1.418.157v.079h.079a10.766,10.766,0,0,0,1.1,1.417l.788,1.654.078-.078a1.923,1.923,0,0,0,.709-1.732c-.2-.206-.225-.464-.394-.709C273.9,24.817,273.468,24.632,273.184,24.357Z" transform="translate(-261.629 -15.811)"/></svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
1
portal-ui/build/nats-logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="51.66" height="53.482" viewBox="0 0 51.66 53.482"><defs><style>.a{fill:#34a574;}.b{fill:#27aae1;}.c{fill:#8dc63f;}.d{fill:#375c93;}.e{fill:#fff;}</style></defs><path class="a" d="M142.8,5.3h25.83V26.24H142.8Z" transform="translate(-116.97 -5.3)"/><path class="b" d="M8.1,5.3H33.93V26.24H8.1Z" transform="translate(-8.1 -5.3)"/><path class="c" d="M142.8,114.6h25.83v20.94H142.8Z" transform="translate(-116.97 -93.641)"/><path class="d" d="M8.1,114.6H33.93v20.94H8.1Z" transform="translate(-8.1 -93.641)"/><path class="c" d="M123,223.2l12.637,11.7V223.2Z" transform="translate(-100.967 -181.416)"/><path class="d" d="M126.312,222.8l.134,3.682L122.4,222.7Z" transform="translate(-100.482 -181.012)"/><path class="e" d="M79.465,73.435V56.1H85.64V78.517H76.282L57.394,60.875V78.536H51.2V56.1h9.684Z" transform="translate(-42.935 -46.359)"/></svg>
|
||||
|
After Width: | Height: | Size: 888 B |
1
portal-ui/build/nsq-logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="50.821" height="50.82" viewBox="0 0 50.821 50.82"><defs><style>.a{fill:#38bef2;}</style></defs><path class="a" d="M24.482,50.438l-9.431-9.431A3.931,3.931,0,0,1,9.814,35.77L.386,26.342a1.317,1.317,0,0,1,0-1.864l9.427-9.426a3.931,3.931,0,0,1,5.237-5.237L24.479.386a1.317,1.317,0,0,1,1.862,0L35.77,9.814a3.931,3.931,0,0,1,5.237,5.237l9.428,9.428a1.316,1.316,0,0,1,0,1.864L41.007,35.77a3.931,3.931,0,0,1-5.237,5.237l-9.429,9.428a1.32,1.32,0,0,1-1.86,0ZM16.965,35.869a3.871,3.871,0,0,1,.337,1.583,3.922,3.922,0,0,1-.44,1.8L25.411,47.8l8.549-8.549a3.907,3.907,0,0,1-.035-3.535L25.369,27.2Zm19.074,1.583a1.413,1.413,0,1,0,1.413-1.413A1.415,1.415,0,0,0,36.039,37.453Zm-24.084,0a1.413,1.413,0,1,0,1.413-1.413A1.415,1.415,0,0,0,11.955,37.453Zm3.3-3.444,7.077-7.3H17.079a3.981,3.981,0,0,1-1.34,1.836,3.923,3.923,0,0,1-4.742,0,3.982,3.982,0,0,1-1.34-1.836H4.32l7.248,7.248a3.9,3.9,0,0,1,3.691.049Zm23.994-.049L46.5,26.711H41.215a3.97,3.97,0,0,1-1.322,1.946,3.915,3.915,0,0,1-4.88,0,3.969,3.969,0,0,1-1.322-1.946H28.446L35.7,33.932a3.906,3.906,0,0,1,3.55.027Zm-3.214-8.384a1.413,1.413,0,1,0,1.413-1.413A1.415,1.415,0,0,0,36.039,25.575Zm-24.084-.165A1.413,1.413,0,1,0,13.368,24,1.415,1.415,0,0,0,11.955,25.411Zm27.831-3a3.956,3.956,0,0,1,1.346,1.779h5.449l-7.329-7.328a3.905,3.905,0,0,1-3.767-.089L28.292,24.19h5.48a3.929,3.929,0,0,1,6.014-1.779ZM15.773,22.3A3.977,3.977,0,0,1,17.1,24.19h5.235l-7.3-7.263a3.9,3.9,0,0,1-3.472-.066L4.24,24.19H9.633A3.976,3.976,0,0,1,10.964,22.3a3.919,3.919,0,0,1,4.808,0Zm1.089-10.733a3.9,3.9,0,0,1-.006,3.61l8.481,8.438,8.484-8.748a3.876,3.876,0,0,1-.3-1.5,3.919,3.919,0,0,1,.441-1.8L25.411,3.019Zm19.178,1.8a1.413,1.413,0,1,0,1.413-1.413A1.415,1.415,0,0,0,36.039,13.368Zm-24.084,0a1.413,1.413,0,1,0,1.413-1.413A1.415,1.415,0,0,0,11.955,13.368Z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
1
portal-ui/build/postgres-logo.svg
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
1
portal-ui/build/redis-logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="49.23" height="42.194" viewBox="0 0 49.23 42.194"><defs><style>.a{fill:#a41e11;}.b{fill:#d82c20;}.c{fill:#fff;}.d{fill:#7a0c00;}.e{fill:#ad2115;}</style></defs><path class="a" d="M218.623,310.094c-2.627,1.369-16.236,6.965-19.134,8.475s-4.507,1.5-6.8.4-16.771-6.944-19.38-8.191c-1.3-.623-1.99-1.149-1.99-1.646v-4.976s18.854-4.1,21.9-5.2,4.1-1.132,6.69-.183,18.079,3.744,20.639,4.681c0,0,0,4.444,0,4.905,0,.492-.59,1.032-1.928,1.728Z" transform="translate(-171.323 -277.559)"/><path class="b" d="M218.622,295.26c-2.627,1.369-16.236,6.965-19.134,8.475s-4.507,1.5-6.8.4-16.771-6.945-19.38-8.191-2.664-2.105-.1-3.109,16.966-6.655,20.01-7.747,4.1-1.132,6.69-.182,16.119,6.334,18.679,7.271,2.659,1.711.032,3.081Z" transform="translate(-171.322 -267.702)"/><path class="a" d="M218.623,282.054c-2.627,1.369-16.236,6.965-19.134,8.476s-4.507,1.5-6.8.4-16.771-6.944-19.38-8.191c-1.3-.623-1.99-1.149-1.99-1.645v-4.977s18.854-4.1,21.9-5.2,4.1-1.132,6.69-.183,18.079,3.743,20.639,4.681c0,0,0,4.444,0,4.906C220.551,280.818,219.96,281.358,218.623,282.054Z" transform="translate(-171.323 -257.634)"/><path class="b" d="M218.622,267.22c-2.627,1.369-16.236,6.965-19.134,8.476s-4.507,1.5-6.8.4-16.771-6.944-19.38-8.191-2.664-2.105-.1-3.109,16.966-6.654,20.01-7.746,4.1-1.132,6.69-.183,16.119,6.333,18.679,7.271,2.659,1.711.032,3.081Z" transform="translate(-171.322 -247.777)"/><path class="a" d="M218.623,252.976c-2.627,1.369-16.236,6.965-19.134,8.476s-4.507,1.5-6.8.4-16.771-6.944-19.38-8.191c-1.3-.623-1.99-1.149-1.99-1.645V247.04s18.854-4.1,21.9-5.2,4.1-1.132,6.69-.183,18.079,3.743,20.639,4.681c0,0,0,4.444,0,4.906,0,.491-.59,1.031-1.928,1.728Z" transform="translate(-171.323 -236.97)"/><path class="b" d="M218.622,238.141c-2.627,1.369-16.236,6.965-19.134,8.476s-4.507,1.5-6.8.4-16.771-6.944-19.38-8.191-2.664-2.105-.1-3.109,16.966-6.654,20.01-7.746,4.1-1.132,6.69-.182,16.119,6.333,18.679,7.271,2.659,1.711.032,3.08Z" transform="translate(-171.322 -227.113)"/><path class="c" d="M249.968,239.756l-4.266.443-.955,2.3-1.542-2.564-4.925-.443,3.675-1.325-1.1-2.034,3.441,1.346,3.244-1.062-.877,2.1Z" transform="translate(-218.903 -233.521)"/><path class="c" d="M240.2,274.773l-7.961-3.3,11.408-1.751Z" transform="translate(-214.611 -257.39)"/><ellipse class="c" cx="6.097" cy="2.363" rx="6.097" ry="2.363" transform="translate(8.456 7.513)"/><path class="d" d="M296.09,250.83l6.751,2.668-6.746,2.665Z" transform="translate(-259.984 -243.967)"/><path class="e" d="M270.28,253.785l7.469-2.955.006,5.333-.732.286Z" transform="translate(-241.643 -243.967)"/></svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |