Removed Tools support (#3467)
- Removed Menu links for Support tools - Removed support in UI for registering cluster - Removed Subnet support - Removed Websockets for tools support - Removed Support endpoint - Removed Subnet support endpoints Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
@@ -1,57 +0,0 @@
|
||||
// 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 subnet
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
|
||||
"github.com/minio/pkg/v3/licverifier"
|
||||
)
|
||||
|
||||
// GetLicenseInfoFromJWT will return license metadata from a jwt string license
|
||||
func GetLicenseInfoFromJWT(license string, publicKeys []string) (*licverifier.LicenseInfo, error) {
|
||||
if license == "" {
|
||||
return nil, errors.New("license is not present")
|
||||
}
|
||||
for _, publicKey := range publicKeys {
|
||||
lv, err := licverifier.NewLicenseVerifier([]byte(publicKey))
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
continue
|
||||
}
|
||||
licInfo, err := lv.Verify(license)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
continue
|
||||
}
|
||||
return &licInfo, nil
|
||||
}
|
||||
return nil, errors.New("invalid license key")
|
||||
}
|
||||
|
||||
// MfaReq - JSON payload of the SUBNET mfa api
|
||||
type MfaReq struct {
|
||||
Username string `json:"username"`
|
||||
OTP string `json:"otp"`
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
type LoginResp struct {
|
||||
AccessToken string
|
||||
MfaToken string
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
// 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 subnet
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/minio/pkg/v3/licverifier"
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
type args struct {
|
||||
license string
|
||||
publicKeys []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *licverifier.LicenseInfo
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "error because missing license",
|
||||
args: args{
|
||||
license: "",
|
||||
publicKeys: OfflinePublicKeys,
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "error because invalid license",
|
||||
args: args{
|
||||
license: license,
|
||||
publicKeys: []string{"eaeaeae"},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "license successfully verified",
|
||||
args: args{
|
||||
license: license,
|
||||
publicKeys: publicKeys,
|
||||
},
|
||||
wantErr: false,
|
||||
want: mockLicense,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := GetLicenseInfoFromJWT(tt.args.license, tt.args.publicKeys)
|
||||
if !tt.wantErr {
|
||||
t.Skip()
|
||||
}
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("GetLicenseInfoFromJWT() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("GetLicenseInfoFromJWT() got = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
// 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 subnet
|
||||
|
||||
var OfflinePublicKeys = []string{
|
||||
`-----BEGIN PUBLIC KEY-----
|
||||
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEaK31xujr6/rZ7ZfXZh3SlwovjC+X8wGq
|
||||
qkltaKyTLRENd4w3IRktYYCRgzpDLPn/nrf7snV/ERO5qcI7fkEES34IVEr+2Uff
|
||||
JkO2PfyyAYEO/5dBlPh1Undu9WQl6J7B
|
||||
-----END PUBLIC KEY-----`, // https://subnet.min.io/downloads/license-pubkey.pem
|
||||
}
|
||||
|
||||
const (
|
||||
// Constants for subnet configuration
|
||||
ConsoleSubnetURL = "CONSOLE_SUBNET_URL"
|
||||
)
|
||||
@@ -1,131 +0,0 @@
|
||||
// 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 subnet
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"github.com/minio/console/pkg/http"
|
||||
|
||||
"github.com/minio/console/models"
|
||||
"github.com/minio/madmin-go/v3"
|
||||
mc "github.com/minio/mc/cmd"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
func LoginWithMFA(client http.ClientI, username, mfaToken, otp string) (*LoginResp, error) {
|
||||
mfaLoginReq := MfaReq{Username: username, OTP: otp, Token: mfaToken}
|
||||
resp, err := subnetPostReq(client, subnetMFAURL(), mfaLoginReq, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
token := gjson.Get(resp, "token_info.access_token")
|
||||
if token.Exists() {
|
||||
return &LoginResp{AccessToken: token.String(), MfaToken: ""}, nil
|
||||
}
|
||||
return nil, errors.New("access token not found in response")
|
||||
}
|
||||
|
||||
func Login(client http.ClientI, username, password string) (*LoginResp, error) {
|
||||
loginReq := map[string]string{
|
||||
"username": username,
|
||||
"password": password,
|
||||
}
|
||||
respStr, err := subnetPostReq(client, subnetLoginURL(), loginReq, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mfaRequired := gjson.Get(respStr, "mfa_required").Bool()
|
||||
if mfaRequired {
|
||||
mfaToken := gjson.Get(respStr, "mfa_token").String()
|
||||
if mfaToken == "" {
|
||||
return nil, errors.New("missing mfa token")
|
||||
}
|
||||
return &LoginResp{AccessToken: "", MfaToken: mfaToken}, nil
|
||||
}
|
||||
token := gjson.Get(respStr, "token_info.access_token")
|
||||
if token.Exists() {
|
||||
return &LoginResp{AccessToken: token.String(), MfaToken: ""}, nil
|
||||
}
|
||||
return nil, errors.New("access token not found in response")
|
||||
}
|
||||
|
||||
func GetOrganizations(client http.ClientI, token string) ([]*models.SubnetOrganization, error) {
|
||||
headers := subnetAuthHeaders(token)
|
||||
respStr, err := subnetGetReq(client, subnetOrgsURL(), headers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var organizations []*models.SubnetOrganization
|
||||
if err = json.Unmarshal([]byte(respStr), &organizations); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return organizations, nil
|
||||
}
|
||||
|
||||
type LicenseTokenConfig struct {
|
||||
APIKey string
|
||||
License string
|
||||
Proxy string
|
||||
}
|
||||
|
||||
func Register(client http.ClientI, admInfo madmin.InfoMessage, apiKey, token, accountID string) (*LicenseTokenConfig, error) {
|
||||
var headers map[string]string
|
||||
regInfo := GetClusterRegInfo(admInfo)
|
||||
regURL := subnetRegisterURL()
|
||||
if apiKey != "" {
|
||||
regURL += "?api_key=" + apiKey
|
||||
} else {
|
||||
if accountID == "" || token == "" {
|
||||
return nil, errors.New("missing accountID or authentication token")
|
||||
}
|
||||
headers = subnetAuthHeaders(token)
|
||||
regURL += "?aid=" + accountID
|
||||
}
|
||||
regToken, err := GenerateRegToken(regInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reqPayload := mc.ClusterRegistrationReq{Token: regToken}
|
||||
resp, err := subnetPostReq(client, regURL, reqPayload, headers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
respJSON := gjson.Parse(resp)
|
||||
subnetAPIKey := respJSON.Get("api_key").String()
|
||||
licenseJwt := respJSON.Get("license").String()
|
||||
|
||||
if subnetAPIKey != "" || licenseJwt != "" {
|
||||
return &LicenseTokenConfig{
|
||||
APIKey: subnetAPIKey,
|
||||
License: licenseJwt,
|
||||
}, nil
|
||||
}
|
||||
return nil, errors.New("subnet api key not found")
|
||||
}
|
||||
|
||||
func GetAPIKey(client http.ClientI, token string) (string, error) {
|
||||
resp, err := subnetGetReq(client, subnetAPIKeyURL(), subnetAuthHeaders(token))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
respJSON := gjson.Parse(resp)
|
||||
apiKey := respJSON.Get("api_key").String()
|
||||
return apiKey, nil
|
||||
}
|
||||
@@ -1,223 +0,0 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2023 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package subnet
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/mattn/go-ieproxy"
|
||||
xhttp "github.com/minio/console/pkg/http"
|
||||
"github.com/tidwall/gjson"
|
||||
|
||||
"github.com/minio/madmin-go/v3"
|
||||
mc "github.com/minio/mc/cmd"
|
||||
"github.com/minio/pkg/v3/env"
|
||||
)
|
||||
|
||||
const (
|
||||
subnetRespBodyLimit = 1 << 20 // 1 MiB
|
||||
)
|
||||
|
||||
func subnetBaseURL() string {
|
||||
return env.Get(ConsoleSubnetURL, "https://subnet.min.io")
|
||||
}
|
||||
|
||||
func subnetRegisterURL() string {
|
||||
return subnetBaseURL() + "/api/cluster/register"
|
||||
}
|
||||
|
||||
func subnetLoginURL() string {
|
||||
return subnetBaseURL() + "/api/auth/login"
|
||||
}
|
||||
|
||||
func subnetOrgsURL() string {
|
||||
return subnetBaseURL() + "/api/auth/organizations"
|
||||
}
|
||||
|
||||
func subnetMFAURL() string {
|
||||
return subnetBaseURL() + "/api/auth/mfa-login"
|
||||
}
|
||||
|
||||
func subnetAPIKeyURL() string {
|
||||
return subnetBaseURL() + "/api/auth/api-key"
|
||||
}
|
||||
|
||||
func LogWebhookURL() string {
|
||||
return subnetBaseURL() + "/api/logs"
|
||||
}
|
||||
|
||||
func UploadURL(uploadType string, filename string) string {
|
||||
return fmt.Sprintf("%s/api/%s/upload?filename=%s", subnetBaseURL(), uploadType, filename)
|
||||
}
|
||||
|
||||
func UploadAuthHeaders(apiKey string) map[string]string {
|
||||
return map[string]string{"x-subnet-api-key": apiKey}
|
||||
}
|
||||
|
||||
func GenerateRegToken(clusterRegInfo mc.ClusterRegistrationInfo) (string, error) {
|
||||
token, e := json.Marshal(clusterRegInfo)
|
||||
if e != nil {
|
||||
return "", e
|
||||
}
|
||||
|
||||
return base64.StdEncoding.EncodeToString(token), nil
|
||||
}
|
||||
|
||||
func subnetAuthHeaders(authToken string) map[string]string {
|
||||
return map[string]string{"Authorization": "Bearer " + authToken}
|
||||
}
|
||||
|
||||
func httpDo(client xhttp.ClientI, req *http.Request) (*http.Response, error) {
|
||||
return client.Do(req)
|
||||
}
|
||||
|
||||
func subnetReqDo(client xhttp.ClientI, r *http.Request, headers map[string]string) (string, error) {
|
||||
for k, v := range headers {
|
||||
r.Header.Add(k, v)
|
||||
}
|
||||
|
||||
ct := r.Header.Get("Content-Type")
|
||||
if len(ct) == 0 {
|
||||
r.Header.Add("Content-Type", "application/json")
|
||||
}
|
||||
|
||||
resp, e := httpDo(client, r)
|
||||
if e != nil {
|
||||
return "", e
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
respBytes, e := io.ReadAll(io.LimitReader(resp.Body, subnetRespBodyLimit))
|
||||
if e != nil {
|
||||
return "", e
|
||||
}
|
||||
respStr := string(respBytes)
|
||||
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
return respStr, nil
|
||||
}
|
||||
return respStr, fmt.Errorf("Request failed with code %d and errors: %s", resp.StatusCode, respStr)
|
||||
}
|
||||
|
||||
func subnetGetReq(client xhttp.ClientI, reqURL string, headers map[string]string) (string, error) {
|
||||
r, e := http.NewRequest(http.MethodGet, reqURL, nil)
|
||||
if e != nil {
|
||||
return "", e
|
||||
}
|
||||
return subnetReqDo(client, r, headers)
|
||||
}
|
||||
|
||||
func subnetPostReq(client xhttp.ClientI, reqURL string, payload interface{}, headers map[string]string) (string, error) {
|
||||
body, e := json.Marshal(payload)
|
||||
if e != nil {
|
||||
return "", e
|
||||
}
|
||||
r, e := http.NewRequest(http.MethodPost, reqURL, bytes.NewReader(body))
|
||||
if e != nil {
|
||||
return "", e
|
||||
}
|
||||
return subnetReqDo(client, r, headers)
|
||||
}
|
||||
|
||||
func GetClusterRegInfo(admInfo madmin.InfoMessage) mc.ClusterRegistrationInfo {
|
||||
return mc.GetClusterRegInfo(admInfo, admInfo.DeploymentID)
|
||||
}
|
||||
|
||||
func GetSubnetAPIKeyUsingLicense(lic string) (string, error) {
|
||||
return getSubnetAPIKeyUsingAuthHeaders(map[string]string{"x-subnet-license": lic})
|
||||
}
|
||||
|
||||
func getSubnetAPIKeyUsingAuthHeaders(authHeaders map[string]string) (string, error) {
|
||||
resp, e := subnetGetReqMC(subnetAPIKeyURL(), authHeaders)
|
||||
if e != nil {
|
||||
return "", e
|
||||
}
|
||||
return extractSubnetCred("api_key", gjson.Parse(resp))
|
||||
}
|
||||
|
||||
func extractSubnetCred(key string, resp gjson.Result) (string, error) {
|
||||
result := resp.Get(key)
|
||||
if result.Index == 0 {
|
||||
return "", fmt.Errorf("Couldn't extract %s from SUBNET response: %s", key, resp)
|
||||
}
|
||||
return result.String(), nil
|
||||
}
|
||||
|
||||
func subnetGetReqMC(reqURL string, headers map[string]string) (string, error) {
|
||||
r, e := http.NewRequest(http.MethodGet, reqURL, nil)
|
||||
if e != nil {
|
||||
return "", e
|
||||
}
|
||||
return subnetReqDoMC(r, headers)
|
||||
}
|
||||
|
||||
func subnetReqDoMC(r *http.Request, headers map[string]string) (string, error) {
|
||||
for k, v := range headers {
|
||||
r.Header.Add(k, v)
|
||||
}
|
||||
|
||||
ct := r.Header.Get("Content-Type")
|
||||
if len(ct) == 0 {
|
||||
r.Header.Add("Content-Type", "application/json")
|
||||
}
|
||||
|
||||
resp, e := httpClientSubnet(0).Do(r)
|
||||
if e != nil {
|
||||
return "", e
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
respBytes, e := io.ReadAll(io.LimitReader(resp.Body, subnetRespBodyLimit))
|
||||
if e != nil {
|
||||
return "", e
|
||||
}
|
||||
respStr := string(respBytes)
|
||||
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
return respStr, nil
|
||||
}
|
||||
return respStr, fmt.Errorf("Request failed with code %d with error: %s", resp.StatusCode, respStr)
|
||||
}
|
||||
|
||||
func httpClientSubnet(reqTimeout time.Duration) *http.Client {
|
||||
return &http.Client{
|
||||
Timeout: reqTimeout,
|
||||
Transport: &http.Transport{
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 10 * time.Second,
|
||||
}).DialContext,
|
||||
Proxy: ieproxy.GetProxyFunc(),
|
||||
TLSClientConfig: &tls.Config{
|
||||
// Can't use SSLv3 because of POODLE and BEAST
|
||||
// Can't use TLSv1.0 because of POODLE and BEAST using CBC cipher
|
||||
// Can't use TLSv1.1 because of RC4 cipher usage
|
||||
MinVersion: tls.VersionTLS12,
|
||||
},
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 10 * time.Second,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1,481 +0,0 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2023 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package subnet
|
||||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/minio/mc/cmd"
|
||||
)
|
||||
|
||||
func Test_subnetBaseURL(t *testing.T) {
|
||||
type args struct {
|
||||
env map[string]string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "default",
|
||||
args: args{
|
||||
env: nil,
|
||||
},
|
||||
want: "https://subnet.min.io",
|
||||
},
|
||||
{
|
||||
name: "with env",
|
||||
args: args{
|
||||
env: map[string]string{
|
||||
"CONSOLE_SUBNET_URL": "http://oorgle",
|
||||
},
|
||||
},
|
||||
want: "http://oorgle",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
if tt.args.env != nil {
|
||||
for k, v := range tt.args.env {
|
||||
os.Setenv(k, v)
|
||||
}
|
||||
}
|
||||
if got := subnetBaseURL(); got != tt.want {
|
||||
t.Errorf("subnetBaseURL() = %v, want %v", got, tt.want)
|
||||
}
|
||||
if tt.args.env != nil {
|
||||
for k := range tt.args.env {
|
||||
os.Unsetenv(k)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_subnetRegisterURL(t *testing.T) {
|
||||
type args struct {
|
||||
env map[string]string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "default",
|
||||
args: args{
|
||||
env: nil,
|
||||
},
|
||||
want: "https://subnet.min.io/api/cluster/register",
|
||||
},
|
||||
{
|
||||
name: "with env",
|
||||
args: args{
|
||||
env: map[string]string{
|
||||
"CONSOLE_SUBNET_URL": "http://oorgle",
|
||||
},
|
||||
},
|
||||
want: "http://oorgle/api/cluster/register",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if tt.args.env != nil {
|
||||
for k, v := range tt.args.env {
|
||||
os.Setenv(k, v)
|
||||
}
|
||||
}
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
if got := subnetRegisterURL(); got != tt.want {
|
||||
t.Errorf("subnetRegisterURL() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
if tt.args.env != nil {
|
||||
for k := range tt.args.env {
|
||||
os.Unsetenv(k)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_subnetLoginURL(t *testing.T) {
|
||||
type args struct {
|
||||
env map[string]string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "default",
|
||||
args: args{
|
||||
env: nil,
|
||||
},
|
||||
want: "https://subnet.min.io/api/auth/login",
|
||||
},
|
||||
{
|
||||
name: "with env",
|
||||
args: args{
|
||||
env: map[string]string{
|
||||
"CONSOLE_SUBNET_URL": "http://oorgle",
|
||||
},
|
||||
},
|
||||
want: "http://oorgle/api/auth/login",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if tt.args.env != nil {
|
||||
for k, v := range tt.args.env {
|
||||
os.Setenv(k, v)
|
||||
}
|
||||
}
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
if got := subnetLoginURL(); got != tt.want {
|
||||
t.Errorf("subnetLoginURL() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
if tt.args.env != nil {
|
||||
for k := range tt.args.env {
|
||||
os.Unsetenv(k)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_subnetOrgsURL(t *testing.T) {
|
||||
type args struct {
|
||||
env map[string]string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "default",
|
||||
args: args{
|
||||
env: nil,
|
||||
},
|
||||
want: "https://subnet.min.io/api/auth/organizations",
|
||||
},
|
||||
{
|
||||
name: "with env",
|
||||
args: args{
|
||||
env: map[string]string{
|
||||
"CONSOLE_SUBNET_URL": "http://oorgle",
|
||||
},
|
||||
},
|
||||
want: "http://oorgle/api/auth/organizations",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if tt.args.env != nil {
|
||||
for k, v := range tt.args.env {
|
||||
os.Setenv(k, v)
|
||||
}
|
||||
}
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
if got := subnetOrgsURL(); got != tt.want {
|
||||
t.Errorf("subnetOrgsURL() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
if tt.args.env != nil {
|
||||
for k := range tt.args.env {
|
||||
os.Unsetenv(k)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_subnetMFAURL(t *testing.T) {
|
||||
type args struct {
|
||||
env map[string]string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "default",
|
||||
args: args{
|
||||
env: nil,
|
||||
},
|
||||
want: "https://subnet.min.io/api/auth/mfa-login",
|
||||
},
|
||||
{
|
||||
name: "with env",
|
||||
args: args{
|
||||
env: map[string]string{
|
||||
"CONSOLE_SUBNET_URL": "http://oorgle",
|
||||
},
|
||||
},
|
||||
want: "http://oorgle/api/auth/mfa-login",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if tt.args.env != nil {
|
||||
for k, v := range tt.args.env {
|
||||
os.Setenv(k, v)
|
||||
}
|
||||
}
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
if got := subnetMFAURL(); got != tt.want {
|
||||
t.Errorf("subnetMFAURL() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
if tt.args.env != nil {
|
||||
for k := range tt.args.env {
|
||||
os.Unsetenv(k)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_subnetAPIKeyURL(t *testing.T) {
|
||||
type args struct {
|
||||
env map[string]string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "default",
|
||||
args: args{
|
||||
env: nil,
|
||||
},
|
||||
want: "https://subnet.min.io/api/auth/api-key",
|
||||
},
|
||||
{
|
||||
name: "with env",
|
||||
args: args{
|
||||
env: map[string]string{
|
||||
"CONSOLE_SUBNET_URL": "http://oorgle",
|
||||
},
|
||||
},
|
||||
want: "http://oorgle/api/auth/api-key",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if tt.args.env != nil {
|
||||
for k, v := range tt.args.env {
|
||||
os.Setenv(k, v)
|
||||
}
|
||||
}
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
if got := subnetAPIKeyURL(); got != tt.want {
|
||||
t.Errorf("subnetAPIKeyURL() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
if tt.args.env != nil {
|
||||
for k := range tt.args.env {
|
||||
os.Unsetenv(k)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLogWebhookURL(t *testing.T) {
|
||||
type args struct {
|
||||
env map[string]string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "default",
|
||||
args: args{
|
||||
env: nil,
|
||||
},
|
||||
want: "https://subnet.min.io/api/logs",
|
||||
},
|
||||
{
|
||||
name: "with env",
|
||||
args: args{
|
||||
env: map[string]string{
|
||||
"CONSOLE_SUBNET_URL": "http://oorgle",
|
||||
},
|
||||
},
|
||||
want: "http://oorgle/api/logs",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if tt.args.env != nil {
|
||||
for k, v := range tt.args.env {
|
||||
os.Setenv(k, v)
|
||||
}
|
||||
}
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
if got := LogWebhookURL(); got != tt.want {
|
||||
t.Errorf("LogWebhookURL() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
if tt.args.env != nil {
|
||||
for k := range tt.args.env {
|
||||
os.Unsetenv(k)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUploadURL(t *testing.T) {
|
||||
type args struct {
|
||||
env map[string]string
|
||||
uploadType string
|
||||
filename string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "default",
|
||||
args: args{
|
||||
env: nil,
|
||||
uploadType: "x",
|
||||
filename: "y.jpg",
|
||||
},
|
||||
want: "https://subnet.min.io/api/x/upload?filename=y.jpg",
|
||||
},
|
||||
{
|
||||
name: "with env",
|
||||
args: args{
|
||||
env: map[string]string{
|
||||
"CONSOLE_SUBNET_URL": "http://oorgle",
|
||||
},
|
||||
uploadType: "x",
|
||||
filename: "y.jpg",
|
||||
},
|
||||
want: "http://oorgle/api/x/upload?filename=y.jpg",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if tt.args.env != nil {
|
||||
for k, v := range tt.args.env {
|
||||
os.Setenv(k, v)
|
||||
}
|
||||
}
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
if got := UploadURL(tt.args.uploadType, tt.args.filename); got != tt.want {
|
||||
t.Errorf("UploadURL() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
if tt.args.env != nil {
|
||||
for k := range tt.args.env {
|
||||
os.Unsetenv(k)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUploadAuthHeaders(t *testing.T) {
|
||||
type args struct {
|
||||
apiKey string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want map[string]string
|
||||
}{
|
||||
{
|
||||
name: "basic",
|
||||
args: args{
|
||||
apiKey: "xx",
|
||||
},
|
||||
want: map[string]string{"x-subnet-api-key": "xx"},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
if got := UploadAuthHeaders(tt.args.apiKey); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("UploadAuthHeaders() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateRegToken(t *testing.T) {
|
||||
type args struct {
|
||||
clusterRegInfo cmd.ClusterRegistrationInfo
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "basic",
|
||||
args: args{
|
||||
clusterRegInfo: cmd.ClusterRegistrationInfo{
|
||||
DeploymentID: "x",
|
||||
ClusterName: "y",
|
||||
UsedCapacity: 1,
|
||||
Info: cmd.ClusterInfo{},
|
||||
},
|
||||
},
|
||||
want: "eyJkZXBsb3ltZW50X2lkIjoieCIsImNsdXN0ZXJfbmFtZSI6InkiLCJ1c2VkX2NhcGFjaXR5IjoxLCJpbmZvIjp7Im1pbmlvX3ZlcnNpb24iOiIiLCJub19vZl9zZXJ2ZXJfcG9vbHMiOjAsIm5vX29mX3NlcnZlcnMiOjAsIm5vX29mX2RyaXZlcyI6MCwibm9fb2ZfYnVja2V0cyI6MCwibm9fb2Zfb2JqZWN0cyI6MCwidG90YWxfZHJpdmVfc3BhY2UiOjAsInVzZWRfZHJpdmVfc3BhY2UiOjB9fQ==",
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
got, err := GenerateRegToken(tt.args.clusterRegInfo)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("GenerateRegToken() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if got != tt.want {
|
||||
t.Errorf("GenerateRegToken() got = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_subnetAuthHeaders(t *testing.T) {
|
||||
type args struct {
|
||||
authToken string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want map[string]string
|
||||
}{
|
||||
{
|
||||
name: "basic",
|
||||
args: args{
|
||||
authToken: "x",
|
||||
},
|
||||
want: map[string]string{"Authorization": "Bearer x"},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(_ *testing.T) {
|
||||
if got := subnetAuthHeaders(tt.args.authToken); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("subnetAuthHeaders() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user