Compare commits
67 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
14fe7c1269 | ||
|
|
b6938a5888 | ||
|
|
901358e8d4 | ||
|
|
5155aef802 | ||
|
|
23b3283014 | ||
|
|
53eb59f5ad | ||
|
|
e088431c62 | ||
|
|
8bb982b39f | ||
|
|
744ccea842 | ||
|
|
19195e0cd0 | ||
|
|
7ce36bac42 | ||
|
|
2a704d3d59 | ||
|
|
897b5b8be5 | ||
|
|
03dc83af3a | ||
|
|
26f7982323 | ||
|
|
934e8c9f4c | ||
|
|
e780f24fb9 | ||
|
|
c48a024310 | ||
|
|
3fcf278460 | ||
|
|
8b6202296e | ||
|
|
7030e80ac8 | ||
|
|
6bed9f8f97 | ||
|
|
e7263c9a89 | ||
|
|
9c1e87b1be | ||
|
|
6f98ecc59f | ||
|
|
ac77b8b441 | ||
|
|
d4a69978fc | ||
|
|
81087ae910 | ||
|
|
ebab2e1648 | ||
|
|
9a875a6f14 | ||
|
|
abc9f2b428 | ||
|
|
a2a09b8db1 | ||
|
|
716aabe782 | ||
|
|
07a23ab374 | ||
|
|
e7838ebc47 | ||
|
|
e6705b685c | ||
|
|
6b11d403a6 | ||
|
|
8958cbec69 | ||
|
|
5ef66c3cfc | ||
|
|
d4395e1409 | ||
|
|
8a4139c8e7 | ||
|
|
34bcd25c9f | ||
|
|
7853aa6bb9 | ||
|
|
9c1f0c47b0 | ||
|
|
6ac95e40a4 | ||
|
|
70fb7291f5 | ||
|
|
4b28bf5921 | ||
|
|
99d5e71512 | ||
|
|
2a5c1afbdf | ||
|
|
51a9482e91 | ||
|
|
d01eeb43a7 | ||
|
|
7121dbfcea | ||
|
|
e5fc6e3125 | ||
|
|
396d8fbcfc | ||
|
|
f958b73e48 | ||
|
|
940c7dc5bc | ||
|
|
cdadb05551 | ||
|
|
1dcdc61ce8 | ||
|
|
7174892231 | ||
|
|
3262212bd0 | ||
|
|
ee1a6718d7 | ||
|
|
1c6a29bc20 | ||
|
|
6b02f472e6 | ||
|
|
eddb6a810b | ||
|
|
3b1449c029 | ||
|
|
365778eecb | ||
|
|
52fac7f542 |
2
.github/workflows/go.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.15.x]
|
||||
go-version: [1.16.x]
|
||||
os: [ubuntu-latest]
|
||||
steps:
|
||||
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
|
||||
|
||||
1
.gitignore
vendored
@@ -27,7 +27,6 @@ dist/
|
||||
# Ignore node_modules
|
||||
|
||||
portal-ui/node_modules/
|
||||
portal-ui/build/
|
||||
|
||||
# Ignore tls cert and key
|
||||
private.key
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
project_name: console
|
||||
|
||||
release:
|
||||
name_template: "Release version {{.Version}}"
|
||||
name_template: "Release version {{.Tag}}"
|
||||
github:
|
||||
owner: minio
|
||||
name: console
|
||||
@@ -27,8 +27,6 @@ builds:
|
||||
- s390x
|
||||
- arm64
|
||||
ignore:
|
||||
- goos: darwin
|
||||
goarch: arm64
|
||||
- goos: darwin
|
||||
goarch: arm
|
||||
- goos: windows
|
||||
@@ -80,11 +78,16 @@ nfpms:
|
||||
formats:
|
||||
- deb
|
||||
- rpm
|
||||
contents:
|
||||
# Basic file that applies to all packagers
|
||||
- src: systemd/console.service
|
||||
dst: /etc/systemd/system/minio-console.service
|
||||
|
||||
dockers:
|
||||
- image_templates:
|
||||
- "minio/console:{{ .Tag }}-amd64"
|
||||
use_buildx: true
|
||||
goarch: amd64
|
||||
dockerfile: Dockerfile.release
|
||||
extra_files:
|
||||
- LICENSE
|
||||
@@ -94,6 +97,7 @@ dockers:
|
||||
- image_templates:
|
||||
- "minio/console:{{ .Tag }}-ppc64le"
|
||||
use_buildx: true
|
||||
goarch: ppc64le
|
||||
dockerfile: Dockerfile.release
|
||||
extra_files:
|
||||
- LICENSE
|
||||
@@ -103,6 +107,7 @@ dockers:
|
||||
- image_templates:
|
||||
- "minio/console:{{ .Tag }}-s390x"
|
||||
use_buildx: true
|
||||
goarch: s390x
|
||||
dockerfile: Dockerfile.release
|
||||
extra_files:
|
||||
- LICENSE
|
||||
@@ -113,6 +118,7 @@ dockers:
|
||||
- "minio/console:{{ .Tag }}-arm64"
|
||||
use_buildx: true
|
||||
goarch: arm64
|
||||
goos: linux
|
||||
dockerfile: Dockerfile.release
|
||||
extra_files:
|
||||
- LICENSE
|
||||
|
||||
73
CREDITS
@@ -2836,35 +2836,6 @@ Everyone is permitted to copy and distribute copies of this Agreement, but in or
|
||||
This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
|
||||
================================================================
|
||||
|
||||
github.com/elazarl/go-bindata-assetfs
|
||||
https://github.com/elazarl/go-bindata-assetfs
|
||||
----------------------------------------------------------------
|
||||
Copyright (c) 2014, Elazar Leibovich
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
================================================================
|
||||
|
||||
github.com/evanphx/json-patch
|
||||
https://github.com/evanphx/json-patch
|
||||
----------------------------------------------------------------
|
||||
@@ -13173,28 +13144,28 @@ SOFTWARE.
|
||||
github.com/klauspost/readahead
|
||||
https://github.com/klauspost/readahead
|
||||
----------------------------------------------------------------
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Klaus Post
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Klaus Post
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
================================================================
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ Run the `billy.ldif` file using `ldapadd` command to create a new user and assig
|
||||
|
||||
```
|
||||
$ docker cp console/docs/ldap/billy.ldif my-openldap-container:/container/service/slapd/assets/test/billy.ldif
|
||||
$ docker exec my-openldap-container ldapadd -x -D "cn=admin,dc=example,dc=org" -w admin -f /container/service/slapd/assets/test/billy.ldif -H ldap://localhost -ZZ
|
||||
$ docker exec my-openldap-container ldapadd -x -D "cn=admin,dc=example,dc=org" -w admin -f /container/service/slapd/assets/test/billy.ldif -H ldap://localhost
|
||||
```
|
||||
|
||||
Query the ldap server to check the user billy was created correctly and got assigned to the consoleAdmin group, you should get a list
|
||||
@@ -67,7 +67,7 @@ $ cat > consoleAdmin.json << EOF
|
||||
}
|
||||
EOF
|
||||
$ mc admin policy add myminio consoleAdmin consoleAdmin.json
|
||||
$ mc admin policy set myminio consoleAdmin user=billy
|
||||
$ mc admin policy set myminio consoleAdmin user="uid=billy,dc=example,dc=org"
|
||||
```
|
||||
|
||||
## Run MinIO
|
||||
|
||||
11
Dockerfile
@@ -1,14 +1,7 @@
|
||||
FROM golang:1.15 as binlayer
|
||||
|
||||
RUN go get github.com/go-bindata/go-bindata/... && go get github.com/elazarl/go-bindata-assetfs/...
|
||||
|
||||
FROM node:10 as uilayer
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=binlayer /go/bin/go-bindata-assetfs /bin/
|
||||
COPY --from=binlayer /go/bin/go-bindata /bin/
|
||||
|
||||
COPY ./portal-ui/package.json ./
|
||||
COPY ./portal-ui/yarn.lock ./
|
||||
RUN yarn install
|
||||
@@ -19,7 +12,7 @@ RUN yarn install && make build-static
|
||||
|
||||
USER node
|
||||
|
||||
FROM golang:1.15 as golayer
|
||||
FROM golang:1.16 as golayer
|
||||
|
||||
RUN apt-get update -y && apt-get install -y ca-certificates
|
||||
|
||||
@@ -33,8 +26,6 @@ RUN go mod download
|
||||
ADD . /go/src/github.com/minio/console/
|
||||
WORKDIR /go/src/github.com/minio/console/
|
||||
|
||||
COPY --from=uilayer /app/bindata_assetfs.go /go/src/github.com/minio/console/portal-ui/bindata_assetfs.go
|
||||
|
||||
ENV CGO_ENABLED=0
|
||||
|
||||
RUN go build -ldflags "-w -s" -a -o console ./cmd/console
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
FROM golang:1.15 as binlayer
|
||||
|
||||
RUN go get github.com/go-bindata/go-bindata/... && go get github.com/elazarl/go-bindata-assetfs/...
|
||||
|
||||
FROM node:10 as uilayer
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=binlayer /go/bin/go-bindata-assetfs /bin/
|
||||
COPY --from=binlayer /go/bin/go-bindata /bin/
|
||||
|
||||
COPY ./portal-ui/package.json ./
|
||||
COPY ./portal-ui/yarn.lock ./
|
||||
RUN yarn install
|
||||
|
||||
@@ -6,8 +6,8 @@ COPY LICENSE /licenses/LICENSE
|
||||
LABEL name="MinIO" \
|
||||
vendor="MinIO Inc <dev@min.io>" \
|
||||
maintainer="MinIO Inc <dev@min.io>" \
|
||||
version="v0.5.2" \
|
||||
release="v0.5.2" \
|
||||
version="v0.6.6" \
|
||||
release="v0.6.6" \
|
||||
summary="A graphical user interface for MinIO" \
|
||||
description="MinIO object storage is fundamentally different. Designed for performance and the S3 API, it is 100% open-source. MinIO is ideal for large, private cloud environments with stringent security requirements and delivers mission-critical availability across a diverse range of workloads."
|
||||
|
||||
|
||||
2
Makefile
@@ -3,7 +3,7 @@ GOPATH := $(shell go env GOPATH)
|
||||
# Sets the build version based on the output of the following command, if we are building for a tag, that's the build else it uses the current git branch as the build
|
||||
BUILD_VERSION:=$(shell git describe --exact-match --tags $(git log -n1 --pretty='%h') 2>/dev/null || git rev-parse --abbrev-ref HEAD 2>/dev/null)
|
||||
BUILD_TIME:=$(shell date 2>/dev/null)
|
||||
TAG ?= "minio/console:$(VERSION)-dev"
|
||||
TAG ?= "minio/console:$(BUILD_VERSION)-dev"
|
||||
|
||||
default: console
|
||||
|
||||
|
||||
51
README.md
@@ -12,25 +12,61 @@ A graphical user interface for [MinIO](https://github.com/minio/minio)
|
||||
**Table of Contents**
|
||||
|
||||
- [MinIO Console](#minio-console)
|
||||
- [-](#-)
|
||||
- [Install](#install)
|
||||
- [Binary Releases](#binary-releases)
|
||||
- [Docker](#docker)
|
||||
- [Build from source](#build-from-source)
|
||||
- [Setup](#setup)
|
||||
- [1. Create a user `console` using `mc`](#1-create-a-user-console-using-mc)
|
||||
- [2. Create a policy for `console` with admin access to all resources (for testing)](#2-create-a-policy-for-console-with-admin-access-to-all-resources-for-testing)
|
||||
- [3. Set the policy for the new `console` user](#3-set-the-policy-for-the-new-console-user)
|
||||
- [Start Console service:](#start-console-service)
|
||||
- [Salt to encrypt JWT payload](#salt-to-encrypt-jwt-payload)
|
||||
- [Start Console service with TLS:](#start-console-service-with-tls)
|
||||
- [Connect Console to a Minio using TLS and a self-signed certificate](#connect-console-to-a-minio-using-tls-and-a-self-signed-certificate)
|
||||
- [Contribute to console Project](#contribute-to-console-project)
|
||||
|
||||
<!-- markdown-toc end -->
|
||||
|
||||
### Setup
|
||||
## Install
|
||||
|
||||
### Binary Releases
|
||||
|
||||
| OS | ARCH | Binary |
|
||||
|:-------:|:-------:|:----------------------------------------------------------------------------------------------------:|
|
||||
| Linux | amd64 | [linux-amd64](https://github.com/minio/console/releases/latest/download/console-linux-amd64) |
|
||||
| Linux | arm64 | [linux-arm64](https://github.com/minio/console/releases/latest/download/console-linux-arm64) |
|
||||
| Linux | ppc64le | [linux-ppc64le](https://github.com/minio/console/releases/latest/download/console-linux-ppc64le) |
|
||||
| Linux | s390x | [linux-s390x](https://github.com/minio/console/releases/latest/download/console-linux-s390x) |
|
||||
| Apple | amd64 | [darwin-amd64](https://github.com/minio/console/releases/latest/download/console-darwin-amd64) |
|
||||
| Windows | amd64 | [windows-amd64](https://github.com/minio/console/releases/latest/download/console-windows-amd64.exe) |
|
||||
|
||||
You can also verify the binary with [minisign](https://jedisct1.github.io/minisign/) by downloading the corresponding [`.minisig`](https://github.com/minio/console/releases/latest) signature file. Then run:
|
||||
```
|
||||
minisign -Vm console-<OS>-<ARCH> -P RWTx5Zr1tiHQLwG9keckT0c45M3AGeHD6IvimQHpyRywVWGbP1aVSGav
|
||||
```
|
||||
|
||||
### Docker
|
||||
|
||||
Pull the latest release via:
|
||||
```
|
||||
docker pull minio/console
|
||||
```
|
||||
|
||||
### Build from source
|
||||
|
||||
```
|
||||
GO111MODULE=on go get github.com/minio/console/cmd/console
|
||||
```
|
||||
> You will need a working Go environment. Therefore, please follow [How to install Go](https://golang.org/doc/install).
|
||||
> Minimum version required is go1.16
|
||||
|
||||
## Setup
|
||||
|
||||
All `console` needs is a MinIO user with admin privileges and URL pointing to your MinIO deployment.
|
||||
|
||||
> Note: We don't recommend using MinIO's Operator Credentials
|
||||
|
||||
#### 1. Create a user `console` using `mc`
|
||||
### 1. Create a user `console` using `mc`
|
||||
|
||||
```bash
|
||||
mc admin user add myminio/
|
||||
@@ -38,7 +74,7 @@ Enter Access Key: console
|
||||
Enter Secret Key: xxxxxxxx
|
||||
```
|
||||
|
||||
#### 2. Create a policy for `console` with admin access to all resources (for testing)
|
||||
### 2. Create a policy for `console` with admin access to all resources (for testing)
|
||||
|
||||
```sh
|
||||
cat > admin.json << EOF
|
||||
@@ -70,7 +106,7 @@ EOF
|
||||
mc admin policy add myminio/ consoleAdmin admin.json
|
||||
```
|
||||
|
||||
#### 3. Set the policy for the new `console` user
|
||||
### 3. Set the policy for the new `console` user
|
||||
|
||||
```sh
|
||||
mc admin policy set myminio consoleAdmin user=console
|
||||
@@ -173,7 +209,8 @@ Following tree structure is expected for supporting multiple domains:
|
||||
## Connect Console to a Minio using TLS and a self-signed certificate
|
||||
|
||||
Copy the MinIO `ca.crt` under `~/.console/certs/CAs`, then:
|
||||
```
|
||||
|
||||
```sh
|
||||
export CONSOLE_MINIO_SERVER=https://localhost:9000
|
||||
./console server
|
||||
```
|
||||
|
||||
12
SECURITY.md
@@ -18,13 +18,13 @@ you need access credentials for a successful exploit).
|
||||
|
||||
If you have not received a reply to your email within 48 hours or you have not heard from the security team
|
||||
for the past five days please contact the security team directly:
|
||||
- Primary security coordinator: lenin@min.io
|
||||
- Secondary coordinator: daniel@min.io, cesar@min.io
|
||||
- If you receive no response: dev@min.io
|
||||
- Primary security coordinator: lenin@min.io
|
||||
- Secondary coordinator: security@min.io
|
||||
- If you receive no response: dev@min.io
|
||||
|
||||
### Disclosure Process
|
||||
|
||||
MinIO uses the following disclosure process:
|
||||
MinIO Console uses the following disclosure process:
|
||||
|
||||
1. Once the security report is received one member of the security team tries to verify and reproduce
|
||||
the issue and determines the impact it has.
|
||||
@@ -33,8 +33,8 @@ MinIO uses the following disclosure process:
|
||||
3. Code is audited to find any potential similar problems.
|
||||
4. Fixes are prepared for the latest release.
|
||||
5. On the date that the fixes are applied a security advisory will be published on https://blog.min.io.
|
||||
Please inform us in your report email whether MinIO should mention your contribution w.r.t. fixing
|
||||
the security issue. By default MinIO will **not** publish this information to protect your privacy.
|
||||
Please inform us in your report email whether MinIO Console should mention your contribution w.r.t. fixing
|
||||
the security issue. By default MinIO Console will **not** publish this information to protect your privacy.
|
||||
|
||||
This process can take some time, especially when coordination is required with maintainers of other projects.
|
||||
Every effort will be made to handle the bug in as timely a manner as possible, however it's important that we
|
||||
|
||||
38
VULNERABILITY_REPORT.md
Normal file
@@ -0,0 +1,38 @@
|
||||
## Vulnerability Management Policy
|
||||
|
||||
This document formally describes the process of addressing and managing a
|
||||
reported vulnerability that has been found in the MinIO Console server code base,
|
||||
any directly connected ecosystem component or a direct / indirect dependency
|
||||
of the code base.
|
||||
|
||||
### Scope
|
||||
|
||||
The vulnerability management policy described in this document covers the
|
||||
process of investigating, assessing and resolving a vulnerability report
|
||||
opened by a MinIO Console employee or an external third party.
|
||||
|
||||
Therefore, it lists pre-conditions and actions that should be performed to
|
||||
resolve and fix a reported vulnerability.
|
||||
|
||||
### Vulnerability Management Process
|
||||
|
||||
The vulnerability management process requires that the vulnerability report
|
||||
contains the following information:
|
||||
|
||||
- The project / component that contains the reported vulnerability.
|
||||
- A description of the vulnerability. In particular, the type of the
|
||||
reported vulnerability and how it might be exploited. Alternatively,
|
||||
a well-established vulnerability identifier, e.g. CVE number, can be
|
||||
used instead.
|
||||
|
||||
Based on the description mentioned above, a MinIO Console engineer or security team
|
||||
member investigates:
|
||||
|
||||
- Whether the reported vulnerability exists.
|
||||
- The conditions that are required such that the vulnerability can be exploited.
|
||||
- The steps required to fix the vulnerability.
|
||||
|
||||
In general, if the vulnerability exists in one of the MinIO Console code bases
|
||||
itself - not in a code dependency - then MinIO Console will, if possible, fix
|
||||
the vulnerability or implement reasonable countermeasures such that the
|
||||
vulnerability cannot be exploited anymore.
|
||||
@@ -17,6 +17,7 @@
|
||||
package cluster
|
||||
|
||||
import (
|
||||
direct "github.com/minio/direct-csi/pkg/clientset"
|
||||
operator "github.com/minio/operator/pkg/client/clientset/versioned"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
@@ -63,3 +64,8 @@ func OperatorClient(token string) (*operator.Clientset, error) {
|
||||
func K8sClient(token string) (*kubernetes.Clientset, error) {
|
||||
return kubernetes.NewForConfig(GetK8sConfig(token))
|
||||
}
|
||||
|
||||
// DirectCSIClient returns Direct CSI client using GetK8sConfig for its config
|
||||
func DirectCSIClient(token string) (*direct.Clientset, error) {
|
||||
return direct.NewForConfig(GetK8sConfig(token))
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ VERSION:
|
||||
|
||||
var appCmds = []cli.Command{
|
||||
serverCmd,
|
||||
updateCmd,
|
||||
}
|
||||
|
||||
func newApp(name string) *cli.App {
|
||||
|
||||
@@ -17,10 +17,15 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/minio/minio/cmd/config"
|
||||
|
||||
"github.com/go-openapi/loads"
|
||||
"github.com/jessevdk/go-flags"
|
||||
@@ -57,11 +62,31 @@ var serverCmd = cli.Command{
|
||||
Value: restapi.GetTLSPort(),
|
||||
Usage: "HTTPS server port",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "tls-redirect",
|
||||
Value: restapi.GetTLSRedirect(),
|
||||
Usage: "HTTPS redirect by default",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "certs-dir",
|
||||
Value: certs.GlobalCertsCADir.Get(),
|
||||
Usage: "path to certs directory",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "tls-certificate",
|
||||
Value: "",
|
||||
Usage: "path tls certificate",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "tls-key",
|
||||
Value: "",
|
||||
Usage: "path tls key",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "tls-ca",
|
||||
Value: "",
|
||||
Usage: "path tls ca",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -116,6 +141,29 @@ func startServer(ctx *cli.Context) error {
|
||||
// load the certificates and the CAs
|
||||
restapi.GlobalRootCAs, restapi.GlobalPublicCerts, restapi.GlobalTLSCertsManager = certs.GetAllCertificatesAndCAs()
|
||||
|
||||
// TLS flags from swagger server, used to support older versions of minio-operator
|
||||
swaggerServerCertificate := ctx.String("tls-certificate")
|
||||
swaggerServerCertificateKey := ctx.String("tls-key")
|
||||
SwaggerServerCACertificate := ctx.String("tls-ca")
|
||||
// load tls cert and key from swagger server tls-certificate and tls-key flags
|
||||
if swaggerServerCertificate != "" && swaggerServerCertificateKey != "" {
|
||||
if errAddCert := certs.AddCertificate(context.Background(), restapi.GlobalTLSCertsManager, swaggerServerCertificate, swaggerServerCertificateKey); errAddCert != nil {
|
||||
log.Println(errAddCert)
|
||||
}
|
||||
if x509Certs, errParseCert := config.ParsePublicCertFile(swaggerServerCertificate); errParseCert == nil {
|
||||
if len(x509Certs) > 0 {
|
||||
restapi.GlobalPublicCerts = append(restapi.GlobalPublicCerts, x509Certs[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
// load ca cert from swagger server tls-ca flag
|
||||
if SwaggerServerCACertificate != "" {
|
||||
caCert, caCertErr := ioutil.ReadFile(SwaggerServerCACertificate)
|
||||
if caCertErr == nil {
|
||||
restapi.GlobalRootCAs.AppendCertsFromPEM(caCert)
|
||||
}
|
||||
}
|
||||
|
||||
if len(restapi.GlobalPublicCerts) > 0 {
|
||||
// If TLS certificates are provided enforce the HTTPS schema, meaning console will redirect
|
||||
// plain HTTP connections to HTTPS server
|
||||
@@ -125,11 +173,33 @@ func startServer(ctx *cli.Context) error {
|
||||
// Need to store tls-port, tls-host un config variables so secure.middleware can read from there
|
||||
restapi.TLSPort = fmt.Sprintf("%v", ctx.Int("tls-port"))
|
||||
restapi.TLSHostname = ctx.String("tls-host")
|
||||
restapi.TLSRedirect = "on"
|
||||
restapi.TLSRedirect = ctx.String("tls-redirect")
|
||||
}
|
||||
|
||||
server.ConfigureAPI()
|
||||
|
||||
// subnet license refresh process
|
||||
go func() {
|
||||
failedAttempts := 0
|
||||
for {
|
||||
if err := restapi.RefreshLicense(); err != nil {
|
||||
log.Println(err)
|
||||
failedAttempts++
|
||||
// end license refresh after 3 consecutive failed attempts
|
||||
if failedAttempts >= 3 {
|
||||
return
|
||||
}
|
||||
// wait 5 minutes and retry again
|
||||
time.Sleep(time.Minute * 5)
|
||||
continue
|
||||
}
|
||||
// if license refreshed successfully reset the counter
|
||||
failedAttempts = 0
|
||||
// try to refresh license every 24 hrs
|
||||
time.Sleep(time.Hour * 24)
|
||||
}
|
||||
}()
|
||||
|
||||
if err := server.Serve(); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
154
cmd/console/update.go
Normal file
@@ -0,0 +1,154 @@
|
||||
// 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 main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/blang/semver/v4"
|
||||
"github.com/cheggaaa/pb/v3"
|
||||
"github.com/minio/cli"
|
||||
"github.com/minio/console/pkg"
|
||||
"github.com/minio/selfupdate"
|
||||
)
|
||||
|
||||
func getUpdateTransport(timeout time.Duration) http.RoundTripper {
|
||||
var updateTransport http.RoundTripper = &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: timeout,
|
||||
KeepAlive: timeout,
|
||||
DualStack: true,
|
||||
}).DialContext,
|
||||
IdleConnTimeout: timeout,
|
||||
TLSHandshakeTimeout: timeout,
|
||||
ExpectContinueTimeout: timeout,
|
||||
DisableCompression: true,
|
||||
}
|
||||
return updateTransport
|
||||
}
|
||||
|
||||
func getUpdateReaderFromURL(u string, transport http.RoundTripper) (io.ReadCloser, int64, error) {
|
||||
clnt := &http.Client{
|
||||
Transport: transport,
|
||||
}
|
||||
req, err := http.NewRequest(http.MethodGet, u, nil)
|
||||
if err != nil {
|
||||
return nil, -1, err
|
||||
}
|
||||
|
||||
resp, err := clnt.Do(req)
|
||||
if err != nil {
|
||||
return nil, -1, err
|
||||
}
|
||||
return resp.Body, resp.ContentLength, nil
|
||||
}
|
||||
|
||||
const defaultPubKey = "RWTx5Zr1tiHQLwG9keckT0c45M3AGeHD6IvimQHpyRywVWGbP1aVSGav"
|
||||
|
||||
func getLatestRelease(tr http.RoundTripper) (string, error) {
|
||||
releaseURL := "https://api.github.com/repos/minio/console/releases/latest"
|
||||
|
||||
body, _, err := getUpdateReaderFromURL(releaseURL, tr)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("unable to access github release URL %w", err)
|
||||
}
|
||||
defer body.Close()
|
||||
|
||||
lm := make(map[string]interface{})
|
||||
if err = json.NewDecoder(body).Decode(&lm); err != nil {
|
||||
return "", err
|
||||
}
|
||||
rel, ok := lm["tag_name"].(string)
|
||||
if !ok {
|
||||
return "", errors.New("unable to find latest release tag")
|
||||
}
|
||||
return rel, nil
|
||||
}
|
||||
|
||||
// update console in-place
|
||||
var updateCmd = cli.Command{
|
||||
Name: "update",
|
||||
Usage: "update console to latest release",
|
||||
Action: updateInplace,
|
||||
}
|
||||
|
||||
func updateInplace(ctx *cli.Context) error {
|
||||
transport := getUpdateTransport(30 * time.Second)
|
||||
rel, err := getLatestRelease(transport)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
latest, err := semver.Make(strings.TrimPrefix(rel, "v"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
current, err := semver.Make(pkg.Version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if current.GTE(latest) {
|
||||
fmt.Printf("You are already running the latest version v%v.\n", pkg.Version)
|
||||
return nil
|
||||
}
|
||||
|
||||
consoleBin := fmt.Sprintf("https://github.com/minio/console/releases/download/%s/console-%s-%s", rel, runtime.GOOS, runtime.GOARCH)
|
||||
reader, length, err := getUpdateReaderFromURL(consoleBin, transport)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to fetch binary from %s: %w", consoleBin, err)
|
||||
}
|
||||
|
||||
minisignPubkey := os.Getenv("CONSOLE_MINISIGN_PUBKEY")
|
||||
if minisignPubkey == "" {
|
||||
minisignPubkey = defaultPubKey
|
||||
}
|
||||
|
||||
v := selfupdate.NewVerifier()
|
||||
if err = v.LoadFromURL(consoleBin+".minisig", minisignPubkey, transport); err != nil {
|
||||
return fmt.Errorf("unable to fetch binary signature for %s: %w", consoleBin, err)
|
||||
}
|
||||
opts := selfupdate.Options{
|
||||
Verifier: v,
|
||||
}
|
||||
|
||||
tmpl := `{{ red "Downloading:" }} {{bar . (red "[") (green "=") (red "]")}} {{speed . | rndcolor }}`
|
||||
bar := pb.ProgressBarTemplate(tmpl).Start64(length)
|
||||
barReader := bar.NewProxyReader(reader)
|
||||
if err = selfupdate.Apply(barReader, opts); err != nil {
|
||||
bar.Finish()
|
||||
if rerr := selfupdate.RollbackError(err); rerr != nil {
|
||||
return rerr
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
bar.Finish()
|
||||
fmt.Printf("Updated 'console' to latest release %s\n", rel)
|
||||
return nil
|
||||
}
|
||||
61
compose/.env
Normal file
@@ -0,0 +1,61 @@
|
||||
## PostgreSQL related variables
|
||||
|
||||
# Postgres Docker image
|
||||
POSTGRES_IMAGE=library/postgres
|
||||
|
||||
# Postgres user
|
||||
POSTGRES_USER=postgres
|
||||
|
||||
# Postgres password
|
||||
POSTGRES_PASSWORD=magical_password
|
||||
|
||||
# Postgres port number
|
||||
POSTGRES_PORT=5432
|
||||
|
||||
# Postgres data directory
|
||||
PGDATA=/data/postgres
|
||||
|
||||
|
||||
## Logsearch related variables
|
||||
|
||||
# Logsearch Docker image
|
||||
LOGSEARCH_IMAGE=minio/logsearchapi:v4.0.2
|
||||
|
||||
# Logsearch storage max
|
||||
LOGSEARCH_DISK_CAPACITY_GB=5
|
||||
|
||||
# Logsearch port number
|
||||
LOGSEARCH_PORT=8080
|
||||
|
||||
# Log retention duration
|
||||
LOGSEARCH_MAX_RETENTION_MONTHS=1
|
||||
|
||||
# Logsearch audit authentication token
|
||||
LOGSEARCH_AUDIT_AUTH_TOKEN=c6rkqjZ03ElEUKQ7MtSeYBJ8q_p3GDFPBQAQJlcbBLA=
|
||||
|
||||
# Logsearch query authentication token
|
||||
LOGSEARCH_QUERY_AUTH_TOKEN=c6rkqjZ03ElEUKQ7MtSeYBJ8q_p3GDFPBQAQJlcbBLA=
|
||||
|
||||
|
||||
## Console related variables
|
||||
|
||||
# Console Docker image
|
||||
CONSOLE_IMAGE=minio/console:v0.6.2
|
||||
|
||||
# Salt to encrypt JWT payload
|
||||
CONSOLE_PBKDF_PASSPHRASE=top_secret
|
||||
|
||||
# Required to encrypt JWT payload
|
||||
CONSOLE_PBKDF_SALT=top_secret1
|
||||
|
||||
# MinIO Server URL
|
||||
CONSOLE_MINIO_SERVER=http://localhost:9000
|
||||
|
||||
|
||||
## Prometheus related variables
|
||||
|
||||
# Prometheus Docker image
|
||||
PROMETHEUS_IMAGE=prom/prometheus:latest
|
||||
|
||||
# Prometheus port number
|
||||
PROMETHEUS_PORT=9999
|
||||
64
compose/README.md
Normal file
@@ -0,0 +1,64 @@
|
||||
|
||||
## Console Docker Compose
|
||||
|
||||
This compose file allows users to quickly deploy MinIO Console, LogSearch & Prometheus in a baremetal (non Kubernetes) environment.
|
||||
|
||||
### Pre-requisites
|
||||
|
||||
1. [MinIO](https://docs.minio.io/docs/distributed-minio-quickstart-guide.html) cluster up and running.
|
||||
2. [mc](https://docs.minio.io/docs/minio-client-quickstart-guide.html) configured for this MinIO cluster.
|
||||
3. [Docker-Compose](https://docs.docker.com/compose/) installed on the server.
|
||||
|
||||
### Getting Started
|
||||
|
||||
- Download the contents of `compose` directory on your machine.
|
||||
|
||||
- Edit the `prometheus.yaml` file and fill in the correct target (MinIO Endpoint). Optionally setup the `bearer_token` as explained [here](https://github.com/minio/minio/tree/master/docs/metrics/prometheus#31-authenticated-prometheus-config).
|
||||
|
||||
- Setup a console admin policy.
|
||||
|
||||
```sh
|
||||
cat > admin.json << EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [{
|
||||
"Action": [
|
||||
"admin:*"
|
||||
],
|
||||
"Effect": "Allow",
|
||||
"Sid": ""
|
||||
},
|
||||
{
|
||||
"Action": [
|
||||
"s3:*"
|
||||
],
|
||||
"Effect": "Allow",
|
||||
"Resource": [
|
||||
"arn:aws:s3:::*"
|
||||
],
|
||||
"Sid": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
Then create this policy on MinIO server: `mc admin policy add myminio consoleAdmin admin.json`.
|
||||
|
||||
- Setup user and policy for Console
|
||||
|
||||
```
|
||||
mc admin user add myminio console console123
|
||||
mc admin policy set myminio consoleAdmin user=console
|
||||
```
|
||||
|
||||
- Configure Webhook target on the MinIO server. Remember to change the `token` value in below URL to the actual token value as set in the `.env` file.
|
||||
|
||||
```
|
||||
mc admin config set myminio audit_webhook:1 endpoint=http://localhost:8080/api/ingest?token=c6rkqjZ03ElEUKQ7MtSeYBJ8q_p3GDFPBQAQJlcbBLA=
|
||||
mc admin service restart myminio
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
To configure the Console Compose file to custom setup, please take a look at the [`.env`](./.env) file.
|
||||
62
compose/docker-compose.yaml
Normal file
@@ -0,0 +1,62 @@
|
||||
version: '3.4'
|
||||
services:
|
||||
pg_database:
|
||||
image: ${POSTGRES_IMAGE}
|
||||
network_mode: host
|
||||
environment:
|
||||
- POSTGRES_USER=${POSTGRES_USER}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
- PGDATA=${PGDATA}
|
||||
- POSTGRES_DB=minio_logs
|
||||
volumes:
|
||||
- database:${PGDATA}
|
||||
ports:
|
||||
- ${POSTGRES_PORT}:${POSTGRES_PORT}
|
||||
|
||||
log_search:
|
||||
image: ${LOGSEARCH_IMAGE}
|
||||
network_mode: host
|
||||
environment:
|
||||
- LOGSEARCH_AUDIT_AUTH_TOKEN=${LOGSEARCH_AUDIT_AUTH_TOKEN}
|
||||
- LOGSEARCH_QUERY_AUTH_TOKEN=${LOGSEARCH_QUERY_AUTH_TOKEN}
|
||||
- LOGSEARCH_DISK_CAPACITY_GB=${LOGSEARCH_DISK_CAPACITY_GB}
|
||||
- LOGSEARCH_MAX_RETENTION_MONTHS=${LOGSEARCH_MAX_RETENTION_MONTHS}
|
||||
- LOGSEARCH_PG_CONN_STR=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${POSTGRES_PORT}/minio_logs?sslmode=disable
|
||||
ports:
|
||||
- ${LOGSEARCH_PORT}:${LOGSEARCH_PORT}
|
||||
command: ["/usr/bin/wait-for-it.sh", "localhost:${POSTGRES_PORT}", "--", "/logsearchapi"]
|
||||
volumes:
|
||||
- ./wait-for-it.sh:/usr/bin/wait-for-it.sh
|
||||
depends_on:
|
||||
- pg_database
|
||||
|
||||
console:
|
||||
image: ${CONSOLE_IMAGE}
|
||||
network_mode: host
|
||||
environment:
|
||||
- CONSOLE_PBKDF_PASSPHRASE=${CONSOLE_PBKDF_PASSPHRASE}
|
||||
- CONSOLE_PBKDF_SALT=${CONSOLE_PBKDF_SALT}
|
||||
- LOGSEARCH_QUERY_AUTH_TOKEN=${LOGSEARCH_QUERY_AUTH_TOKEN}
|
||||
- CONSOLE_MINIO_SERVER=${CONSOLE_MINIO_SERVER}
|
||||
- CONSOLE_LOG_QUERY_URL=http://localhost:${LOGSEARCH_PORT}
|
||||
- CONSOLE_PROMETHEUS_URL=http://localhost:${PROMETHEUS_PORT}
|
||||
ports:
|
||||
- "9090:9090"
|
||||
command: server
|
||||
depends_on:
|
||||
- log_search
|
||||
- prometheus
|
||||
|
||||
prometheus:
|
||||
image: ${PROMETHEUS_IMAGE}
|
||||
network_mode: host
|
||||
ports:
|
||||
- ${PROMETHEUS_PORT}:${PROMETHEUS_PORT}
|
||||
command:
|
||||
- --config.file=/etc/prometheus/prometheus.yml
|
||||
- --web.listen-address=:${PROMETHEUS_PORT}
|
||||
volumes:
|
||||
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
|
||||
|
||||
volumes:
|
||||
database:
|
||||
15
compose/prometheus.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
global:
|
||||
scrape_interval: 10s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
|
||||
evaluation_interval: 30s # Evaluate rules every 15 seconds. The default is every 1 minute.
|
||||
# scrape_timeout is set to the global default (10s).
|
||||
|
||||
# A scrape configuration containing exactly one endpoint to scrape:
|
||||
# Here it's Prometheus itself.
|
||||
scrape_configs:
|
||||
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
|
||||
- job_name: minio-node1
|
||||
metrics_path: /minio/v2/metrics/cluster
|
||||
scheme: http
|
||||
static_configs:
|
||||
- targets:
|
||||
- 'localhost:9000'
|
||||
182
compose/wait-for-it.sh
Executable file
@@ -0,0 +1,182 @@
|
||||
#!/usr/bin/env bash
|
||||
# Use this script to test if a given TCP host/port are available
|
||||
|
||||
WAITFORIT_cmdname=${0##*/}
|
||||
|
||||
echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
|
||||
|
||||
usage()
|
||||
{
|
||||
cat << USAGE >&2
|
||||
Usage:
|
||||
$WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args]
|
||||
-h HOST | --host=HOST Host or IP under test
|
||||
-p PORT | --port=PORT TCP port under test
|
||||
Alternatively, you specify the host and port as host:port
|
||||
-s | --strict Only execute subcommand if the test succeeds
|
||||
-q | --quiet Don't output any status messages
|
||||
-t TIMEOUT | --timeout=TIMEOUT
|
||||
Timeout in seconds, zero for no timeout
|
||||
-- COMMAND ARGS Execute command with args after the test finishes
|
||||
USAGE
|
||||
exit 1
|
||||
}
|
||||
|
||||
wait_for()
|
||||
{
|
||||
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
|
||||
echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
|
||||
else
|
||||
echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout"
|
||||
fi
|
||||
WAITFORIT_start_ts=$(date +%s)
|
||||
while :
|
||||
do
|
||||
if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then
|
||||
nc -z $WAITFORIT_HOST $WAITFORIT_PORT
|
||||
WAITFORIT_result=$?
|
||||
else
|
||||
(echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1
|
||||
WAITFORIT_result=$?
|
||||
fi
|
||||
if [[ $WAITFORIT_result -eq 0 ]]; then
|
||||
WAITFORIT_end_ts=$(date +%s)
|
||||
echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
return $WAITFORIT_result
|
||||
}
|
||||
|
||||
wait_for_wrapper()
|
||||
{
|
||||
# In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
|
||||
if [[ $WAITFORIT_QUIET -eq 1 ]]; then
|
||||
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
|
||||
else
|
||||
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
|
||||
fi
|
||||
WAITFORIT_PID=$!
|
||||
trap "kill -INT -$WAITFORIT_PID" INT
|
||||
wait $WAITFORIT_PID
|
||||
WAITFORIT_RESULT=$?
|
||||
if [[ $WAITFORIT_RESULT -ne 0 ]]; then
|
||||
echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
|
||||
fi
|
||||
return $WAITFORIT_RESULT
|
||||
}
|
||||
|
||||
# process arguments
|
||||
while [[ $# -gt 0 ]]
|
||||
do
|
||||
case "$1" in
|
||||
*:* )
|
||||
WAITFORIT_hostport=(${1//:/ })
|
||||
WAITFORIT_HOST=${WAITFORIT_hostport[0]}
|
||||
WAITFORIT_PORT=${WAITFORIT_hostport[1]}
|
||||
shift 1
|
||||
;;
|
||||
--child)
|
||||
WAITFORIT_CHILD=1
|
||||
shift 1
|
||||
;;
|
||||
-q | --quiet)
|
||||
WAITFORIT_QUIET=1
|
||||
shift 1
|
||||
;;
|
||||
-s | --strict)
|
||||
WAITFORIT_STRICT=1
|
||||
shift 1
|
||||
;;
|
||||
-h)
|
||||
WAITFORIT_HOST="$2"
|
||||
if [[ $WAITFORIT_HOST == "" ]]; then break; fi
|
||||
shift 2
|
||||
;;
|
||||
--host=*)
|
||||
WAITFORIT_HOST="${1#*=}"
|
||||
shift 1
|
||||
;;
|
||||
-p)
|
||||
WAITFORIT_PORT="$2"
|
||||
if [[ $WAITFORIT_PORT == "" ]]; then break; fi
|
||||
shift 2
|
||||
;;
|
||||
--port=*)
|
||||
WAITFORIT_PORT="${1#*=}"
|
||||
shift 1
|
||||
;;
|
||||
-t)
|
||||
WAITFORIT_TIMEOUT="$2"
|
||||
if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi
|
||||
shift 2
|
||||
;;
|
||||
--timeout=*)
|
||||
WAITFORIT_TIMEOUT="${1#*=}"
|
||||
shift 1
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
WAITFORIT_CLI=("$@")
|
||||
break
|
||||
;;
|
||||
--help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
echoerr "Unknown argument: $1"
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then
|
||||
echoerr "Error: you need to provide a host and port to test."
|
||||
usage
|
||||
fi
|
||||
|
||||
WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15}
|
||||
WAITFORIT_STRICT=${WAITFORIT_STRICT:-0}
|
||||
WAITFORIT_CHILD=${WAITFORIT_CHILD:-0}
|
||||
WAITFORIT_QUIET=${WAITFORIT_QUIET:-0}
|
||||
|
||||
# Check to see if timeout is from busybox?
|
||||
WAITFORIT_TIMEOUT_PATH=$(type -p timeout)
|
||||
WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH)
|
||||
|
||||
WAITFORIT_BUSYTIMEFLAG=""
|
||||
if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then
|
||||
WAITFORIT_ISBUSY=1
|
||||
# Check if busybox timeout uses -t flag
|
||||
# (recent Alpine versions don't support -t anymore)
|
||||
if timeout &>/dev/stdout | grep -q -e '-t '; then
|
||||
WAITFORIT_BUSYTIMEFLAG="-t"
|
||||
fi
|
||||
else
|
||||
WAITFORIT_ISBUSY=0
|
||||
fi
|
||||
|
||||
if [[ $WAITFORIT_CHILD -gt 0 ]]; then
|
||||
wait_for
|
||||
WAITFORIT_RESULT=$?
|
||||
exit $WAITFORIT_RESULT
|
||||
else
|
||||
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
|
||||
wait_for_wrapper
|
||||
WAITFORIT_RESULT=$?
|
||||
else
|
||||
wait_for
|
||||
WAITFORIT_RESULT=$?
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $WAITFORIT_CLI != "" ]]; then
|
||||
if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then
|
||||
echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess"
|
||||
exit $WAITFORIT_RESULT
|
||||
fi
|
||||
exec "${WAITFORIT_CLI[@]}"
|
||||
else
|
||||
exit $WAITFORIT_RESULT
|
||||
fi
|
||||
27
go.mod
@@ -1,10 +1,11 @@
|
||||
module github.com/minio/console
|
||||
|
||||
go 1.15
|
||||
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/elazarl/go-bindata-assetfs v1.0.0
|
||||
github.com/go-openapi/errors v0.19.6
|
||||
github.com/go-openapi/loads v0.19.5
|
||||
github.com/go-openapi/runtime v0.19.19
|
||||
@@ -15,24 +16,24 @@ require (
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/jessevdk/go-flags v1.4.0
|
||||
github.com/minio/cli v1.22.0
|
||||
github.com/minio/direct-csi v1.2.8
|
||||
github.com/minio/kes v0.11.0
|
||||
github.com/minio/mc v0.0.0-20201220181029-41c804b179de
|
||||
github.com/minio/minio v0.0.0-20201221162327-6df6ac0f3410
|
||||
github.com/minio/minio-go/v7 v7.0.7-0.20201217170524-3baf9ea06f7c
|
||||
github.com/minio/operator v0.0.0-20201204220226-9901d1d0766c
|
||||
github.com/minio/operator/logsearchapi v0.0.0-20201217190212-bf6546b09012
|
||||
github.com/minio/mc v0.0.0-20210301162250-f9d36f9b5243
|
||||
github.com/minio/minio v0.0.0-20210301203133-e8d8dfa3ae8f
|
||||
github.com/minio/minio-go/v7 v7.0.10
|
||||
github.com/minio/operator v0.0.0-20210317030027-207337abe7fd
|
||||
github.com/minio/operator/logsearchapi v0.0.0-20210201110528-753019b838b4
|
||||
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/secure-io/sio-go v0.3.1
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/unrolled/secure v1.0.7
|
||||
golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb
|
||||
golang.org/x/net v0.0.0-20201216054612-986b41b23924
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||
gopkg.in/yaml.v2 v2.3.0
|
||||
k8s.io/api v0.18.6
|
||||
k8s.io/apimachinery v0.18.8
|
||||
k8s.io/client-go v0.18.6
|
||||
k8s.io/api v0.20.2
|
||||
k8s.io/apimachinery v0.20.2
|
||||
k8s.io/client-go v0.20.2
|
||||
)
|
||||
|
||||
replace github.com/minio/operator v0.0.0-20201204220226-9901d1d0766c => github.com/dvaldivia/operator v0.0.0-20201230052356-04efc0ea5890
|
||||
|
||||
BIN
images/pic1.png
|
Before Width: | Height: | Size: 1.9 MiB After Width: | Height: | Size: 1.7 MiB |
@@ -3,20 +3,6 @@ kind: ClusterRole
|
||||
metadata:
|
||||
name: console-sa-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- namespaces
|
||||
- pods
|
||||
- services
|
||||
- events
|
||||
- resourcequotas
|
||||
verbs:
|
||||
- get
|
||||
- watch
|
||||
- create
|
||||
- list
|
||||
- patch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
@@ -27,8 +13,33 @@ rules:
|
||||
- create
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- deletecollection
|
||||
- delete
|
||||
- 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:
|
||||
@@ -86,3 +97,126 @@ rules:
|
||||
- "*"
|
||||
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
|
||||
|
||||
@@ -15,7 +15,7 @@ spec:
|
||||
serviceAccountName: console-sa
|
||||
containers:
|
||||
- name: console
|
||||
image: minio/console:v0.5.2
|
||||
image: minio/console:v0.6.6
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
args:
|
||||
- server
|
||||
|
||||
@@ -38,6 +38,8 @@ rules:
|
||||
- deletecollection
|
||||
- list
|
||||
- get
|
||||
- watch
|
||||
- update
|
||||
- apiGroups:
|
||||
- "storage.k8s.io"
|
||||
resources:
|
||||
@@ -95,3 +97,126 @@ rules:
|
||||
- "*"
|
||||
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
|
||||
|
||||
@@ -15,7 +15,7 @@ spec:
|
||||
serviceAccountName: console-sa
|
||||
containers:
|
||||
- name: console
|
||||
image: minio/console:v0.5.2
|
||||
image: minio/console:v0.6.6
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
env:
|
||||
- name: CONSOLE_OPERATOR_MODE
|
||||
|
||||
60
models/bucket_ob_locking_response.go
Normal file
@@ -0,0 +1,60 @@
|
||||
// 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 (
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// BucketObLockingResponse bucket ob locking response
|
||||
//
|
||||
// swagger:model bucketObLockingResponse
|
||||
type BucketObLockingResponse struct {
|
||||
|
||||
// object locking enabled
|
||||
ObjectLockingEnabled bool `json:"object_locking_enabled,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this bucket ob locking response
|
||||
func (m *BucketObLockingResponse) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *BucketObLockingResponse) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *BucketObLockingResponse) UnmarshalBinary(b []byte) error {
|
||||
var res BucketObLockingResponse
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
78
models/direct_c_s_i_drive_info.go
Normal file
@@ -0,0 +1,78 @@
|
||||
// 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 (
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// DirectCSIDriveInfo direct c s i drive info
|
||||
//
|
||||
// swagger:model directCSIDriveInfo
|
||||
type DirectCSIDriveInfo struct {
|
||||
|
||||
// allocated
|
||||
Allocated int64 `json:"allocated,omitempty"`
|
||||
|
||||
// capacity
|
||||
Capacity int64 `json:"capacity,omitempty"`
|
||||
|
||||
// drive
|
||||
Drive string `json:"drive,omitempty"`
|
||||
|
||||
// message
|
||||
Message string `json:"message,omitempty"`
|
||||
|
||||
// node
|
||||
Node string `json:"node,omitempty"`
|
||||
|
||||
// status
|
||||
Status string `json:"status,omitempty"`
|
||||
|
||||
// volumes
|
||||
Volumes int64 `json:"volumes,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this direct c s i drive info
|
||||
func (m *DirectCSIDriveInfo) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *DirectCSIDriveInfo) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *DirectCSIDriveInfo) UnmarshalBinary(b []byte) error {
|
||||
var res DirectCSIDriveInfo
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
69
models/direct_c_s_i_volume_info.go
Normal file
@@ -0,0 +1,69 @@
|
||||
// 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 (
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// DirectCSIVolumeInfo direct c s i volume info
|
||||
//
|
||||
// swagger:model directCSIVolumeInfo
|
||||
type DirectCSIVolumeInfo struct {
|
||||
|
||||
// capacity
|
||||
Capacity int64 `json:"capacity,omitempty"`
|
||||
|
||||
// drive
|
||||
Drive string `json:"drive,omitempty"`
|
||||
|
||||
// node
|
||||
Node string `json:"node,omitempty"`
|
||||
|
||||
// volume
|
||||
Volume string `json:"volume,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this direct c s i volume info
|
||||
func (m *DirectCSIVolumeInfo) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *DirectCSIVolumeInfo) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *DirectCSIVolumeInfo) UnmarshalBinary(b []byte) error {
|
||||
var res DirectCSIVolumeInfo
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -40,6 +40,9 @@ type EncryptionConfiguration struct {
|
||||
// client
|
||||
Client *KeyPairConfiguration `json:"client,omitempty"`
|
||||
|
||||
// gcp
|
||||
Gcp *GcpConfiguration `json:"gcp,omitempty"`
|
||||
|
||||
// gemalto
|
||||
Gemalto *GemaltoConfiguration `json:"gemalto,omitempty"`
|
||||
|
||||
@@ -68,6 +71,8 @@ func (m *EncryptionConfiguration) UnmarshalJSON(raw []byte) error {
|
||||
|
||||
Client *KeyPairConfiguration `json:"client,omitempty"`
|
||||
|
||||
Gcp *GcpConfiguration `json:"gcp,omitempty"`
|
||||
|
||||
Gemalto *GemaltoConfiguration `json:"gemalto,omitempty"`
|
||||
|
||||
Image string `json:"image,omitempty"`
|
||||
@@ -84,6 +89,8 @@ func (m *EncryptionConfiguration) UnmarshalJSON(raw []byte) error {
|
||||
|
||||
m.Client = dataAO1.Client
|
||||
|
||||
m.Gcp = dataAO1.Gcp
|
||||
|
||||
m.Gemalto = dataAO1.Gemalto
|
||||
|
||||
m.Image = dataAO1.Image
|
||||
@@ -109,6 +116,8 @@ func (m EncryptionConfiguration) MarshalJSON() ([]byte, error) {
|
||||
|
||||
Client *KeyPairConfiguration `json:"client,omitempty"`
|
||||
|
||||
Gcp *GcpConfiguration `json:"gcp,omitempty"`
|
||||
|
||||
Gemalto *GemaltoConfiguration `json:"gemalto,omitempty"`
|
||||
|
||||
Image string `json:"image,omitempty"`
|
||||
@@ -122,6 +131,8 @@ func (m EncryptionConfiguration) MarshalJSON() ([]byte, error) {
|
||||
|
||||
dataAO1.Client = m.Client
|
||||
|
||||
dataAO1.Gcp = m.Gcp
|
||||
|
||||
dataAO1.Gemalto = m.Gemalto
|
||||
|
||||
dataAO1.Image = m.Image
|
||||
@@ -155,6 +166,10 @@ func (m *EncryptionConfiguration) Validate(formats strfmt.Registry) error {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateGcp(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateGemalto(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -209,6 +224,24 @@ func (m *EncryptionConfiguration) validateClient(formats strfmt.Registry) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *EncryptionConfiguration) validateGcp(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.Gcp) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.Gcp != nil {
|
||||
if err := m.Gcp.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("gcp")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *EncryptionConfiguration) validateGemalto(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.Gemalto) { // not required
|
||||
|
||||
210
models/gcp_configuration.go
Normal file
@@ -0,0 +1,210 @@
|
||||
// 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 (
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/validate"
|
||||
)
|
||||
|
||||
// GcpConfiguration gcp configuration
|
||||
//
|
||||
// swagger:model gcpConfiguration
|
||||
type GcpConfiguration struct {
|
||||
|
||||
// secretmanager
|
||||
// Required: true
|
||||
Secretmanager *GcpConfigurationSecretmanager `json:"secretmanager"`
|
||||
}
|
||||
|
||||
// Validate validates this gcp configuration
|
||||
func (m *GcpConfiguration) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateSecretmanager(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GcpConfiguration) validateSecretmanager(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("secretmanager", "body", m.Secretmanager); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if m.Secretmanager != nil {
|
||||
if err := m.Secretmanager.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("secretmanager")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *GcpConfiguration) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *GcpConfiguration) UnmarshalBinary(b []byte) error {
|
||||
var res GcpConfiguration
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
|
||||
// GcpConfigurationSecretmanager gcp configuration secretmanager
|
||||
//
|
||||
// swagger:model GcpConfigurationSecretmanager
|
||||
type GcpConfigurationSecretmanager struct {
|
||||
|
||||
// credentials
|
||||
Credentials *GcpConfigurationSecretmanagerCredentials `json:"credentials,omitempty"`
|
||||
|
||||
// endpoint
|
||||
Endpoint string `json:"endpoint,omitempty"`
|
||||
|
||||
// project id
|
||||
// Required: true
|
||||
ProjectID *string `json:"project_id"`
|
||||
}
|
||||
|
||||
// Validate validates this gcp configuration secretmanager
|
||||
func (m *GcpConfigurationSecretmanager) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateCredentials(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateProjectID(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GcpConfigurationSecretmanager) 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("secretmanager" + "." + "credentials")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GcpConfigurationSecretmanager) validateProjectID(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("secretmanager"+"."+"project_id", "body", m.ProjectID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *GcpConfigurationSecretmanager) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *GcpConfigurationSecretmanager) UnmarshalBinary(b []byte) error {
|
||||
var res GcpConfigurationSecretmanager
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
|
||||
// GcpConfigurationSecretmanagerCredentials gcp configuration secretmanager credentials
|
||||
//
|
||||
// swagger:model GcpConfigurationSecretmanagerCredentials
|
||||
type GcpConfigurationSecretmanagerCredentials struct {
|
||||
|
||||
// client email
|
||||
ClientEmail string `json:"client_email,omitempty"`
|
||||
|
||||
// client id
|
||||
ClientID string `json:"client_id,omitempty"`
|
||||
|
||||
// private key
|
||||
PrivateKey string `json:"private_key,omitempty"`
|
||||
|
||||
// private key id
|
||||
PrivateKeyID string `json:"private_key_id,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this gcp configuration secretmanager credentials
|
||||
func (m *GcpConfigurationSecretmanagerCredentials) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *GcpConfigurationSecretmanagerCredentials) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *GcpConfigurationSecretmanagerCredentials) UnmarshalBinary(b []byte) error {
|
||||
var res GcpConfigurationSecretmanagerCredentials
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
97
models/get_direct_c_s_i_drive_list_response.go
Normal file
@@ -0,0 +1,97 @@
|
||||
// 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 (
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// GetDirectCSIDriveListResponse get direct c s i drive list response
|
||||
//
|
||||
// swagger:model getDirectCSIDriveListResponse
|
||||
type GetDirectCSIDriveListResponse struct {
|
||||
|
||||
// drives
|
||||
Drives []*DirectCSIDriveInfo `json:"drives"`
|
||||
}
|
||||
|
||||
// Validate validates this get direct c s i drive list response
|
||||
func (m *GetDirectCSIDriveListResponse) 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 *GetDirectCSIDriveListResponse) 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
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *GetDirectCSIDriveListResponse) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *GetDirectCSIDriveListResponse) UnmarshalBinary(b []byte) error {
|
||||
var res GetDirectCSIDriveListResponse
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
97
models/get_direct_c_s_i_volume_list_response.go
Normal file
@@ -0,0 +1,97 @@
|
||||
// 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 (
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// GetDirectCSIVolumeListResponse get direct c s i volume list response
|
||||
//
|
||||
// swagger:model getDirectCSIVolumeListResponse
|
||||
type GetDirectCSIVolumeListResponse struct {
|
||||
|
||||
// volumes
|
||||
Volumes []*DirectCSIVolumeInfo `json:"volumes"`
|
||||
}
|
||||
|
||||
// Validate validates this get direct c s i volume list response
|
||||
func (m *GetDirectCSIVolumeListResponse) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateVolumes(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GetDirectCSIVolumeListResponse) validateVolumes(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.Volumes) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.Volumes); i++ {
|
||||
if swag.IsZero(m.Volumes[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.Volumes[i] != nil {
|
||||
if err := m.Volumes[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("volumes" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *GetDirectCSIVolumeListResponse) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *GetDirectCSIVolumeListResponse) UnmarshalBinary(b []byte) error {
|
||||
var res GetDirectCSIVolumeListResponse
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
97
models/has_permission_request.go
Normal file
@@ -0,0 +1,97 @@
|
||||
// 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 (
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// HasPermissionRequest has permission request
|
||||
//
|
||||
// swagger:model hasPermissionRequest
|
||||
type HasPermissionRequest struct {
|
||||
|
||||
// actions
|
||||
Actions []*PolicyArgs `json:"actions"`
|
||||
}
|
||||
|
||||
// Validate validates this has permission request
|
||||
func (m *HasPermissionRequest) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateActions(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *HasPermissionRequest) validateActions(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.Actions) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.Actions); i++ {
|
||||
if swag.IsZero(m.Actions[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.Actions[i] != nil {
|
||||
if err := m.Actions[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("actions" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *HasPermissionRequest) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *HasPermissionRequest) UnmarshalBinary(b []byte) error {
|
||||
var res HasPermissionRequest
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
97
models/has_permission_response.go
Normal file
@@ -0,0 +1,97 @@
|
||||
// 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 (
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// HasPermissionResponse has permission response
|
||||
//
|
||||
// swagger:model hasPermissionResponse
|
||||
type HasPermissionResponse struct {
|
||||
|
||||
// permissions
|
||||
Permissions []*PermissionAction `json:"permissions"`
|
||||
}
|
||||
|
||||
// Validate validates this has permission response
|
||||
func (m *HasPermissionResponse) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validatePermissions(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *HasPermissionResponse) validatePermissions(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.Permissions) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.Permissions); i++ {
|
||||
if swag.IsZero(m.Permissions[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.Permissions[i] != nil {
|
||||
if err := m.Permissions[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("permissions" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *HasPermissionResponse) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *HasPermissionResponse) UnmarshalBinary(b []byte) error {
|
||||
var res HasPermissionResponse
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -34,6 +34,9 @@ import (
|
||||
// swagger:model makeBucketRequest
|
||||
type MakeBucketRequest struct {
|
||||
|
||||
// locking
|
||||
Locking bool `json:"locking,omitempty"`
|
||||
|
||||
// name
|
||||
// Required: true
|
||||
Name *string `json:"name"`
|
||||
|
||||
63
models/permission_action.go
Normal file
@@ -0,0 +1,63 @@
|
||||
// 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 (
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// PermissionAction permission action
|
||||
//
|
||||
// swagger:model permissionAction
|
||||
type PermissionAction struct {
|
||||
|
||||
// can
|
||||
Can bool `json:"can,omitempty"`
|
||||
|
||||
// id
|
||||
ID string `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this permission action
|
||||
func (m *PermissionAction) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *PermissionAction) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *PermissionAction) UnmarshalBinary(b []byte) error {
|
||||
var res PermissionAction
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
66
models/policy_args.go
Normal file
@@ -0,0 +1,66 @@
|
||||
// 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 (
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// PolicyArgs policy args
|
||||
//
|
||||
// swagger:model policyArgs
|
||||
type PolicyArgs struct {
|
||||
|
||||
// action
|
||||
Action string `json:"action,omitempty"`
|
||||
|
||||
// bucket name
|
||||
BucketName string `json:"bucket_name,omitempty"`
|
||||
|
||||
// id
|
||||
ID string `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this policy args
|
||||
func (m *PolicyArgs) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *PolicyArgs) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *PolicyArgs) UnmarshalBinary(b []byte) error {
|
||||
var res PolicyArgs
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -44,9 +44,6 @@ type Principal struct {
|
||||
// account access key
|
||||
AccountAccessKey string `json:"accountAccessKey,omitempty"`
|
||||
|
||||
// account secret key
|
||||
AccountSecretKey string `json:"accountSecretKey,omitempty"`
|
||||
|
||||
// actions
|
||||
Actions []string `json:"actions"`
|
||||
}
|
||||
|
||||
@@ -35,6 +35,9 @@ import (
|
||||
// swagger:model tlsConfiguration
|
||||
type TLSConfiguration struct {
|
||||
|
||||
// ca certificates
|
||||
CaCertificates []string `json:"ca_certificates"`
|
||||
|
||||
// console
|
||||
Console *KeyPairConfiguration `json:"console,omitempty"`
|
||||
|
||||
|
||||
@@ -26,3 +26,7 @@ import (
|
||||
func GetOperatorMode() bool {
|
||||
return strings.ToLower(env.Get(consoleOperatorMode, "off")) == "on"
|
||||
}
|
||||
|
||||
func GetLDAPEnabled() bool {
|
||||
return strings.ToLower(env.Get(ConsoleLDAPEnabled, "off")) == "on"
|
||||
}
|
||||
|
||||
@@ -18,4 +18,6 @@ package acl
|
||||
|
||||
const (
|
||||
consoleOperatorMode = "CONSOLE_OPERATOR_MODE"
|
||||
// const for ldap configuration
|
||||
ConsoleLDAPEnabled = "CONSOLE_LDAP_ENABLED"
|
||||
)
|
||||
|
||||
@@ -31,6 +31,7 @@ var (
|
||||
buckets = "/buckets"
|
||||
bucketsDetail = "/buckets/:bucketName"
|
||||
serviceAccounts = "/account"
|
||||
changePassword = "/account/change-password"
|
||||
tenants = "/tenants"
|
||||
tenantsDetail = "/namespaces/:tenantNamespace/tenants/:tenantName"
|
||||
remoteBuckets = "/remote-buckets"
|
||||
@@ -156,6 +157,16 @@ var serviceAccountsActionSet = ConfigurationActionSet{
|
||||
actions: iampolicy.NewActionSet(),
|
||||
}
|
||||
|
||||
// changePasswordActionSet requires admin:CreateUser policy permission
|
||||
var changePasswordActionSet = ConfigurationActionSet{
|
||||
actionTypes: iampolicy.NewActionSet(
|
||||
iampolicy.AllAdminActions,
|
||||
),
|
||||
actions: iampolicy.NewActionSet(
|
||||
iampolicy.CreateUserAdminAction,
|
||||
),
|
||||
}
|
||||
|
||||
// tenantsActionSet temporally no actions needed for tenants sections to work
|
||||
var tenantsActionSet = ConfigurationActionSet{
|
||||
actionTypes: iampolicy.NewActionSet(),
|
||||
@@ -242,6 +253,17 @@ var healthInfoActionSet = ConfigurationActionSet{
|
||||
),
|
||||
}
|
||||
|
||||
var displayRules = map[string]func() bool{
|
||||
// disable users page if LDAP is enabled
|
||||
users: func() bool {
|
||||
return !GetLDAPEnabled()
|
||||
},
|
||||
// disable groups page if LDAP is enabled
|
||||
groups: func() bool {
|
||||
return !GetLDAPEnabled()
|
||||
},
|
||||
}
|
||||
|
||||
// endpointRules contains the mapping between endpoints and ActionSets, additional rules can be added here
|
||||
var endpointRules = map[string]ConfigurationActionSet{
|
||||
configuration: configurationActionSet,
|
||||
@@ -253,6 +275,7 @@ var endpointRules = map[string]ConfigurationActionSet{
|
||||
buckets: bucketsActionSet,
|
||||
bucketsDetail: bucketsActionSet,
|
||||
serviceAccounts: serviceAccountsActionSet,
|
||||
changePassword: changePasswordActionSet,
|
||||
remoteBuckets: remoteBucketsActionSet,
|
||||
replication: replicationActionSet,
|
||||
objectBrowser: objectBrowserActionSet,
|
||||
@@ -335,6 +358,15 @@ func GetAuthorizedEndpoints(actions []string) []string {
|
||||
userAllowedAction := actionsStringToActionSet(actions)
|
||||
var allowedEndpoints []string
|
||||
for endpoint, rules := range rangeTake {
|
||||
|
||||
// check if display rule exists for this endpoint, this will control
|
||||
// what user sees on the console UI
|
||||
if rule, ok := displayRules[endpoint]; ok {
|
||||
if rule != nil && !rule() {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// check if user policy matches s3:* or admin:* typesIntersection
|
||||
endpointActionTypes := rules.actionTypes
|
||||
typesIntersection := endpointActionTypes.Intersection(userAllowedAction)
|
||||
|
||||
@@ -72,7 +72,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
|
||||
"admin:*",
|
||||
},
|
||||
},
|
||||
want: 18,
|
||||
want: 19,
|
||||
},
|
||||
{
|
||||
name: "all s3 endpoints",
|
||||
@@ -91,7 +91,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
|
||||
"s3:*",
|
||||
},
|
||||
},
|
||||
want: 20,
|
||||
want: 21,
|
||||
},
|
||||
{
|
||||
name: "Console User - default endpoints",
|
||||
|
||||
@@ -91,9 +91,10 @@ type Provider struct {
|
||||
// often available via site-specific packages, such as
|
||||
// google.Endpoint or github.Endpoint.
|
||||
// - Scopes specifies optional requested permissions.
|
||||
ClientID string
|
||||
oauth2Config Configuration
|
||||
oidcProvider *oidc.Provider
|
||||
ClientID string
|
||||
oauth2Config Configuration
|
||||
oidcProvider *oidc.Provider
|
||||
provHTTPClient *http.Client
|
||||
}
|
||||
|
||||
// derivedKey is the key used to compute the HMAC for signing the oauth state parameter
|
||||
@@ -103,8 +104,9 @@ var derivedKey = pbkdf2.Key([]byte(getPassphraseForIdpHmac()), []byte(getSaltFor
|
||||
// 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) (*Provider, error) {
|
||||
provider, err := oidc.NewProvider(ctx, GetIdpURL())
|
||||
func NewOauth2ProviderClient(ctx context.Context, scopes []string, httpClient *http.Client) (*Provider, error) {
|
||||
customCtx := oidc.ClientContext(ctx, httpClient)
|
||||
provider, err := oidc.NewProvider(customCtx, GetIdpURL())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -122,6 +124,7 @@ func NewOauth2ProviderClient(ctx context.Context, scopes []string) (*Provider, e
|
||||
}
|
||||
client.oidcProvider = provider
|
||||
client.ClientID = GetIdpClientID()
|
||||
client.provHTTPClient = httpClient
|
||||
|
||||
return client, nil
|
||||
}
|
||||
@@ -172,10 +175,11 @@ func (client *Provider) VerifyIdentity(ctx context.Context, code, state string)
|
||||
}, nil
|
||||
}
|
||||
stsEndpoint := GetSTSEndpoint()
|
||||
sts, err := credentials.NewSTSWebIdentity(stsEndpoint, getWebTokenExpiry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sts := credentials.New(&credentials.STSWebIdentity{
|
||||
Client: client.provHTTPClient,
|
||||
STSEndpoint: stsEndpoint,
|
||||
GetWebIDTokenExpiry: getWebTokenExpiry,
|
||||
})
|
||||
return sts, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,6 @@ type TokenClaims struct {
|
||||
STSSecretAccessKey string `json:"stsSecretAccessKey,omitempty"`
|
||||
STSSessionToken string `json:"stsSessionToken,omitempty"`
|
||||
AccountAccessKey string `json:"accountAccessKey,omitempty"`
|
||||
AccountSecretKey string `json:"accountSecretKey,omitempty"`
|
||||
Actions []string `json:"actions,omitempty"`
|
||||
}
|
||||
|
||||
@@ -79,7 +78,6 @@ type TokenClaims struct {
|
||||
// STSSecretAccessKey
|
||||
// STSSessionToken
|
||||
// AccountAccessKey
|
||||
// AccountSecretKey
|
||||
// Actions
|
||||
// }
|
||||
func SessionTokenAuthenticate(token string) (*TokenClaims, error) {
|
||||
@@ -100,14 +98,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, accountSecretKey string, actions []string) (string, error) {
|
||||
func NewEncryptedTokenForClient(credentials *credentials.Value, accountAccessKey string, actions []string) (string, error) {
|
||||
if credentials != nil {
|
||||
encryptedClaims, err := encryptClaims(&TokenClaims{
|
||||
STSAccessKeyID: credentials.AccessKeyID,
|
||||
STSSecretAccessKey: credentials.SecretAccessKey,
|
||||
STSSessionToken: credentials.SessionToken,
|
||||
AccountAccessKey: accountAccessKey,
|
||||
AccountSecretKey: accountSecretKey,
|
||||
Actions: actions,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -330,6 +327,5 @@ func GetClaimsFromTokenInRequest(req *http.Request) (*models.Principal, error) {
|
||||
STSSecretAccessKey: claims.STSSecretAccessKey,
|
||||
STSSessionToken: claims.STSSessionToken,
|
||||
AccountAccessKey: claims.AccountAccessKey,
|
||||
AccountSecretKey: claims.AccountSecretKey,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -36,14 +36,14 @@ func TestNewJWTWithClaimsForClient(t *testing.T) {
|
||||
funcAssert := assert.New(t)
|
||||
// Test-1 : NewEncryptedTokenForClient() is generated correctly without errors
|
||||
function := "NewEncryptedTokenForClient()"
|
||||
token, err := NewEncryptedTokenForClient(creds, "", "", []string{""})
|
||||
token, err := NewEncryptedTokenForClient(creds, "", []string{""})
|
||||
if err != nil || token == "" {
|
||||
t.Errorf("Failed on %s:, error occurred: %s", function, err)
|
||||
}
|
||||
// saving token for future tests
|
||||
goodToken = token
|
||||
// Test-2 : NewEncryptedTokenForClient() throws error because of empty credentials
|
||||
if _, err = NewEncryptedTokenForClient(nil, "", "", []string{""}); err != nil {
|
||||
if _, err = NewEncryptedTokenForClient(nil, "", []string{""}); err != nil {
|
||||
funcAssert.Equal("provided credentials are empty", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,3 +228,14 @@ func GetAllCertificatesAndCAs() (*x509.CertPool, []*x509.Certificate, *xcerts.Ma
|
||||
logger.FatalIf(err, "Unable to load the TLS configuration")
|
||||
return GlobalRootCAs, globalPublicCerts, globalTLSCertsManager
|
||||
}
|
||||
|
||||
// AddCertificate check if Manager is initialized and then append a new certificate to it
|
||||
func AddCertificate(ctx context.Context, manager *xcerts.Manager, publicKey, privateKey string) (err error) {
|
||||
// If Cert Manager is not nil add more certificates
|
||||
if manager != nil {
|
||||
return manager.AddCertificate(publicKey, privateKey)
|
||||
}
|
||||
// Initialize cert manager
|
||||
manager, err = xcerts.NewManager(ctx, publicKey, privateKey, config.LoadX509KeyPair)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -113,11 +113,29 @@ type Gemalto struct {
|
||||
KeySecure *GemaltoKeySecure `yaml:"keysecure,omitempty"`
|
||||
}
|
||||
|
||||
type GcpCredentials struct {
|
||||
ClientEmail string `yaml:"client_email"`
|
||||
ClientID string `yaml:"client_id"`
|
||||
PrivateKeyID string `yaml:"private_key_id"`
|
||||
PrivateKey string `yaml:"private_key"`
|
||||
}
|
||||
|
||||
type GcpSecretManager struct {
|
||||
ProjectID string `yaml:"project_id"`
|
||||
Endpoint string `yaml:"endpoint,omitempty"`
|
||||
Credentials *GcpCredentials `yaml:"credentials,omitempty"`
|
||||
}
|
||||
|
||||
type Gcp struct {
|
||||
SecretManager *GcpSecretManager `yaml:"secretmanager,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"`
|
||||
}
|
||||
|
||||
type ServerConfig struct {
|
||||
|
||||
@@ -23,13 +23,17 @@ import (
|
||||
"github.com/minio/minio/pkg/licverifier"
|
||||
)
|
||||
|
||||
func TestGetLicenseInfoFromJWT(t *testing.T) {
|
||||
license := "eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZW5pbitjMUBtaW5pby5pbyIsInRlYW1OYW1lIjoiY29uc29sZS1jdXN0b21lciIsImV4cCI6MS42Mzk5NTI2MTE2MDkxNDQ3MzJlOSwiaXNzIjoic3VibmV0QG1pbmlvLmlvIiwiY2FwYWNpdHkiOjI1LCJpYXQiOjEuNjA4NDE2NjExNjA5MTQ0NzMyZTksImFjY291bnRJZCI6MTc2LCJzZXJ2aWNlVHlwZSI6IlNUQU5EQVJEIn0.ndtf8V_FJTvhXeemVLlORyDev6RJaSPhZ2djkMVK9SvXD0srR_qlYJATPjC4NljkS71nXMGVDov5uCTuUL97x6FGQEKDruA-z24x_2Zr8kof4LfBb3HUHudCR8QvE--I"
|
||||
publicKeys := []string{`-----BEGIN PUBLIC KEY-----
|
||||
var (
|
||||
license = "eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJrYW5hZ2FyYWorYzFAbWluaW8uaW8iLCJjYXAiOjUwLCJvcmciOiJHcmluZ290dHMgSW5jLiIsImV4cCI6MS42NDE0NDYxNjkwMDExOTg4OTRlOSwicGxhbiI6IlNUQU5EQVJEIiwiaXNzIjoic3VibmV0QG1pbi5pbyIsImFpZCI6MSwiaWF0IjoxLjYwOTkxMDE2OTAwMTE5ODg5NGU5fQ.EhTL2xwMHnUoLQF4UR-5bjUCja3whseLU5mb9XEj7PvAae6HEIDCOMEF8Hhh20DN_v_LRE283j2ZlA5zulcXSZXS0CLcrKqbVy6QLvZfvvLuerOjJI-NBa9dSJWJ0WoN"
|
||||
|
||||
publicKeys = []string{`-----BEGIN PUBLIC KEY-----
|
||||
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEbo+e1wpBY4tBq9AONKww3Kq7m6QP/TBQ
|
||||
mr/cKCUyBL7rcAvg0zNq1vcSrUSGlAmY3SEDCu3GOKnjG/U4E7+p957ocWSV+mQU
|
||||
9NKlTdQFGF3+aO6jbQ4hX/S5qPyF+a3z
|
||||
-----END PUBLIC KEY-----`}
|
||||
)
|
||||
|
||||
func TestGetLicenseInfoFromJWT(t *testing.T) {
|
||||
|
||||
mockLicense, _ := GetLicenseInfoFromJWT(license, publicKeys)
|
||||
|
||||
@@ -54,7 +58,7 @@ mr/cKCUyBL7rcAvg0zNq1vcSrUSGlAmY3SEDCu3GOKnjG/U4E7+p957ocWSV+mQU
|
||||
{
|
||||
name: "error because invalid license",
|
||||
args: args{
|
||||
license: "eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZW5pbitjMUBtaW5pby5pbyIsInRlYW1OYW1lIjoiY29uc29sZS1jdXN0b21lciIsImV4cCI6MS42Mzk5NTI2MTE2MDkxNDQ3MzJlOSwiaXNzIjoic3VibmV0QG1pbmlvLmlvIiwiY2FwYWNpdHkiOjI1LCJpYXQiOjEuNjA4NDE2NjExNjA5MTQ0NzMyZTksImFjY291bnRJZCI6MTc2LCJzZXJ2aWNlVHlwZSI6IlNUQU5EQVJEIn0.ndtf8V_FJTvhXeemVLlORyDev6RJaSPhZ2djkMVK9SvXD0srR_qlYJATPjC4NljkS71nXMGVDov5uCTuUL97x6FGQEKDruA-z24x_2Zr8kof4LfBb3HUHudCR8QvE--I",
|
||||
license: license,
|
||||
publicKeys: []string{"eaeaeae"},
|
||||
},
|
||||
wantErr: true,
|
||||
@@ -62,12 +66,8 @@ mr/cKCUyBL7rcAvg0zNq1vcSrUSGlAmY3SEDCu3GOKnjG/U4E7+p957ocWSV+mQU
|
||||
{
|
||||
name: "license successfully verified",
|
||||
args: args{
|
||||
license: "eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZW5pbitjMUBtaW5pby5pbyIsInRlYW1OYW1lIjoiY29uc29sZS1jdXN0b21lciIsImV4cCI6MS42Mzk5NTI2MTE2MDkxNDQ3MzJlOSwiaXNzIjoic3VibmV0QG1pbmlvLmlvIiwiY2FwYWNpdHkiOjI1LCJpYXQiOjEuNjA4NDE2NjExNjA5MTQ0NzMyZTksImFjY291bnRJZCI6MTc2LCJzZXJ2aWNlVHlwZSI6IlNUQU5EQVJEIn0.ndtf8V_FJTvhXeemVLlORyDev6RJaSPhZ2djkMVK9SvXD0srR_qlYJATPjC4NljkS71nXMGVDov5uCTuUL97x6FGQEKDruA-z24x_2Zr8kof4LfBb3HUHudCR8QvE--I",
|
||||
publicKeys: []string{`-----BEGIN PUBLIC KEY-----
|
||||
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEbo+e1wpBY4tBq9AONKww3Kq7m6QP/TBQ
|
||||
mr/cKCUyBL7rcAvg0zNq1vcSrUSGlAmY3SEDCu3GOKnjG/U4E7+p957ocWSV+mQU
|
||||
9NKlTdQFGF3+aO6jbQ4hX/S5qPyF+a3z
|
||||
-----END PUBLIC KEY-----`},
|
||||
license: license,
|
||||
publicKeys: publicKeys,
|
||||
},
|
||||
wantErr: false,
|
||||
want: mockLicense,
|
||||
|
||||
@@ -30,7 +30,8 @@ const (
|
||||
// Constants for subnet configuration
|
||||
ConsoleSubnetURL = "CONSOLE_SUBNET_URL"
|
||||
// Subnet endpoints
|
||||
publicKey = "/downloads/license-pubkey.pem"
|
||||
loginEndpoint = "/api/auth/login"
|
||||
licenseKeyEndpoint = "/api/auth/subscription/license-key"
|
||||
publicKey = "/downloads/license-pubkey.pem"
|
||||
loginEndpoint = "/api/auth/login"
|
||||
refreshLicenseKeyEndpoint = "/api/auth/subscription/renew-license"
|
||||
licenseKeyEndpoint = "/api/auth/subscription/license-key"
|
||||
)
|
||||
|
||||
@@ -67,6 +67,41 @@ type subnetLicenseResponse struct {
|
||||
Metadata LicenseMetadata `json:"metadata"`
|
||||
}
|
||||
|
||||
// subnetLoginRequest body request for subnet login
|
||||
type subnetRefreshRequest struct {
|
||||
License string `json:"license"`
|
||||
}
|
||||
|
||||
// getNewLicenseFromExistingLicense will perform license refresh based on the provided license key
|
||||
func getNewLicenseFromExistingLicense(client cluster.HTTPClientI, licenseKey string) (string, error) {
|
||||
request := subnetRefreshRequest{
|
||||
License: licenseKey,
|
||||
}
|
||||
// http body for login request
|
||||
payloadBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
subnetURL := GetSubnetURL()
|
||||
url := fmt.Sprintf("%s%s", subnetURL, refreshLicenseKeyEndpoint)
|
||||
resp, err := client.Post(url, "application/json", bytes.NewReader(payloadBytes))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
bodyBytes, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
subnetLicense := &subnetLicenseResponse{}
|
||||
// Parse subnet login response
|
||||
err = json.Unmarshal(bodyBytes, subnetLicense)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return subnetLicense.License, nil
|
||||
}
|
||||
|
||||
// getLicenseFromCredentials will perform authentication against subnet using
|
||||
// user provided credentials and return the current subnet license key
|
||||
func getLicenseFromCredentials(client cluster.HTTPClientI, username, password string) (string, error) {
|
||||
@@ -171,3 +206,18 @@ func ValidateLicense(client cluster.HTTPClientI, licenseKey, email, password str
|
||||
}
|
||||
return licInfo, license, nil
|
||||
}
|
||||
|
||||
func RefreshLicense(client cluster.HTTPClientI, licenseKey string) (licInfo *licverifier.LicenseInfo, license string, err error) {
|
||||
if licenseKey != "" {
|
||||
license, err = getNewLicenseFromExistingLicense(client, licenseKey)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
licenseInfo, rawLicense, err := ValidateLicense(client, license, "", "")
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
return licenseInfo, rawLicense, nil
|
||||
}
|
||||
return nil, "", errors.New("invalid license")
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"errors"
|
||||
@@ -138,7 +139,7 @@ func Test_getLicenseFromCredentials(t *testing.T) {
|
||||
username: "valid",
|
||||
password: "valid",
|
||||
},
|
||||
want: "eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZW5pbitjMUBtaW5pby5pbyIsInRlYW1OYW1lIjoiY29uc29sZS1jdXN0b21lciIsImV4cCI6MS42Mzk5NTI2MTE2MDkxNDQ3MzJlOSwiaXNzIjoic3VibmV0QG1pbmlvLmlvIiwiY2FwYWNpdHkiOjI1LCJpYXQiOjEuNjA4NDE2NjExNjA5MTQ0NzMyZTksImFjY291bnRJZCI6MTc2LCJzZXJ2aWNlVHlwZSI6IlNUQU5EQVJEIn0.ndtf8V_FJTvhXeemVLlORyDev6RJaSPhZ2djkMVK9SvXD0srR_qlYJATPjC4NljkS71nXMGVDov5uCTuUL97x6FGQEKDruA-z24x_2Zr8kof4LfBb3HUHudCR8QvE--I",
|
||||
want: license,
|
||||
wantErr: false,
|
||||
mockFunc: func() {
|
||||
HTTPPostMock = func(url, contentType string, body io.Reader) (resp *http.Response, err error) {
|
||||
@@ -147,7 +148,7 @@ func Test_getLicenseFromCredentials(t *testing.T) {
|
||||
}
|
||||
HTTPDoMock = func(req *http.Request) (*http.Response, error) {
|
||||
// returning test jwt license
|
||||
return &http.Response{Body: ioutil.NopCloser(bytes.NewReader([]byte("{\"license\":\"eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZW5pbitjMUBtaW5pby5pbyIsInRlYW1OYW1lIjoiY29uc29sZS1jdXN0b21lciIsImV4cCI6MS42Mzk5NTI2MTE2MDkxNDQ3MzJlOSwiaXNzIjoic3VibmV0QG1pbmlvLmlvIiwiY2FwYWNpdHkiOjI1LCJpYXQiOjEuNjA4NDE2NjExNjA5MTQ0NzMyZTksImFjY291bnRJZCI6MTc2LCJzZXJ2aWNlVHlwZSI6IlNUQU5EQVJEIn0.ndtf8V_FJTvhXeemVLlORyDev6RJaSPhZ2djkMVK9SvXD0srR_qlYJATPjC4NljkS71nXMGVDov5uCTuUL97x6FGQEKDruA-z24x_2Zr8kof4LfBb3HUHudCR8QvE--I\",\"metadata\":{\"email\":\"lenin+c1@minio.io\",\"issuer\":\"subnet@minio.io\",\"accountId\":176,\"teamName\":\"console-customer\",\"serviceType\":\"STANDARD\",\"capacity\":25,\"requestedAt\":\"2020-12-19T22:23:31.609144732Z\",\"expiresAt\":\"2021-12-19T22:23:31.609144732Z\"}}")))}, nil
|
||||
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
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -282,11 +283,7 @@ func TestValidateLicense(t *testing.T) {
|
||||
wantErr: true,
|
||||
mockFunc: func() {
|
||||
HTTPGetMock = func(url string) (resp *http.Response, err error) {
|
||||
return &http.Response{Body: ioutil.NopCloser(bytes.NewReader([]byte(`-----BEGIN PUBLIC KEY-----
|
||||
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEbo+e1wpBY4tBq9AONKww3Kq7m6QP/TBQ
|
||||
mr/cKCUyBL7rcAvg0zNq1vcSrUSGlAmY3SEDCu3GOKnjG/U4E7+p957ocWSV+mQU
|
||||
9NKlTdQFGF3+aO6jbQ4hX/S5qPyF+a3z
|
||||
-----END PUBLIC KEY-----`)))}, nil
|
||||
return &http.Response{Body: ioutil.NopCloser(strings.NewReader(publicKeys[0]))}, nil
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -294,21 +291,17 @@ mr/cKCUyBL7rcAvg0zNq1vcSrUSGlAmY3SEDCu3GOKnjG/U4E7+p957ocWSV+mQU
|
||||
name: "license validated successfully",
|
||||
args: args{
|
||||
client: clientMock,
|
||||
licenseKey: "eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZW5pbitjMUBtaW5pby5pbyIsInRlYW1OYW1lIjoiY29uc29sZS1jdXN0b21lciIsImV4cCI6MS42Mzk5NTI2MTE2MDkxNDQ3MzJlOSwiaXNzIjoic3VibmV0QG1pbmlvLmlvIiwiY2FwYWNpdHkiOjI1LCJpYXQiOjEuNjA4NDE2NjExNjA5MTQ0NzMyZTksImFjY291bnRJZCI6MTc2LCJzZXJ2aWNlVHlwZSI6IlNUQU5EQVJEIn0.ndtf8V_FJTvhXeemVLlORyDev6RJaSPhZ2djkMVK9SvXD0srR_qlYJATPjC4NljkS71nXMGVDov5uCTuUL97x6FGQEKDruA-z24x_2Zr8kof4LfBb3HUHudCR8QvE--I",
|
||||
licenseKey: license,
|
||||
email: "",
|
||||
password: "",
|
||||
},
|
||||
wantErr: false,
|
||||
mockFunc: func() {
|
||||
HTTPGetMock = func(url string) (resp *http.Response, err error) {
|
||||
return &http.Response{Body: ioutil.NopCloser(bytes.NewReader([]byte(`-----BEGIN PUBLIC KEY-----
|
||||
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEbo+e1wpBY4tBq9AONKww3Kq7m6QP/TBQ
|
||||
mr/cKCUyBL7rcAvg0zNq1vcSrUSGlAmY3SEDCu3GOKnjG/U4E7+p957ocWSV+mQU
|
||||
9NKlTdQFGF3+aO6jbQ4hX/S5qPyF+a3z
|
||||
-----END PUBLIC KEY-----`)))}, nil
|
||||
return &http.Response{Body: ioutil.NopCloser(strings.NewReader(publicKeys[0]))}, nil
|
||||
}
|
||||
},
|
||||
wantLicense: "eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZW5pbitjMUBtaW5pby5pbyIsInRlYW1OYW1lIjoiY29uc29sZS1jdXN0b21lciIsImV4cCI6MS42Mzk5NTI2MTE2MDkxNDQ3MzJlOSwiaXNzIjoic3VibmV0QG1pbmlvLmlvIiwiY2FwYWNpdHkiOjI1LCJpYXQiOjEuNjA4NDE2NjExNjA5MTQ0NzMyZTksImFjY291bnRJZCI6MTc2LCJzZXJ2aWNlVHlwZSI6IlNUQU5EQVJEIn0.ndtf8V_FJTvhXeemVLlORyDev6RJaSPhZ2djkMVK9SvXD0srR_qlYJATPjC4NljkS71nXMGVDov5uCTuUL97x6FGQEKDruA-z24x_2Zr8kof4LfBb3HUHudCR8QvE--I",
|
||||
wantLicense: license,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
3
portal-ui/.gitignore
vendored
@@ -1,7 +1,6 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/build
|
||||
node_modules/
|
||||
/.pnp
|
||||
.pnp.js
|
||||
@@ -9,8 +8,6 @@ node_modules/
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
|
||||
@@ -3,5 +3,4 @@ default: build-static
|
||||
build-static:
|
||||
@echo "Building frontend static assets to 'build'"
|
||||
yarn build
|
||||
go-bindata-assetfs -pkg portal build/...
|
||||
|
||||
|
||||
10
portal-ui/assets.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package portalui
|
||||
|
||||
import "embed"
|
||||
|
||||
//go:embed build/*
|
||||
var fs embed.FS
|
||||
|
||||
func GetStaticAssets() embed.FS {
|
||||
return fs
|
||||
}
|
||||
1
portal-ui/build/agpl.svg
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
portal-ui/build/amqp.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
portal-ui/build/android-icon-144x144.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
portal-ui/build/android-icon-192x192.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
portal-ui/build/android-icon-36x36.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
portal-ui/build/android-icon-48x48.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
portal-ui/build/android-icon-72x72.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
portal-ui/build/android-icon-96x96.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
portal-ui/build/apple-icon-180x180.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
25
portal-ui/build/asset-manifest.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "/static/css/main.a19f3d53.chunk.css",
|
||||
"main.js": "/static/js/main.fa0873e1.chunk.js",
|
||||
"main.js.map": "/static/js/main.fa0873e1.chunk.js.map",
|
||||
"runtime-main.js": "/static/js/runtime-main.f48e99e5.js",
|
||||
"runtime-main.js.map": "/static/js/runtime-main.f48e99e5.js.map",
|
||||
"static/css/2.f324abd6.chunk.css": "/static/css/2.f324abd6.chunk.css",
|
||||
"static/js/2.44b7c49b.chunk.js": "/static/js/2.44b7c49b.chunk.js",
|
||||
"static/js/2.44b7c49b.chunk.js.map": "/static/js/2.44b7c49b.chunk.js.map",
|
||||
"index.html": "/index.html",
|
||||
"static/css/2.f324abd6.chunk.css.map": "/static/css/2.f324abd6.chunk.css.map",
|
||||
"static/css/main.a19f3d53.chunk.css.map": "/static/css/main.a19f3d53.chunk.css.map",
|
||||
"static/js/2.44b7c49b.chunk.js.LICENSE.txt": "/static/js/2.44b7c49b.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"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/js/runtime-main.f48e99e5.js",
|
||||
"static/css/2.f324abd6.chunk.css",
|
||||
"static/js/2.44b7c49b.chunk.js",
|
||||
"static/css/main.a19f3d53.chunk.css",
|
||||
"static/js/main.fa0873e1.chunk.js"
|
||||
]
|
||||
}
|
||||
BIN
portal-ui/build/elasticsearch.png
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
portal-ui/build/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
portal-ui/build/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
portal-ui/build/favicon-96x96.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
portal-ui/build/favicon.ico
Normal file
|
After Width: | Height: | Size: 22 KiB |
1
portal-ui/build/images/BG_Illustration.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 368.999 192.934"><defs><style>.cls-1{opacity:0.35;}.cls-12,.cls-15,.cls-16,.cls-17,.cls-2,.cls-5,.cls-6,.cls-7,.cls-8{opacity:0.5;}.cls-10,.cls-11,.cls-12,.cls-13,.cls-14,.cls-15,.cls-16,.cls-17,.cls-3,.cls-4,.cls-5,.cls-6,.cls-7,.cls-9{fill:none;stroke:#fff;stroke-miterlimit:10;}.cls-4{stroke-width:0.5px;}.cls-10,.cls-11,.cls-5,.cls-9{stroke-width:0.873px;}.cls-5{stroke-dasharray:2.619 2.182;}.cls-12,.cls-15,.cls-16,.cls-17,.cls-5,.cls-6,.cls-7,.cls-8{isolation:isolate;}.cls-6{stroke-width:0.715px;stroke-dasharray:2.144 1.786;}.cls-7{stroke-width:0.743px;stroke-dasharray:2.23 1.858;}.cls-10{stroke-dasharray:2.646 2.204;}.cls-11{stroke-dasharray:2.585 2.154;}.cls-12{stroke-width:0.828px;stroke-dasharray:2.484 2.07;}.cls-13{stroke-dasharray:2.984 2.487;}.cls-14{stroke-dasharray:2.773 2.311;}.cls-16{stroke-width:0.899px;}.cls-17{stroke-width:0.859px;}</style></defs><title>BG_Illustration</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><g id="BG_Illustration" data-name="BG Illustration" class="cls-1"><g id="Group_118" data-name="Group 118" class="cls-2"><path id="Path_56" data-name="Path 56" class="cls-3" d="M211.5,140.678l-52.726,29.078L79.687,126.139V29.652L132.411.571,211.5,44.188Z"/><path id="Path_58" data-name="Path 58" class="cls-3" d="M158.776,169.756V73.271L211.5,44.193,158.776,73.271,79.688,29.654"/><path id="Path_59" data-name="Path 59" class="cls-4" d="M84.681,41l69.1,38.11v79.3l-69.1-38.11Z"/><line id="Line_37" data-name="Line 37" class="cls-4" x1="106.25" y1="52.782" x2="106.25" y2="132.086"/><line id="Line_38" data-name="Line 38" class="cls-4" x1="153.783" y1="92.327" x2="106.25" y2="65.999"/><line id="Line_39" data-name="Line 39" class="cls-4" x1="153.783" y1="105.545" x2="106.25" y2="79.217"/><line id="Line_40" data-name="Line 40" class="cls-4" x1="153.783" y1="118.762" x2="106.25" y2="92.434"/><line id="Line_41" data-name="Line 41" class="cls-4" x1="153.783" y1="131.979" x2="106.25" y2="105.651"/><line id="Line_42" data-name="Line 42" class="cls-4" x1="153.783" y1="145.197" x2="106.25" y2="118.869"/><path id="Path_60" data-name="Path 60" class="cls-4" d="M166.723,151.031l38.8-22.487V62.916L166.723,85.4Z"/></g><path id="Path_62" data-name="Path 62" class="cls-5" d="M117.106,148.062l-76.18,43.33"/><path id="Path_63" data-name="Path 63" class="cls-6" d="M271.394,167.271l-44.483,25.3"/><path id="Path_64" data-name="Path 64" class="cls-7" d="M190.722,155.708l61.951,36.031"/><path id="Path_65" data-name="Path 65" class="cls-5" d="M237.7,36.385l28.182,17.229"/><g id="Path_66" data-name="Path 66" class="cls-8"><line class="cls-9" x1="362.563" y1="69.327" x2="361.42" y2="68.688"/><line class="cls-10" x1="359.496" y1="67.613" x2="305.418" y2="37.39"/><polyline class="cls-9" points="304.456 36.852 303.313 36.213 302.158 36.83"/><line class="cls-11" x1="300.258" y1="37.844" x2="213.418" y2="84.213"/><line class="cls-9" x1="212.468" y1="84.72" x2="211.313" y2="85.337"/></g><path id="Path_67" data-name="Path 67" class="cls-12" d="M79.648,192.571,31.786,166.344h-.868l-23.579,14.2"/><g id="Path_68" data-name="Path 68" class="cls-8"><line class="cls-3" x1="22.871" y1="84.641" x2="24.156" y2="83.867"/><line class="cls-13" x1="26.286" y1="82.584" x2="48.654" y2="69.113"/><polyline class="cls-3" points="49.719 68.471 51.004 67.698 52.307 68.441"/><line class="cls-14" x1="54.315" y1="69.585" x2="75.395" y2="81.606"/><line class="cls-3" x1="76.399" y1="82.178" x2="77.702" y2="82.921"/></g><circle id="Ellipse_11" data-name="Ellipse 11" class="cls-15" cx="4.092" cy="183.59" r="3.592"/><circle id="Ellipse_12" data-name="Ellipse 12" class="cls-15" cx="274.986" cy="165.477" r="3.592"/><ellipse id="Ellipse_13" data-name="Ellipse 13" class="cls-16" cx="364.957" cy="71.922" rx="3.592" ry="2.904"/><circle id="Ellipse_14" data-name="Ellipse 14" class="cls-15" cx="19.279" cy="87.681" r="3.592"/><ellipse id="Ellipse_15" data-name="Ellipse 15" class="cls-17" cx="234.106" cy="32.58" rx="3.592" ry="2.649"/></g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
67
portal-ui/build/images/BG_IllustrationDarker.svg
Normal file
@@ -0,0 +1,67 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 368.999 192.934">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1{opacity:0.35;}.cls-12,.cls-15,.cls-16,.cls-17,.cls-2,.cls-5,.cls-6,.cls-7,.cls-8{opacity:0.5;}.cls-10,.cls-11,.cls-12,.cls-13,.cls-14,.cls-15,.cls-16,.cls-17,.cls-3,.cls-4,.cls-5,.cls-6,.cls-7,.cls-9{fill:none;stroke:#707070;stroke-miterlimit:10;}.cls-4{stroke-width:1px;}.cls-10,.cls-11,.cls-5,.cls-9{stroke-width:1.2px;}.cls-5{stroke-dasharray:2.619
|
||||
2.182;}.cls-12,.cls-15,.cls-16,.cls-17,.cls-5,.cls-6,.cls-7,.cls-8{isolation:isolate;}.cls-6{stroke-width:1.6px;stroke-dasharray:2.144
|
||||
1.786;}.cls-7{stroke-width:1.6px;stroke-dasharray:2.23 1.858;}.cls-10{stroke-dasharray:2.646
|
||||
2.204;}.cls-11{stroke-dasharray:2.585 2.154;}.cls-12{stroke-width:1.8px;stroke-dasharray:2.484
|
||||
2.07;}.cls-13{stroke-dasharray:2.984 2.487;}.cls-14{stroke-dasharray:2.773
|
||||
2.311;}.cls-16{stroke-width:1.8px;}.cls-17{stroke-width:1.8px;}
|
||||
</style>
|
||||
</defs>
|
||||
<title>BG_Illustration</title>
|
||||
<g id="Layer_2" data-name="Layer 2">
|
||||
<g id="Layer_1-2" data-name="Layer 1">
|
||||
<g id="BG_Illustration" data-name="BG Illustration" class="cls-1">
|
||||
<g id="Group_118" data-name="Group 118" class="cls-2">
|
||||
<path id="Path_56" data-name="Path 56" class="cls-3"
|
||||
d="M211.5,140.678l-52.726,29.078L79.687,126.139V29.652L132.411.571,211.5,44.188Z"/>
|
||||
<path id="Path_58" data-name="Path 58" class="cls-3"
|
||||
d="M158.776,169.756V73.271L211.5,44.193,158.776,73.271,79.688,29.654"/>
|
||||
<path id="Path_59" data-name="Path 59" class="cls-4" d="M84.681,41l69.1,38.11v79.3l-69.1-38.11Z"/>
|
||||
<line id="Line_37" data-name="Line 37" class="cls-4" x1="106.25" y1="52.782" x2="106.25"
|
||||
y2="132.086"/>
|
||||
<line id="Line_38" data-name="Line 38" class="cls-4" x1="153.783" y1="92.327" x2="106.25"
|
||||
y2="65.999"/>
|
||||
<line id="Line_39" data-name="Line 39" class="cls-4" x1="153.783" y1="105.545" x2="106.25"
|
||||
y2="79.217"/>
|
||||
<line id="Line_40" data-name="Line 40" class="cls-4" x1="153.783" y1="118.762" x2="106.25"
|
||||
y2="92.434"/>
|
||||
<line id="Line_41" data-name="Line 41" class="cls-4" x1="153.783" y1="131.979" x2="106.25"
|
||||
y2="105.651"/>
|
||||
<line id="Line_42" data-name="Line 42" class="cls-4" x1="153.783" y1="145.197" x2="106.25"
|
||||
y2="118.869"/>
|
||||
<path id="Path_60" data-name="Path 60" class="cls-4"
|
||||
d="M166.723,151.031l38.8-22.487V62.916L166.723,85.4Z"/>
|
||||
</g>
|
||||
<path id="Path_62" data-name="Path 62" class="cls-5" d="M117.106,148.062l-76.18,43.33"/>
|
||||
<path id="Path_63" data-name="Path 63" class="cls-6" d="M271.394,167.271l-44.483,25.3"/>
|
||||
<path id="Path_64" data-name="Path 64" class="cls-7" d="M190.722,155.708l61.951,36.031"/>
|
||||
<path id="Path_65" data-name="Path 65" class="cls-5" d="M237.7,36.385l28.182,17.229"/>
|
||||
<g id="Path_66" data-name="Path 66" class="cls-8">
|
||||
<line class="cls-9" x1="362.563" y1="69.327" x2="361.42" y2="68.688"/>
|
||||
<line class="cls-10" x1="359.496" y1="67.613" x2="305.418" y2="37.39"/>
|
||||
<polyline class="cls-9" points="304.456 36.852 303.313 36.213 302.158 36.83"/>
|
||||
<line class="cls-11" x1="300.258" y1="37.844" x2="213.418" y2="84.213"/>
|
||||
<line class="cls-9" x1="212.468" y1="84.72" x2="211.313" y2="85.337"/>
|
||||
</g>
|
||||
<path id="Path_67" data-name="Path 67" class="cls-12"
|
||||
d="M79.648,192.571,31.786,166.344h-.868l-23.579,14.2"/>
|
||||
<g id="Path_68" data-name="Path 68" class="cls-8">
|
||||
<line class="cls-3" x1="22.871" y1="84.641" x2="24.156" y2="83.867"/>
|
||||
<line class="cls-13" x1="26.286" y1="82.584" x2="48.654" y2="69.113"/>
|
||||
<polyline class="cls-3" points="49.719 68.471 51.004 67.698 52.307 68.441"/>
|
||||
<line class="cls-14" x1="54.315" y1="69.585" x2="75.395" y2="81.606"/>
|
||||
<line class="cls-3" x1="76.399" y1="82.178" x2="77.702" y2="82.921"/>
|
||||
</g>
|
||||
<circle id="Ellipse_11" data-name="Ellipse 11" class="cls-15" cx="4.092" cy="183.59" r="3.592"/>
|
||||
<circle id="Ellipse_12" data-name="Ellipse 12" class="cls-15" cx="274.986" cy="165.477" r="3.592"/>
|
||||
<ellipse id="Ellipse_13" data-name="Ellipse 13" class="cls-16" cx="364.957" cy="71.922" rx="3.592"
|
||||
ry="2.904"/>
|
||||
<circle id="Ellipse_14" data-name="Ellipse 14" class="cls-15" cx="19.279" cy="87.681" r="3.592"/>
|
||||
<ellipse id="Ellipse_15" data-name="Ellipse 15" class="cls-17" cx="234.106" cy="32.58" rx="3.592"
|
||||
ry="2.649"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.1 KiB |
6
portal-ui/build/images/ob_bucket_clear.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="11.174" height="11" viewBox="0 0 11.174 11">
|
||||
<defs>
|
||||
<style>.a{fill:none;stroke:#081c42;stroke-linecap:round;}</style>
|
||||
</defs>
|
||||
<path class="a" d="M8.392,10H1.608L0,0H10Z" transform="translate(0.587 0.5)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 279 B |
6
portal-ui/build/images/ob_bucket_filled.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="11.174" height="11" viewBox="0 0 11.174 11">
|
||||
<defs>
|
||||
<style>.a{fill:#081c42;stroke:#081c42;stroke-linecap:round;}</style>
|
||||
</defs>
|
||||
<path class="a" d="M8.392,10H1.608L0,0H10Z" transform="translate(0.587 0.5)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 282 B |
10
portal-ui/build/images/ob_file_clear.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="11.442" height="15.302" viewBox="0 0 11.442 15.302">
|
||||
<defs>
|
||||
<style>.a,.b{fill:none;stroke:#081c42;}.b{stroke-linejoin:round;}</style>
|
||||
</defs>
|
||||
<g transform="translate(0.5 0.5)">
|
||||
<path class="a" d="M-12060-11667.842v14.261h10.442v-10.591l-3.671-3.67Z"
|
||||
transform="translate(12059.999 11667.883)"/>
|
||||
<path class="b" d="M-12051.353-11664.255v-3.639l3.528,3.639Z" transform="translate(12058.188 11667.894)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 515 B |
10
portal-ui/build/images/ob_file_filled.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="11.442" height="15.302" viewBox="0 0 11.442 15.302">
|
||||
<defs>
|
||||
<style>.a,.b{fill:#081c42;stroke:#081c42;}.b{stroke-linejoin:round;fill:#fff}</style>
|
||||
</defs>
|
||||
<g transform="translate(0.5 0.5)">
|
||||
<path class="a" d="M-12060-11667.842v14.261h10.442v-10.591l-3.671-3.67Z"
|
||||
transform="translate(12059.999 11667.883)"/>
|
||||
<path class="b" d="M-12051.353-11664.255v-3.639l3.528,3.639Z" transform="translate(12058.188 11667.894)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 527 B |
10
portal-ui/build/images/ob_folder_clear.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="15.999" height="13.999" viewBox="0 0 15.999 13.999">
|
||||
<defs>
|
||||
<style>.a{fill:none;stroke-linecap:square;}.b,.c{stroke:none;}.c{fill:#081c42;}</style>
|
||||
</defs>
|
||||
<g class="a" transform="translate(-0.001 0.001)">
|
||||
<path class="b" d="M0,14V0H8.572V2.411H16V14Z"/>
|
||||
<path class="c"
|
||||
d="M 15.00020027160645 12.99860000610352 L 15.00020027160645 3.411099910736084 L 8.571599960327148 3.411099910736084 L 7.571600437164307 3.411099910736084 L 7.571600437164307 2.411099910736084 L 7.571600437164307 0.9990998506546021 L 1.000900268554688 0.9990998506546021 L 1.000900268554688 2.411099910736084 L 1.000900268554688 12.99860000610352 L 15.00020027160645 12.99860000610352 M 16.00020027160645 13.99860000610352 L 0.0009002700680866838 13.99860000610352 L 0.0009002700680866838 2.411099910736084 L 0.0009002700680866838 -0.0009001312428154051 L 8.571599960327148 -0.0009001312428154051 L 8.571599960327148 2.411099910736084 L 16.00020027160645 2.411099910736084 L 16.00020027160645 13.99860000610352 Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
10
portal-ui/build/images/ob_folder_filled.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="15.999" height="13.999" viewBox="0 0 15.999 13.999">
|
||||
<defs>
|
||||
<style>.a{fill:none;stroke-linecap:square;}.b,.c{stroke:none;fill:#081c42}.c{fill:#081c42;}</style>
|
||||
</defs>
|
||||
<g class="a" transform="translate(-0.001 0.001)">
|
||||
<path class="b" d="M0,14V0H8.572V2.411H16V14Z"/>
|
||||
<path class="c"
|
||||
d="M 15.00020027160645 12.99860000610352 L 15.00020027160645 3.411099910736084 L 8.571599960327148 3.411099910736084 L 7.571600437164307 3.411099910736084 L 7.571600437164307 2.411099910736084 L 7.571600437164307 0.9990998506546021 L 1.000900268554688 0.9990998506546021 L 1.000900268554688 2.411099910736084 L 1.000900268554688 12.99860000610352 L 15.00020027160645 12.99860000610352 M 16.00020027160645 13.99860000610352 L 0.0009002700680866838 13.99860000610352 L 0.0009002700680866838 2.411099910736084 L 0.0009002700680866838 -0.0009001312428154051 L 8.571599960327148 -0.0009001312428154051 L 8.571599960327148 2.411099910736084 L 16.00020027160645 2.411099910736084 L 16.00020027160645 13.99860000610352 Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
1
portal-ui/build/index.html
Normal file
@@ -0,0 +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 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.f324abd6.chunk.css" rel="stylesheet"><link href="/static/css/main.a19f3d53.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></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.44b7c49b.chunk.js"></script><script src="/static/js/main.fa0873e1.chunk.js"></script></body></html>
|
||||
BIN
portal-ui/build/kafka.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
portal-ui/build/logo192.png
Normal file
|
After Width: | Height: | Size: 8.4 KiB |
BIN
portal-ui/build/logo512.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
41
portal-ui/build/manifest.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "MinIO Console",
|
||||
"icons": [
|
||||
{
|
||||
"src": "android-icon-36x36.png",
|
||||
"sizes": "36x36",
|
||||
"type": "image/png",
|
||||
"density": "0.75"
|
||||
},
|
||||
{
|
||||
"src": "android-icon-48x48.png",
|
||||
"sizes": "48x48",
|
||||
"type": "image/png",
|
||||
"density": "1.0"
|
||||
},
|
||||
{
|
||||
"src": "android-icon-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image/png",
|
||||
"density": "1.5"
|
||||
},
|
||||
{
|
||||
"src": "android-icon-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image/png",
|
||||
"density": "2.0"
|
||||
},
|
||||
{
|
||||
"src": "android-icon-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image/png",
|
||||
"density": "3.0"
|
||||
},
|
||||
{
|
||||
"src": "android-icon-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"density": "4.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
portal-ui/build/mqtt.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
portal-ui/build/mysql.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
portal-ui/build/nats.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
portal-ui/build/postgres.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
portal-ui/build/redis.png
Normal file
|
After Width: | Height: | Size: 47 KiB |
2
portal-ui/build/robots.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
148
portal-ui/build/safari-pinned-tab.svg
Normal file
@@ -0,0 +1,148 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="1344.000000pt" height="1344.000000pt" viewBox="0 0 1344.000000 1344.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.11, written by Peter Selinger 2001-2013
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,1344.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M7171 13408 c-35 -4 -87 -12 -117 -18 -30 -6 -56 -11 -59 -10 -3 0
|
||||
-19 -7 -35 -15 -17 -9 -30 -13 -30 -11 0 12 -265 -115 -280 -133 -3 -3 -24
|
||||
-19 -48 -34 -71 -46 -214 -196 -274 -287 -93 -144 -150 -293 -176 -460 -17
|
||||
-119 -2 -363 29 -450 1 -3 3 -9 5 -15 42 -141 95 -243 187 -365 23 -30 45 -59
|
||||
49 -65 34 -48 152 -181 244 -275 61 -63 129 -133 150 -156 54 -57 367 -384
|
||||
494 -515 93 -96 218 -226 500 -519 47 -48 137 -143 200 -211 63 -67 143 -152
|
||||
178 -188 104 -108 196 -221 255 -311 75 -116 173 -328 177 -382 1 -4 7 -22 15
|
||||
-41 14 -34 42 -167 53 -252 9 -70 8 -328 -2 -400 -14 -110 -77 -347 -97 -370
|
||||
-5 -5 -9 -15 -9 -22 0 -21 -72 -163 -126 -249 -36 -58 -77 -119 -83 -124 -3
|
||||
-3 -25 -28 -49 -57 -43 -53 -159 -169 -200 -200 -13 -10 -36 -27 -50 -39 -108
|
||||
-85 -380 -234 -392 -214 -3 4 -5 580 -4 1279 l0 1270 -105 -55 c-57 -30 -109
|
||||
-58 -115 -63 -6 -4 -36 -22 -66 -38 -141 -77 -319 -186 -498 -306 -75 -51
|
||||
-141 -94 -147 -96 -5 -2 -15 -9 -22 -15 -29 -26 -43 -36 -70 -53 -51 -32 -292
|
||||
-215 -329 -250 -7 -7 -17 -13 -22 -13 -6 0 -12 -3 -14 -7 -1 -5 -28 -28 -58
|
||||
-53 -30 -25 -60 -49 -66 -55 -6 -5 -36 -30 -65 -55 -46 -38 -80 -68 -155 -135
|
||||
-169 -151 -434 -411 -434 -426 0 -5 -7 -9 -15 -9 -8 0 -15 -3 -15 -7 0 -5 -25
|
||||
-35 -56 -68 -102 -109 -180 -198 -291 -330 -95 -113 -100 -120 -143 -175 -19
|
||||
-25 -37 -47 -40 -50 -29 -26 -440 -610 -440 -626 0 -3 -43 -70 -57 -89 -5 -5
|
||||
-15 -23 -23 -40 -8 -16 -18 -32 -21 -35 -10 -9 -194 -335 -190 -339 1 -2 -1
|
||||
-7 -6 -10 -5 -3 -24 -37 -43 -76 -19 -38 -38 -73 -43 -76 -5 -3 -9 -10 -9 -15
|
||||
0 -5 -29 -67 -63 -139 -72 -150 -100 -211 -144 -315 -18 -41 -36 -84 -41 -95
|
||||
-43 -93 -212 -555 -204 -555 2 0 -2 -13 -11 -30 -8 -16 -15 -38 -15 -50 0 -11
|
||||
-4 -20 -8 -20 -5 0 -9 -6 -9 -13 0 -7 -16 -67 -37 -135 -20 -67 -39 -130 -41
|
||||
-140 -2 -9 -20 -80 -40 -156 -20 -77 -39 -151 -41 -165 -3 -14 -10 -44 -16
|
||||
-66 -6 -22 -11 -43 -10 -46 0 -3 -3 -22 -8 -42 -4 -20 -5 -36 -1 -34 51 24 87
|
||||
44 93 52 4 6 8 7 8 3 0 -6 284 135 305 152 6 5 14 8 18 8 8 1 339 164 347 172
|
||||
10 10 459 230 468 230 6 0 12 3 14 8 2 4 158 85 348 180 190 96 352 177 360
|
||||
182 8 4 29 14 45 21 17 8 33 18 37 24 4 5 8 6 8 1 0 -5 6 -4 13 2 17 14 335
|
||||
173 343 171 4 0 10 3 13 8 3 5 110 62 236 125 127 64 336 171 465 237 232 119
|
||||
318 161 327 161 3 0 3 -9 0 -20 -3 -11 -1 -22 4 -25 4 -3 5 -16 0 -28 -5 -12
|
||||
-5 -31 -1 -42 4 -11 5 -26 2 -34 -7 -19 -7 -80 1 -87 3 -3 1 -18 -4 -33 -6
|
||||
-14 -10 -27 -9 -28 9 -15 17 -63 10 -63 -4 0 -4 -16 0 -35 4 -19 5 -35 1 -35
|
||||
-8 0 -6 -68 2 -76 3 -3 2 -17 -3 -30 -5 -13 -6 -25 -2 -28 5 -3 5 -30 2 -61
|
||||
-3 -31 -3 -58 2 -61 4 -3 3 -15 -2 -28 -5 -13 -6 -27 -3 -30 8 -7 10 -76 3
|
||||
-76 -7 0 -3 -77 4 -88 2 -4 1 -14 -4 -21 -4 -8 -4 -27 0 -42 5 -16 6 -29 2
|
||||
-29 -4 0 -7 -16 -7 -35 0 -19 2 -35 5 -35 3 0 5 -16 5 -35 0 -19 -2 -35 -5
|
||||
-35 -3 0 -4 -19 -2 -43 3 -48 5 -100 2 -107 -5 -17 -4 -280 2 -280 4 0 3 -13
|
||||
-2 -30 -5 -18 -5 -30 0 -30 6 0 6 -10 0 -25 -6 -15 -6 -26 1 -30 5 -4 7 -10 4
|
||||
-15 -7 -12 -10 -124 -3 -135 3 -6 2 -19 -2 -30 -4 -11 -4 -30 1 -41 4 -12 5
|
||||
-24 2 -28 -8 -8 -9 -276 -1 -276 4 0 3 -13 -2 -30 -5 -18 -5 -30 0 -30 6 0 6
|
||||
-10 0 -25 -6 -15 -6 -26 1 -30 5 -4 7 -10 4 -15 -5 -8 -9 -116 -5 -135 1 -5 1
|
||||
-14 0 -20 -5 -24 -3 -105 3 -111 3 -3 2 -16 -3 -29 -5 -13 -6 -26 -3 -29 8 -7
|
||||
10 -76 3 -76 -7 0 -3 -77 4 -88 2 -4 1 -14 -4 -21 -4 -8 -4 -27 0 -42 5 -16 6
|
||||
-29 2 -29 -4 0 -7 -16 -7 -35 0 -19 2 -35 5 -35 3 0 5 -16 5 -35 0 -19 -2 -35
|
||||
-5 -35 -7 0 -3 -77 4 -88 2 -4 1 -14 -4 -21 -4 -8 -4 -27 0 -42 5 -16 5 -29 0
|
||||
-29 -4 0 -4 -16 0 -35 4 -19 5 -35 1 -35 -8 0 -6 -68 2 -76 3 -3 2 -16 -3 -29
|
||||
-5 -13 -6 -26 -3 -29 5 -5 8 -80 3 -88 -5 -10 -4 -278 2 -278 4 0 3 -13 -2
|
||||
-30 -5 -18 -5 -30 0 -30 6 0 6 -10 0 -25 -6 -15 -6 -26 1 -30 5 -4 7 -10 4
|
||||
-15 -8 -13 -10 -128 -3 -136 4 -3 2 -18 -3 -33 -6 -14 -10 -27 -9 -28 9 -15
|
||||
17 -63 10 -63 -4 0 -4 -16 0 -35 4 -19 5 -35 1 -35 -8 0 -6 -68 2 -76 3 -3 2
|
||||
-17 -3 -30 -5 -13 -6 -25 -2 -28 5 -3 5 -30 2 -61 -3 -31 -3 -58 2 -61 4 -3 3
|
||||
-15 -2 -28 -5 -13 -6 -27 -3 -30 7 -7 10 -76 3 -76 -3 0 -4 -17 -2 -37 4 -55
|
||||
2 -124 -3 -133 -3 -5 -1 -11 5 -15 6 -4 7 -13 1 -23 -6 -11 -5 -24 1 -36 13
|
||||
-23 785 -796 796 -796 4 0 6 19 4 42 -1 24 -3 49 -2 56 0 6 0 19 0 27 0 8 0
|
||||
22 0 30 0 8 0 22 0 30 0 8 0 22 0 30 0 8 0 22 0 30 0 8 0 22 0 30 0 8 0 22 0
|
||||
30 0 8 0 22 0 30 0 8 0 22 0 30 0 8 0 22 0 30 0 8 0 22 0 30 0 8 0 22 0 30 0
|
||||
8 0 22 0 30 0 8 0 22 0 30 0 8 0 22 0 30 0 8 0 22 0 30 0 8 0 22 0 30 0 8 0
|
||||
21 0 28 -1 6 1 31 2 55 2 23 0 42 -4 42 -4 0 -3 14 2 30 5 17 5 30 0 30 -5 0
|
||||
-5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5
|
||||
17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30
|
||||
-5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0
|
||||
30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30
|
||||
0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5
|
||||
13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17
|
||||
5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5
|
||||
0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30
|
||||
5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0
|
||||
30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13
|
||||
0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5
|
||||
30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0
|
||||
-5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5
|
||||
17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30
|
||||
-5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 6 30 2 30 -8 0 -7 68 1
|
||||
76 3 3 2 17 -3 30 -6 14 -6 26 0 29 6 3 6 15 0 29 -5 13 -6 26 -4 29 8 8 10
|
||||
167 2 167 -4 0 -3 14 2 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5
|
||||
0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30
|
||||
5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0
|
||||
30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13
|
||||
0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5
|
||||
30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0
|
||||
-5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5
|
||||
17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30
|
||||
-5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0
|
||||
30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30
|
||||
0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5
|
||||
13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17
|
||||
5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5
|
||||
0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30
|
||||
5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0 30 -5 0 -5 13 0 30 5 17 5 30 0
|
||||
30 -4 0 -5 15 -1 33 4 17 4 47 0 65 -3 17 -3 32 2 32 4 0 4 13 -1 29 -4 15 -4
|
||||
34 0 42 5 7 5 20 0 29 -5 9 -5 22 0 30 5 8 5 21 0 30 -5 9 -5 22 0 30 5 8 5
|
||||
21 0 30 -5 9 -5 22 0 30 5 8 5 21 0 30 -5 9 -5 22 0 30 5 8 5 21 0 30 -4 8 -4
|
||||
22 0 31 5 8 5 21 0 29 -4 7 -4 24 0 36 5 13 6 26 1 28 -5 3 -6 17 -4 30 4 21
|
||||
33 39 172 109 266 135 574 311 627 358 11 11 23 19 27 19 8 0 26 15 141 115
|
||||
144 125 302 298 374 409 15 22 30 43 33 46 14 11 130 212 160 276 18 38 37 72
|
||||
43 76 6 4 8 8 4 8 -7 0 9 42 57 155 12 27 54 164 59 190 1 6 5 19 9 30 6 21 7
|
||||
25 31 140 60 297 53 661 -19 975 -8 36 -17 76 -20 89 -3 13 -10 31 -14 40 -5
|
||||
9 -9 18 -9 21 0 13 -24 93 -39 127 -9 21 -17 40 -18 43 -5 35 -111 254 -174
|
||||
359 -29 49 -104 162 -123 186 -4 6 -24 30 -43 55 -84 106 -109 133 -635 679
|
||||
-93 97 -406 423 -465 485 -69 72 -376 393 -455 476 -36 37 -137 143 -225 235
|
||||
-88 93 -170 177 -182 188 -13 12 -23 25 -23 31 0 5 -6 17 -13 25 -41 48 -65
|
||||
187 -46 269 11 52 41 122 51 122 5 0 8 6 8 13 0 24 116 119 176 145 117 50
|
||||
275 35 374 -37 37 -27 46 -36 295 -296 172 -179 189 -196 405 -425 74 -78 155
|
||||
-164 180 -190 25 -26 106 -111 180 -190 74 -78 158 -166 185 -195 28 -29 113
|
||||
-119 190 -200 77 -81 170 -178 206 -216 36 -37 123 -130 195 -205 71 -75 149
|
||||
-158 174 -183 25 -26 99 -105 165 -175 245 -260 297 -309 320 -300 8 3 15 11
|
||||
15 16 0 23 -24 94 -37 109 -7 8 -13 21 -13 27 0 6 -10 23 -23 39 -12 15 -33
|
||||
48 -46 73 -13 25 -29 52 -36 60 -7 8 -25 39 -41 67 -16 29 -32 53 -36 53 -5 0
|
||||
-8 9 -8 20 0 11 -3 20 -7 20 -8 0 -34 39 -60 90 -7 14 -21 39 -32 55 -87 140
|
||||
-121 198 -121 205 0 5 -3 10 -7 12 -5 2 -53 77 -107 168 -54 91 -127 211 -162
|
||||
267 -35 56 -64 106 -64 112 0 5 -3 11 -7 13 -11 4 -83 124 -83 136 0 6 -4 12
|
||||
-8 14 -7 3 -126 194 -201 322 -13 23 -32 53 -42 68 -11 14 -19 31 -19 37 0 6
|
||||
-4 11 -9 11 -5 0 -18 19 -30 43 -12 23 -35 62 -51 87 -30 46 -68 108 -85 141
|
||||
-5 11 -13 19 -17 19 -5 0 -8 4 -8 9 0 6 -27 52 -60 103 -34 51 -66 105 -73
|
||||
121 -6 15 -15 27 -19 27 -4 0 -8 7 -8 15 0 8 -4 15 -10 15 -5 0 -10 5 -10 11
|
||||
0 9 -155 245 -170 259 -3 3 -18 22 -34 43 -102 137 -309 304 -476 384 -79 38
|
||||
-114 53 -132 58 -5 2 -9 3 -10 5 -2 1 -10 3 -18 6 -8 2 -38 10 -67 18 -128 36
|
||||
-284 49 -412 34z m-292 -5345 c-4 -18 -3 -33 1 -33 4 0 4 -18 0 -40 -4 -22 -4
|
||||
-40 1 -40 5 0 4 -11 -1 -24 -5 -13 -6 -27 -2 -30 7 -8 5 -123 -3 -136 -3 -5
|
||||
-1 -11 4 -15 6 -3 7 -15 2 -28 -5 -12 -5 -32 0 -44 4 -12 4 -25 0 -27 -5 -3
|
||||
-6 -20 -2 -38 4 -18 4 -51 1 -73 -3 -22 -3 -53 0 -70 3 -16 3 -45 -1 -62 -4
|
||||
-18 -3 -33 1 -33 5 0 5 -13 0 -30 -5 -18 -5 -30 0 -30 6 0 6 -10 0 -24 -5 -13
|
||||
-6 -27 -2 -30 7 -8 5 -123 -3 -136 -3 -5 -1 -11 5 -15 6 -4 8 -11 4 -16 -8
|
||||
-13 -9 -107 -1 -115 3 -3 2 -16 -3 -29 -5 -13 -6 -26 -3 -29 8 -7 10 -76 3
|
||||
-76 -3 0 -4 -19 -2 -42 4 -51 4 -50 1 -111 -3 -72 -29 -103 -139 -160 -52 -27
|
||||
-129 -66 -170 -88 -41 -21 -80 -39 -87 -39 -6 0 -13 -3 -15 -7 -1 -5 -45 -29
|
||||
-96 -55 -51 -26 -141 -73 -200 -104 -225 -119 -303 -160 -507 -264 -115 -60
|
||||
-223 -115 -240 -124 -16 -9 -35 -16 -42 -16 -6 0 -13 -3 -15 -8 -1 -4 -77 -45
|
||||
-168 -91 -91 -46 -238 -121 -327 -167 -90 -46 -163 -79 -163 -73 0 13 117 245
|
||||
142 282 11 15 16 27 11 27 -4 0 -3 4 2 8 6 4 21 29 35 55 14 27 30 56 35 65 6
|
||||
10 34 58 63 107 84 143 90 151 201 320 92 140 236 347 266 382 5 6 21 26 35
|
||||
44 38 50 223 282 235 295 5 6 35 40 65 75 122 141 308 337 424 448 32 31 84
|
||||
81 116 111 65 62 174 159 215 192 15 12 37 31 49 42 11 12 55 48 96 81 41 33
|
||||
84 68 95 78 11 10 32 26 48 35 15 9 28 21 28 27 1 5 5 -8 8 -30 4 -22 3 -55 0
|
||||
-72z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 10 KiB |
2
portal-ui/build/static/css/2.f324abd6.chunk.css
Normal file
@@ -0,0 +1,2 @@
|
||||
.ReactVirtualized__Table__headerRow{font-weight:700;text-transform:uppercase}.ReactVirtualized__Table__headerRow,.ReactVirtualized__Table__row{display:flex;flex-direction:row;align-items:center}.ReactVirtualized__Table__headerTruncatedText{display:inline-block;max-width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.ReactVirtualized__Table__headerColumn,.ReactVirtualized__Table__rowColumn{margin-right:10px;min-width:0}.ReactVirtualized__Table__rowColumn{text-overflow:ellipsis;white-space:nowrap}.ReactVirtualized__Table__headerColumn:first-of-type,.ReactVirtualized__Table__rowColumn:first-of-type{margin-left:10px}.ReactVirtualized__Table__sortableHeaderColumn{cursor:pointer}.ReactVirtualized__Table__sortableHeaderIconContainer{display:flex;align-items:center}.ReactVirtualized__Table__sortableHeaderIcon{flex:0 0 24px;height:1em;width:1em;fill:currentColor}.react-grid-layout{position:relative;transition:height .2s ease}.react-grid-item{transition:all .2s ease;transition-property:left,top}.react-grid-item img{pointer-events:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.react-grid-item.cssTransforms{transition-property:transform}.react-grid-item.resizing{z-index:1;will-change:width,height}.react-grid-item.react-draggable-dragging{transition:none;z-index:3;will-change:transform}.react-grid-item.dropping{visibility:hidden}.react-grid-item.react-grid-placeholder{background:red;opacity:.2;transition-duration:.1s;z-index:2;-webkit-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.react-grid-item>.react-resizable-handle{position:absolute;width:20px;height:20px}.react-grid-item>.react-resizable-handle:after{content:"";position:absolute;right:3px;bottom:3px;width:5px;height:5px;border-right:2px solid rgba(0,0,0,.4);border-bottom:2px solid rgba(0,0,0,.4)}.react-resizable-hide>.react-resizable-handle{display:none}.react-grid-item>.react-resizable-handle.react-resizable-handle-sw{bottom:0;left:0;cursor:sw-resize;transform:rotate(90deg)}.react-grid-item>.react-resizable-handle.react-resizable-handle-se{bottom:0;right:0;cursor:se-resize}.react-grid-item>.react-resizable-handle.react-resizable-handle-nw{top:0;left:0;cursor:nw-resize;transform:rotate(180deg)}.react-grid-item>.react-resizable-handle.react-resizable-handle-ne{top:0;right:0;cursor:ne-resize;transform:rotate(270deg)}.react-grid-item>.react-resizable-handle.react-resizable-handle-e,.react-grid-item>.react-resizable-handle.react-resizable-handle-w{top:50%;margin-top:-10px;cursor:ew-resize}.react-grid-item>.react-resizable-handle.react-resizable-handle-w{left:0;transform:rotate(135deg)}.react-grid-item>.react-resizable-handle.react-resizable-handle-e{right:0;transform:rotate(315deg)}.react-grid-item>.react-resizable-handle.react-resizable-handle-n,.react-grid-item>.react-resizable-handle.react-resizable-handle-s{left:50%;margin-left:-10px;cursor:ns-resize}.react-grid-item>.react-resizable-handle.react-resizable-handle-n{top:0;transform:rotate(225deg)}.react-grid-item>.react-resizable-handle.react-resizable-handle-s{bottom:0;transform:rotate(45deg)}.react-resizable{position:relative}.react-resizable-handle{position:absolute;width:20px;height:20px;background-repeat:no-repeat;background-origin:content-box;box-sizing:border-box;background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOiNmZmZmZmYwMCIgd2lkdGg9IjYiIGhlaWdodD0iNiI+PHBhdGggZD0iTTYgNkgwVjQuMmg0LjJWMEg2djZ6IiBvcGFjaXR5PSIuMzAyIi8+PC9zdmc+");background-position:100% 100%;padding:0 3px 3px 0}.react-resizable-handle-sw{bottom:0;left:0;cursor:sw-resize;transform:rotate(90deg)}.react-resizable-handle-se{bottom:0;right:0;cursor:se-resize}.react-resizable-handle-nw{top:0;left:0;cursor:nw-resize;transform:rotate(180deg)}.react-resizable-handle-ne{top:0;right:0;cursor:ne-resize;transform:rotate(270deg)}.react-resizable-handle-e,.react-resizable-handle-w{top:50%;margin-top:-10px;cursor:ew-resize}.react-resizable-handle-w{left:0;transform:rotate(135deg)}.react-resizable-handle-e{right:0;transform:rotate(315deg)}.react-resizable-handle-n,.react-resizable-handle-s{left:50%;margin-left:-10px;cursor:ns-resize}.react-resizable-handle-n{top:0;transform:rotate(225deg)}.react-resizable-handle-s{bottom:0;transform:rotate(45deg)}
|
||||
/*# sourceMappingURL=2.f324abd6.chunk.css.map */
|
||||
1
portal-ui/build/static/css/2.f324abd6.chunk.css.map
Normal file
2
portal-ui/build/static/css/main.a19f3d53.chunk.css
Normal file
1
portal-ui/build/static/css/main.a19f3d53.chunk.css.map
Normal file
3
portal-ui/build/static/js/2.44b7c49b.chunk.js
Normal file
271
portal-ui/build/static/js/2.44b7c49b.chunk.js.LICENSE.txt
Normal file
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
object-assign
|
||||
(c) Sindre Sorhus
|
||||
@license MIT
|
||||
*/
|
||||
|
||||
/*!
|
||||
Copyright (c) 2017 Jed Watson.
|
||||
Licensed under the MIT License (MIT), see
|
||||
http://jedwatson.github.io/classnames
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Chart.js v2.9.4
|
||||
* https://www.chartjs.org
|
||||
* (c) 2020 Chart.js Contributors
|
||||
* Released under the MIT License
|
||||
*/
|
||||
|
||||
/*!
|
||||
* cookie
|
||||
* Copyright(c) 2012-2014 Roman Shtylman
|
||||
* Copyright(c) 2015 Douglas Christopher Wilson
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/*! Conditions:: INITIAL */
|
||||
|
||||
/*! Moment Duration Format v2.2.2
|
||||
* https://github.com/jsmreese/moment-duration-format
|
||||
* Date: 2018-02-16
|
||||
*
|
||||
* Duration format plugin function for the Moment.js library
|
||||
* http://momentjs.com/
|
||||
*
|
||||
* Copyright 2018 John Madhavan-Reese
|
||||
* Released under the MIT license
|
||||
*/
|
||||
|
||||
/*! Production:: $accept : expression $end */
|
||||
|
||||
/*! Production:: css_value : ANGLE */
|
||||
|
||||
/*! Production:: css_value : CHS */
|
||||
|
||||
/*! Production:: css_value : EMS */
|
||||
|
||||
/*! Production:: css_value : EXS */
|
||||
|
||||
/*! Production:: css_value : FREQ */
|
||||
|
||||
/*! Production:: css_value : LENGTH */
|
||||
|
||||
/*! Production:: css_value : PERCENTAGE */
|
||||
|
||||
/*! Production:: css_value : REMS */
|
||||
|
||||
/*! Production:: css_value : RES */
|
||||
|
||||
/*! Production:: css_value : SUB css_value */
|
||||
|
||||
/*! Production:: css_value : TIME */
|
||||
|
||||
/*! Production:: css_value : VHS */
|
||||
|
||||
/*! Production:: css_value : VMAXS */
|
||||
|
||||
/*! Production:: css_value : VMINS */
|
||||
|
||||
/*! Production:: css_value : VWS */
|
||||
|
||||
/*! Production:: css_variable : CSS_VAR LPAREN CSS_CPROP COMMA math_expression RPAREN */
|
||||
|
||||
/*! Production:: css_variable : CSS_VAR LPAREN CSS_CPROP RPAREN */
|
||||
|
||||
/*! Production:: expression : math_expression EOF */
|
||||
|
||||
/*! Production:: math_expression : LPAREN math_expression RPAREN */
|
||||
|
||||
/*! Production:: math_expression : NESTED_CALC LPAREN math_expression RPAREN */
|
||||
|
||||
/*! Production:: math_expression : SUB PREFIX SUB NESTED_CALC LPAREN math_expression RPAREN */
|
||||
|
||||
/*! Production:: math_expression : css_value */
|
||||
|
||||
/*! Production:: math_expression : css_variable */
|
||||
|
||||
/*! Production:: math_expression : math_expression ADD math_expression */
|
||||
|
||||
/*! Production:: math_expression : math_expression DIV math_expression */
|
||||
|
||||
/*! Production:: math_expression : math_expression MUL math_expression */
|
||||
|
||||
/*! Production:: math_expression : math_expression SUB math_expression */
|
||||
|
||||
/*! Production:: math_expression : value */
|
||||
|
||||
/*! Production:: value : NUMBER */
|
||||
|
||||
/*! Production:: value : SUB NUMBER */
|
||||
|
||||
/*! Rule:: $ */
|
||||
|
||||
/*! Rule:: (--[0-9a-z-A-Z-]*) */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)% */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)Hz\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)ch\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)cm\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)deg\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)dpcm\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)dpi\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)dppx\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)em\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)ex\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)grad\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)in\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)kHz\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)mm\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)ms\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)pc\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)pt\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)px\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)rad\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)rem\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)s\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)turn\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)vh\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)vmax\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)vmin\b */
|
||||
|
||||
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)vw\b */
|
||||
|
||||
/*! Rule:: ([a-z]+) */
|
||||
|
||||
/*! Rule:: (calc) */
|
||||
|
||||
/*! Rule:: (var) */
|
||||
|
||||
/*! Rule:: , */
|
||||
|
||||
/*! Rule:: - */
|
||||
|
||||
/*! Rule:: \( */
|
||||
|
||||
/*! Rule:: \) */
|
||||
|
||||
/*! Rule:: \* */
|
||||
|
||||
/*! Rule:: \+ */
|
||||
|
||||
/*! Rule:: \/ */
|
||||
|
||||
/*! Rule:: \s+ */
|
||||
|
||||
/*! decimal.js-light v2.5.1 https://github.com/MikeMcl/decimal.js-light/LICENCE */
|
||||
|
||||
/**
|
||||
* A better abstraction over CSS.
|
||||
*
|
||||
* @copyright Oleg Isonen (Slobodskoi) / Isonen 2014-present
|
||||
* @website https://github.com/cssinjs/jss
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/** @license React v0.20.1
|
||||
* scheduler.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v16.13.1
|
||||
* react-is.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v17.0.1
|
||||
* react-dom.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v17.0.1
|
||||
* react-is.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v17.0.1
|
||||
* react-jsx-runtime.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v17.0.1
|
||||
* react.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**!
|
||||
* @fileOverview Kickass library to create and place poppers near their reference elements.
|
||||
* @version 1.16.1-lts
|
||||
* @license
|
||||
* Copyright (c) 2016 Federico Zivolo and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
//! moment.js
|
||||