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:
Alex
2024-11-05 14:56:53 -06:00
committed by GitHub
parent d425af3c85
commit 18e50975d4
127 changed files with 28 additions and 15228 deletions

View File

@@ -1,153 +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 api
import (
"context"
b64 "encoding/base64"
"encoding/json"
"errors"
"fmt"
"net/http"
"net/url"
"os"
"time"
"github.com/minio/console/pkg/logger"
"github.com/minio/console/pkg/utils"
subnet "github.com/minio/console/pkg/subnet"
mc "github.com/minio/mc/cmd"
"github.com/minio/websocket"
)
// startHealthInfo starts fetching mc.ServerHealthInfo and
// sends messages with the corresponding data on the websocket connection
func startHealthInfo(ctx context.Context, conn WSConn, client MinioAdmin, deadline *time.Duration) error {
if deadline == nil {
return errors.New("duration can't be nil on startHealthInfo")
}
// Fetch info of all servers (cluster or single server)
healthInfo, version, err := client.serverHealthInfo(ctx, *deadline)
if err != nil {
return err
}
compressedDiag, err := mc.TarGZHealthInfo(healthInfo, version)
if err != nil {
return err
}
encodedDiag := b64.StdEncoding.EncodeToString(compressedDiag)
type messageReport struct {
Encoded string `json:"encoded"`
ServerHealthInfo interface{} `json:"serverHealthInfo"`
SubnetResponse string `json:"subnetResponse"`
}
ctx = context.WithValue(ctx, utils.ContextClientIP, conn.remoteAddress())
err = sendHealthInfoToSubnet(ctx, compressedDiag, client)
report := messageReport{
Encoded: encodedDiag,
ServerHealthInfo: healthInfo,
SubnetResponse: mc.SubnetBaseURL() + "/health",
}
if err != nil {
report.SubnetResponse = fmt.Sprintf("Error: %s", err.Error())
}
message, err := json.Marshal(report)
if err != nil {
return err
}
// Send Message through websocket connection
return conn.writeMessage(websocket.TextMessage, message)
}
// getHealthInfoOptionsFromReq gets duration for startHealthInfo request
// path come as : `/health-info?deadline=2h`
func getHealthInfoOptionsFromReq(req *http.Request) (*time.Duration, error) {
deadlineDuration, err := time.ParseDuration(req.FormValue("deadline"))
if err != nil {
return nil, err
}
return &deadlineDuration, nil
}
func updateMcGlobals(subnetTokenConfig subnet.LicenseTokenConfig) error {
mc.GlobalDevMode = getConsoleDevMode()
if len(subnetTokenConfig.Proxy) > 0 {
proxyURL, e := url.Parse(subnetTokenConfig.Proxy)
if e != nil {
return e
}
mc.GlobalSubnetProxyURL = proxyURL
}
return nil
}
func sendHealthInfoToSubnet(ctx context.Context, compressedHealthInfo []byte, client MinioAdmin) error {
filename := fmt.Sprintf("health_%d.json.gz", time.Now().Unix())
subnetTokenConfig, e := GetSubnetKeyFromMinIOConfig(ctx, client)
if e != nil {
return e
}
e = updateMcGlobals(*subnetTokenConfig)
if e != nil {
return e
}
var apiKey string
if len(subnetTokenConfig.APIKey) != 0 {
apiKey = subnetTokenConfig.APIKey
} else {
apiKey, e = subnet.GetSubnetAPIKeyUsingLicense(subnetTokenConfig.License)
if e != nil {
return e
}
}
e = os.WriteFile(filename, compressedHealthInfo, 0o666)
if e != nil {
return e
}
headers := mc.SubnetAPIKeyAuthHeaders(apiKey)
resp, e := (&mc.SubnetFileUploader{
FilePath: filename,
ReqURL: mc.SubnetUploadURL("health"),
Headers: headers,
DeleteAfterUpload: true,
}).UploadFileToSubnet()
if e != nil {
// file gets deleted only if upload is successful
// so we delete explicitly here as we already have the bytes
logger.LogIf(ctx, os.Remove(filename))
return e
}
type SubnetResponse struct {
LicenseV2 string `json:"license_v2,omitempty"`
APIKey string `json:"api_key,omitempty"`
}
var subnetResp SubnetResponse
e = json.Unmarshal([]byte(resp), &subnetResp)
if e != nil {
return e
}
return nil
}

View File

@@ -1,147 +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 api
import (
"context"
"encoding/json"
"errors"
"reflect"
"testing"
"time"
madmin "github.com/minio/madmin-go/v3"
)
func Test_serverHealthInfo(t *testing.T) {
var testReceiver chan madmin.HealthInfo
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
client := AdminClientMock{}
mockWSConn := mockConn{}
deadlineDuration, _ := time.ParseDuration("1h")
type args struct {
deadline time.Duration
wsWriteMock func(messageType int, data []byte) error
mockMessages []madmin.HealthInfo
}
tests := []struct {
test string
args args
wantError error
}{
{
test: "Return simple health info, no errors",
args: args{
deadline: deadlineDuration,
mockMessages: []madmin.HealthInfo{{}, {}},
wsWriteMock: func(_ int, data []byte) error {
// mock connection WriteMessage() no error
// emulate that receiver gets the message written
var t madmin.HealthInfo
_ = json.Unmarshal(data, &t)
testReceiver <- t
return nil
},
},
wantError: nil,
},
{
test: "Return simple health info2, no errors",
args: args{
deadline: deadlineDuration,
mockMessages: []madmin.HealthInfo{{}},
wsWriteMock: func(_ int, data []byte) error {
// mock connection WriteMessage() no error
// emulate that receiver gets the message written
var t madmin.HealthInfo
_ = json.Unmarshal(data, &t)
testReceiver <- t
return nil
},
},
wantError: nil,
},
{
test: "Handle error on ws write",
args: args{
deadline: deadlineDuration,
mockMessages: []madmin.HealthInfo{{}},
wsWriteMock: func(_ int, data []byte) error {
// mock connection WriteMessage() no error
// emulate that receiver gets the message written
var t madmin.HealthInfo
_ = json.Unmarshal(data, &t)
return errors.New("error on write")
},
},
wantError: errors.New("error on write"),
},
{
test: "Handle error on health function",
args: args{
deadline: deadlineDuration,
mockMessages: []madmin.HealthInfo{
{
Error: "error on healthInfo",
},
},
wsWriteMock: func(_ int, data []byte) error {
// mock connection WriteMessage() no error
// emulate that receiver gets the message written
var t madmin.HealthInfo
_ = json.Unmarshal(data, &t)
return nil
},
},
wantError: nil,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.test, func(_ *testing.T) {
// make testReceiver channel
testReceiver = make(chan madmin.HealthInfo, len(tt.args.mockMessages))
// mock function same for all tests, changes mockMessages
minioServerHealthInfoMock = func(_ context.Context,
_ time.Duration,
) (interface{}, string, error) {
info := tt.args.mockMessages[0]
return info, madmin.HealthInfoVersion, nil
}
connWriteMessageMock = tt.args.wsWriteMock
err := startHealthInfo(ctx, mockWSConn, client, &deadlineDuration)
// close test mock channel
close(testReceiver)
// check that the TestReceiver got the same number of data from Console.
index := 0
for info := range testReceiver {
if !reflect.DeepEqual(info, tt.args.mockMessages[index]) {
t.Errorf("startHealthInfo() got: %v, want: %v", info, tt.args.mockMessages[index])
return
}
index++
}
if !reflect.DeepEqual(err, tt.wantError) {
t.Errorf("startHealthInfo() error: %v, wantError: %v", err, tt.wantError)
return
}
})
}
}

View File

@@ -1,118 +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 api
import (
"context"
"encoding/json"
"fmt"
"net/http"
"strconv"
"time"
"github.com/dustin/go-humanize"
"github.com/minio/madmin-go/v3"
"github.com/minio/websocket"
)
// getSpeedtesthOptionsFromReq gets duration, size & concurrent requests from a websocket
// path come as : `/speedtest?duration=2h&size=12MiB&concurrent=10`
func getSpeedtestOptionsFromReq(req *http.Request) (*madmin.SpeedtestOpts, error) {
optionsSet := madmin.SpeedtestOpts{}
queryPairs := req.URL.Query()
paramDuration := queryPairs.Get("duration")
if paramDuration == "" {
paramDuration = "10s"
}
duration, err := time.ParseDuration(paramDuration)
if err != nil {
return nil, fmt.Errorf("unable to parse duration: %s", paramDuration)
}
if duration <= 0 {
return nil, fmt.Errorf("duration cannot be 0 or negative")
}
optionsSet.Duration = duration
paramSize := queryPairs.Get("size")
if paramSize == "" {
paramSize = "64MiB"
}
size, err := humanize.ParseBytes(paramSize)
if err != nil {
return nil, fmt.Errorf("unable to parse object size")
}
optionsSet.Size = int(size)
paramConcurrent := queryPairs.Get("concurrent")
if paramConcurrent == "" {
paramConcurrent = "32"
}
concurrent, err := strconv.Atoi(paramConcurrent)
if err != nil {
return nil, fmt.Errorf("invalid concurrent value: %s", paramConcurrent)
}
if concurrent <= 0 {
return nil, fmt.Errorf("concurrency cannot be '0' or negative")
}
optionsSet.Concurrency = concurrent
autotune := queryPairs.Get("autotune")
if autotune == "true" {
optionsSet.Autotune = true
}
return &optionsSet, nil
}
func startSpeedtest(ctx context.Context, conn WSConn, client MinioAdmin, speedtestOpts *madmin.SpeedtestOpts) error {
speedtestRes, err := client.speedtest(ctx, *speedtestOpts)
if err != nil {
LogError("error initializing speedtest: %v", err)
return err
}
for result := range speedtestRes {
// Serializing message
bytes, err := json.Marshal(result)
if err != nil {
LogError("error serializing json: %v", err)
return err
}
// Send Message through websocket connection
err = conn.writeMessage(websocket.TextMessage, bytes)
if err != nil {
LogError("error writing speedtest response: %v", err)
return err
}
}
return nil
}

View File

@@ -1,435 +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 api
import (
"context"
"errors"
"fmt"
"net/http"
"net/url"
"os"
"github.com/minio/console/pkg/utils"
xhttp "github.com/minio/console/pkg/http"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/api/operations"
subnetApi "github.com/minio/console/api/operations/subnet"
"github.com/minio/console/models"
"github.com/minio/console/pkg/subnet"
"github.com/minio/madmin-go/v3"
)
func registerSubnetHandlers(api *operations.ConsoleAPI) {
// Get subnet login handler
api.SubnetSubnetLoginHandler = subnetApi.SubnetLoginHandlerFunc(func(params subnetApi.SubnetLoginParams, session *models.Principal) middleware.Responder {
resp, err := GetSubnetLoginResponse(session, params)
if err != nil {
return subnetApi.NewSubnetLoginDefault(err.Code).WithPayload(err.APIError)
}
return subnetApi.NewSubnetLoginOK().WithPayload(resp)
})
// Get subnet login with MFA handler
api.SubnetSubnetLoginMFAHandler = subnetApi.SubnetLoginMFAHandlerFunc(func(params subnetApi.SubnetLoginMFAParams, session *models.Principal) middleware.Responder {
resp, err := GetSubnetLoginWithMFAResponse(session, params)
if err != nil {
return subnetApi.NewSubnetLoginMFADefault(err.Code).WithPayload(err.APIError)
}
return subnetApi.NewSubnetLoginMFAOK().WithPayload(resp)
})
// Get subnet register
api.SubnetSubnetRegisterHandler = subnetApi.SubnetRegisterHandlerFunc(func(params subnetApi.SubnetRegisterParams, session *models.Principal) middleware.Responder {
err := GetSubnetRegisterResponse(session, params)
if err != nil {
return subnetApi.NewSubnetRegisterDefault(err.Code).WithPayload(err.APIError)
}
return subnetApi.NewSubnetRegisterOK()
})
// Get subnet info
api.SubnetSubnetInfoHandler = subnetApi.SubnetInfoHandlerFunc(func(params subnetApi.SubnetInfoParams, session *models.Principal) middleware.Responder {
resp, err := GetSubnetInfoResponse(session, params)
if err != nil {
return subnetApi.NewSubnetInfoDefault(err.Code).WithPayload(err.APIError)
}
return subnetApi.NewSubnetInfoOK().WithPayload(resp)
})
// Get subnet registration token
api.SubnetSubnetRegTokenHandler = subnetApi.SubnetRegTokenHandlerFunc(func(params subnetApi.SubnetRegTokenParams, session *models.Principal) middleware.Responder {
resp, err := GetSubnetRegTokenResponse(session, params)
if err != nil {
return subnetApi.NewSubnetRegTokenDefault(err.Code).WithPayload(err.APIError)
}
return subnetApi.NewSubnetRegTokenOK().WithPayload(resp)
})
api.SubnetSubnetAPIKeyHandler = subnetApi.SubnetAPIKeyHandlerFunc(func(params subnetApi.SubnetAPIKeyParams, session *models.Principal) middleware.Responder {
resp, err := GetSubnetAPIKeyResponse(session, params)
if err != nil {
return subnetApi.NewSubnetAPIKeyDefault(err.Code).WithPayload(err.APIError)
}
return subnetApi.NewSubnetAPIKeyOK().WithPayload(resp)
})
}
const EnvSubnetLicense = "CONSOLE_SUBNET_LICENSE"
func SubnetRegisterWithAPIKey(ctx context.Context, minioClient MinioAdmin, apiKey string) (bool, error) {
serverInfo, err := minioClient.serverInfo(ctx)
if err != nil {
return false, err
}
clientIP := utils.ClientIPFromContext(ctx)
registerResult, err := subnet.Register(GetConsoleHTTPClient(clientIP), serverInfo, apiKey, "", "")
if err != nil {
return false, err
}
// Keep existing subnet proxy if exists
subnetKey, err := GetSubnetKeyFromMinIOConfig(ctx, minioClient)
if err != nil {
return false, err
}
configStr := fmt.Sprintf("subnet license=%s api_key=%s proxy=%s", registerResult.License, registerResult.APIKey, subnetKey.Proxy)
_, err = minioClient.setConfigKV(ctx, configStr)
if err != nil {
return false, err
}
// cluster registered correctly
return true, nil
}
func SubnetLogin(client xhttp.ClientI, username, password string) (string, string, error) {
tokens, err := subnet.Login(client, username, password)
if err != nil {
return "", "", err
}
if tokens.MfaToken != "" {
// user needs to complete login flow using mfa
return "", tokens.MfaToken, nil
}
if tokens.AccessToken != "" {
// register token to minio
return tokens.AccessToken, "", nil
}
return "", "", errors.New("something went wrong")
}
func GetSubnetLoginResponse(session *models.Principal, params subnetApi.SubnetLoginParams) (*models.SubnetLoginResponse, *CodedAPIError) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
return subnetLoginResponse(ctx, AdminClient{Client: mAdmin}, params)
}
func subnetLoginResponse(ctx context.Context, minioClient MinioAdmin, params subnetApi.SubnetLoginParams) (*models.SubnetLoginResponse, *CodedAPIError) {
subnetHTTPClient, err := GetSubnetHTTPClient(ctx, minioClient)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
apiKey := params.Body.APIKey
if apiKey != "" {
registered, err := SubnetRegisterWithAPIKey(ctx, minioClient, apiKey)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
return &models.SubnetLoginResponse{
Registered: registered,
Organizations: []*models.SubnetOrganization{},
}, nil
}
username := params.Body.Username
password := params.Body.Password
if username != "" && password != "" {
token, mfa, err := SubnetLogin(subnetHTTPClient, username, password)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
return &models.SubnetLoginResponse{
MfaToken: mfa,
AccessToken: token,
Organizations: []*models.SubnetOrganization{},
}, nil
}
return nil, ErrorWithContext(ctx, ErrDefault)
}
type SubnetRegistration struct {
AccessToken string
MFAToken string
Organizations []models.SubnetOrganization
}
func SubnetLoginWithMFA(client xhttp.ClientI, username, mfaToken, otp string) (*models.SubnetLoginResponse, error) {
tokens, err := subnet.LoginWithMFA(client, username, mfaToken, otp)
if err != nil {
return nil, err
}
if tokens.AccessToken != "" {
organizations, errOrg := subnet.GetOrganizations(client, tokens.AccessToken)
if errOrg != nil {
return nil, errOrg
}
return &models.SubnetLoginResponse{
AccessToken: tokens.AccessToken,
Organizations: organizations,
}, nil
}
return nil, errors.New("something went wrong")
}
// GetSubnetHTTPClient will return a client with proxy if configured, otherwise will return the default console http client
func GetSubnetHTTPClient(ctx context.Context, minioClient MinioAdmin) (*xhttp.Client, error) {
clientIP := utils.ClientIPFromContext(ctx)
subnetKey, err := GetSubnetKeyFromMinIOConfig(ctx, minioClient)
if err != nil {
return nil, err
}
proxy := getSubnetProxy()
if subnetKey.Proxy != "" {
proxy = subnetKey.Proxy
}
tr := GlobalTransport.Clone()
if proxy != "" {
u, err := url.Parse(proxy)
if err != nil {
return nil, err
}
tr.Proxy = http.ProxyURL(u)
}
return &xhttp.Client{
Client: &http.Client{
Transport: &ConsoleTransport{
Transport: tr,
ClientIP: clientIP,
},
},
}, nil
}
func GetSubnetLoginWithMFAResponse(session *models.Principal, params subnetApi.SubnetLoginMFAParams) (*models.SubnetLoginResponse, *CodedAPIError) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
minioClient := AdminClient{Client: mAdmin}
return subnetLoginWithMFAResponse(ctx, minioClient, params)
}
func subnetLoginWithMFAResponse(ctx context.Context, minioClient MinioAdmin, params subnetApi.SubnetLoginMFAParams) (*models.SubnetLoginResponse, *CodedAPIError) {
subnetHTTPClient, err := GetSubnetHTTPClient(ctx, minioClient)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
resp, err := SubnetLoginWithMFA(subnetHTTPClient, *params.Body.Username, *params.Body.MfaToken, *params.Body.Otp)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
return resp, nil
}
func GetSubnetKeyFromMinIOConfig(ctx context.Context, minioClient MinioAdmin) (*subnet.LicenseTokenConfig, error) {
buf, err := minioClient.getConfigKV(ctx, madmin.SubnetSubSys)
if err != nil {
return nil, err
}
subSysConfigs, err := madmin.ParseServerConfigOutput(string(buf))
if err != nil {
return nil, err
}
for _, scfg := range subSysConfigs {
if scfg.Target == "" {
res := subnet.LicenseTokenConfig{}
res.APIKey, _ = scfg.Lookup("api_key")
res.License, _ = scfg.Lookup("license")
res.Proxy, _ = scfg.Lookup("proxy")
return &res, nil
}
}
return nil, errors.New("unable to find subnet configuration")
}
func GetSubnetRegister(ctx context.Context, minioClient MinioAdmin, httpClient xhttp.ClientI, params subnetApi.SubnetRegisterParams) error {
serverInfo, err := minioClient.serverInfo(ctx)
if err != nil {
return err
}
registerResult, err := subnet.Register(httpClient, serverInfo, "", *params.Body.Token, *params.Body.AccountID)
if err != nil {
return err
}
// Keep existing subnet proxy if exists
subnetKey, err := GetSubnetKeyFromMinIOConfig(ctx, minioClient)
if err != nil {
return err
}
configStr := fmt.Sprintf("subnet license=%s api_key=%s proxy=%s", registerResult.License, registerResult.APIKey, subnetKey.Proxy)
_, err = minioClient.setConfigKV(ctx, configStr)
if err != nil {
return err
}
return nil
}
func GetSubnetRegisterResponse(session *models.Principal, params subnetApi.SubnetRegisterParams) *CodedAPIError {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session)
if err != nil {
return ErrorWithContext(ctx, err)
}
adminClient := AdminClient{Client: mAdmin}
return subnetRegisterResponse(ctx, adminClient, params)
}
func subnetRegisterResponse(ctx context.Context, minioClient MinioAdmin, params subnetApi.SubnetRegisterParams) *CodedAPIError {
subnetHTTPClient, err := GetSubnetHTTPClient(ctx, minioClient)
if err != nil {
return ErrorWithContext(ctx, err)
}
err = GetSubnetRegister(ctx, minioClient, subnetHTTPClient, params)
if err != nil {
return ErrorWithContext(ctx, err)
}
return nil
}
var ErrSubnetLicenseNotFound = errors.New("license not found")
func GetSubnetInfoResponse(session *models.Principal, params subnetApi.SubnetInfoParams) (*models.License, *CodedAPIError) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
clientIP := utils.ClientIPFromContext(ctx)
client := &xhttp.Client{
Client: GetConsoleHTTPClient(clientIP),
}
// license gets seeded to us by MinIO
seededLicense := os.Getenv(EnvSubnetLicense)
// if it's missing, we will gracefully fallback to attempt to fetch it from MinIO
if seededLicense == "" {
mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
adminClient := AdminClient{Client: mAdmin}
configBytes, err := adminClient.getConfigKV(params.HTTPRequest.Context(), "subnet")
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
subSysConfigs, err := madmin.ParseServerConfigOutput(string(configBytes))
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
// search for licese
for _, v := range subSysConfigs {
for _, sv := range v.KV {
if sv.Key == "license" {
seededLicense = sv.Value
}
}
}
}
// still empty means not found
if seededLicense == "" {
return nil, ErrorWithContext(ctx, ErrSubnetLicenseNotFound)
}
licenseInfo, err := getLicenseInfo(*client.Client, seededLicense)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
license := &models.License{
Email: licenseInfo.Email,
AccountID: licenseInfo.AccountID,
StorageCapacity: licenseInfo.StorageCapacity,
Plan: licenseInfo.Plan,
ExpiresAt: licenseInfo.ExpiresAt.String(),
Organization: licenseInfo.Organization,
}
return license, nil
}
func GetSubnetRegToken(ctx context.Context, minioClient MinioAdmin) (string, error) {
serverInfo, err := minioClient.serverInfo(ctx)
if err != nil {
return "", err
}
regInfo := subnet.GetClusterRegInfo(serverInfo)
regToken, err := subnet.GenerateRegToken(regInfo)
if err != nil {
return "", err
}
return regToken, nil
}
func GetSubnetRegTokenResponse(session *models.Principal, params subnetApi.SubnetRegTokenParams) (*models.SubnetRegTokenResponse, *CodedAPIError) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
adminClient := AdminClient{Client: mAdmin}
return subnetRegTokenResponse(ctx, adminClient)
}
func subnetRegTokenResponse(ctx context.Context, minioClient MinioAdmin) (*models.SubnetRegTokenResponse, *CodedAPIError) {
token, err := GetSubnetRegToken(ctx, minioClient)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
return &models.SubnetRegTokenResponse{
RegToken: token,
}, nil
}
func GetSubnetAPIKeyResponse(session *models.Principal, params subnetApi.SubnetAPIKeyParams) (*models.APIKey, *CodedAPIError) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
adminClient := AdminClient{Client: mAdmin}
return subnetAPIKeyResponse(ctx, adminClient, params)
}
func subnetAPIKeyResponse(ctx context.Context, minioClient MinioAdmin, params subnetApi.SubnetAPIKeyParams) (*models.APIKey, *CodedAPIError) {
subnetHTTPClient, err := GetSubnetHTTPClient(ctx, minioClient)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
token := params.HTTPRequest.URL.Query().Get("token")
apiKey, err := subnet.GetAPIKey(subnetHTTPClient, token)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
return &models.APIKey{APIKey: apiKey}, nil
}

View File

@@ -1,233 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package api
import (
"context"
"net/http"
"net/http/httptest"
"net/url"
"os"
"testing"
"github.com/minio/console/api/operations"
subnetApi "github.com/minio/console/api/operations/subnet"
"github.com/minio/console/models"
"github.com/minio/madmin-go/v3"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
)
type AdminSubnetTestSuite struct {
suite.Suite
assert *assert.Assertions
currentServer string
isServerSet bool
server *httptest.Server
adminClient AdminClientMock
}
func (suite *AdminSubnetTestSuite) SetupSuite() {
suite.assert = assert.New(suite.T())
suite.adminClient = AdminClientMock{}
minioGetConfigKVMock = func(_ string) ([]byte, error) {
return []byte("subnet license=mock api_key=mock proxy=http://mock.com"), nil
}
MinioServerInfoMock = func(_ context.Context) (madmin.InfoMessage, error) {
return madmin.InfoMessage{Servers: []madmin.ServerProperties{{}}}, nil
}
}
func (suite *AdminSubnetTestSuite) SetupTest() {
suite.server = httptest.NewServer(http.HandlerFunc(suite.serverHandler))
suite.currentServer, suite.isServerSet = os.LookupEnv(ConsoleMinIOServer)
os.Setenv(ConsoleMinIOServer, suite.server.URL)
}
func (suite *AdminSubnetTestSuite) serverHandler(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(400)
}
func (suite *AdminSubnetTestSuite) TearDownSuite() {
}
func (suite *AdminSubnetTestSuite) TearDownTest() {
if suite.isServerSet {
os.Setenv(ConsoleMinIOServer, suite.currentServer)
} else {
os.Unsetenv(ConsoleMinIOServer)
}
}
func (suite *AdminSubnetTestSuite) TestRegisterSubnetHandlers() {
api := &operations.ConsoleAPI{}
suite.assertHandlersAreNil(api)
registerSubnetHandlers(api)
suite.assertHandlersAreNotNil(api)
}
func (suite *AdminSubnetTestSuite) assertHandlersAreNil(api *operations.ConsoleAPI) {
suite.assert.Nil(api.SubnetSubnetLoginHandler)
suite.assert.Nil(api.SubnetSubnetLoginMFAHandler)
suite.assert.Nil(api.SubnetSubnetRegisterHandler)
suite.assert.Nil(api.SubnetSubnetInfoHandler)
suite.assert.Nil(api.SubnetSubnetRegTokenHandler)
suite.assert.Nil(api.SubnetSubnetAPIKeyHandler)
}
func (suite *AdminSubnetTestSuite) assertHandlersAreNotNil(api *operations.ConsoleAPI) {
suite.assert.NotNil(api.SubnetSubnetLoginHandler)
suite.assert.NotNil(api.SubnetSubnetLoginMFAHandler)
suite.assert.NotNil(api.SubnetSubnetRegisterHandler)
suite.assert.NotNil(api.SubnetSubnetInfoHandler)
suite.assert.NotNil(api.SubnetSubnetRegTokenHandler)
suite.assert.NotNil(api.SubnetSubnetAPIKeyHandler)
}
func (suite *AdminSubnetTestSuite) TestSubnetLoginWithSubnetClientError() {
params, api := suite.initSubnetLoginRequest("", "", "")
response := api.SubnetSubnetLoginHandler.Handle(params, &models.Principal{})
_, ok := response.(*subnetApi.SubnetLoginDefault)
suite.assert.True(ok)
}
func (suite *AdminSubnetTestSuite) TestSubnetLoginResponseWithApiKeyError() {
params, _ := suite.initSubnetLoginRequest("mock", "", "")
res, err := subnetLoginResponse(context.TODO(), suite.adminClient, params)
suite.assert.NotNil(err)
suite.assert.Nil(res)
}
func (suite *AdminSubnetTestSuite) TestSubnetLoginResponseWithCredentialsError() {
params, _ := suite.initSubnetLoginRequest("", "mock", "mock")
res, err := subnetLoginResponse(context.TODO(), suite.adminClient, params)
suite.assert.NotNil(err)
suite.assert.Nil(res)
}
func (suite *AdminSubnetTestSuite) initSubnetLoginRequest(apiKey, username, password string) (params subnetApi.SubnetLoginParams, api operations.ConsoleAPI) {
registerSubnetHandlers(&api)
params.HTTPRequest = &http.Request{}
params.Body = &models.SubnetLoginRequest{}
params.Body.APIKey = apiKey
params.Body.Username = username
params.Body.Password = password
return params, api
}
func (suite *AdminSubnetTestSuite) TestSubnetLoginMFAWithSubnetClientError() {
params, api := suite.initSubnetLoginMFARequest("", "", "")
response := api.SubnetSubnetLoginMFAHandler.Handle(params, &models.Principal{})
_, ok := response.(*subnetApi.SubnetLoginMFADefault)
suite.assert.True(ok)
}
func (suite *AdminSubnetTestSuite) TestSubnetLoginWithMFAResponseError() {
params, _ := suite.initSubnetLoginMFARequest("mock", "mock", "mock")
res, err := subnetLoginWithMFAResponse(context.TODO(), suite.adminClient, params)
suite.assert.NotNil(err)
suite.assert.Nil(res)
}
func (suite *AdminSubnetTestSuite) initSubnetLoginMFARequest(username, mfaToken, otp string) (params subnetApi.SubnetLoginMFAParams, api operations.ConsoleAPI) {
registerSubnetHandlers(&api)
params.HTTPRequest = &http.Request{}
params.Body = &models.SubnetLoginMFARequest{}
params.Body.Username = &username
params.Body.MfaToken = &mfaToken
params.Body.Otp = &otp
return params, api
}
func (suite *AdminSubnetTestSuite) TestSubnetRegisterClientError() {
params, api := suite.initSubnetRegisterRequest("", "")
response := api.SubnetSubnetRegisterHandler.Handle(params, &models.Principal{})
_, ok := response.(*subnetApi.SubnetRegisterDefault)
suite.assert.True(ok)
}
func (suite *AdminSubnetTestSuite) TestSubnetRegisterResponseError() {
params, _ := suite.initSubnetRegisterRequest("mock", "mock")
err := subnetRegisterResponse(context.TODO(), suite.adminClient, params)
suite.assert.NotNil(err)
}
func (suite *AdminSubnetTestSuite) initSubnetRegisterRequest(token, accountID string) (params subnetApi.SubnetRegisterParams, api operations.ConsoleAPI) {
registerSubnetHandlers(&api)
params.HTTPRequest = &http.Request{}
params.Body = &models.SubnetRegisterRequest{}
params.Body.Token = &token
params.Body.AccountID = &accountID
return params, api
}
func (suite *AdminSubnetTestSuite) TestSubnetInfoError() {
params, api := suite.initSubnetInfoRequest()
response := api.SubnetSubnetInfoHandler.Handle(params, &models.Principal{})
_, ok := response.(*subnetApi.SubnetInfoDefault)
suite.assert.True(ok)
}
func (suite *AdminSubnetTestSuite) initSubnetInfoRequest() (params subnetApi.SubnetInfoParams, api operations.ConsoleAPI) {
registerSubnetHandlers(&api)
params.HTTPRequest = &http.Request{}
return params, api
}
func (suite *AdminSubnetTestSuite) TestSubnetRegTokenError() {
params, api := suite.initSubnetRegTokenRequest()
response := api.SubnetSubnetRegTokenHandler.Handle(params, &models.Principal{})
_, ok := response.(*subnetApi.SubnetRegTokenDefault)
suite.assert.True(ok)
}
func (suite *AdminSubnetTestSuite) TestSubnetRegTokenResponse() {
res, err := subnetRegTokenResponse(context.TODO(), suite.adminClient)
suite.assert.Nil(err)
suite.assert.NotEqual("", res)
}
func (suite *AdminSubnetTestSuite) initSubnetRegTokenRequest() (params subnetApi.SubnetRegTokenParams, api operations.ConsoleAPI) {
registerSubnetHandlers(&api)
params.HTTPRequest = &http.Request{}
return params, api
}
func (suite *AdminSubnetTestSuite) TestSubnetAPIKeyWithClientError() {
params, api := suite.initSubnetAPIKeyRequest()
response := api.SubnetSubnetAPIKeyHandler.Handle(params, &models.Principal{})
_, ok := response.(*subnetApi.SubnetAPIKeyDefault)
suite.assert.True(ok)
}
func (suite *AdminSubnetTestSuite) TestSubnetAPIKeyResponseError() {
params, _ := suite.initSubnetAPIKeyRequest()
res, err := subnetAPIKeyResponse(context.TODO(), suite.adminClient, params)
suite.assert.NotNil(err)
suite.assert.Nil(res)
}
func (suite *AdminSubnetTestSuite) initSubnetAPIKeyRequest() (params subnetApi.SubnetAPIKeyParams, api operations.ConsoleAPI) {
registerSubnetHandlers(&api)
params.HTTPRequest = &http.Request{}
params.HTTPRequest.URL = &url.URL{}
return params, api
}
func TestAdminSubnet(t *testing.T) {
suite.Run(t, new(AdminSubnetTestSuite))
}

View File

@@ -98,10 +98,6 @@ func getMinIOServer() string {
return strings.TrimSpace(env.Get(ConsoleMinIOServer, "http://localhost:9000"))
}
func getSubnetProxy() string {
return strings.TrimSpace(env.Get(ConsoleSubnetProxy, ""))
}
func GetMinIORegion() string {
return strings.TrimSpace(env.Get(ConsoleMinIORegion, ""))
}

View File

@@ -143,8 +143,6 @@ func configureAPI(api *operations.ConsoleAPI) http.Handler {
registerAdminBucketRemoteHandlers(api)
// Register admin log search
registerLogSearchHandlers(api)
// Register admin subnet handlers
registerSubnetHandlers(api)
// Register admin KMS handlers
registerKMSHandlers(api)
// Register admin IDP handlers
@@ -158,8 +156,6 @@ func configureAPI(api *operations.ConsoleAPI) http.Handler {
registerSiteReplicationHandler(api)
registerSiteReplicationStatusHandler(api)
// Register Support Handler
registerSupportHandlers(api)
// Operator Console
@@ -178,9 +174,6 @@ func configureAPI(api *operations.ConsoleAPI) http.Handler {
api.ServerShutdown = func() {}
// do an initial subnet plan caching
fetchLicensePlan()
return setupGlobalMiddleware(api.Serve(setupMiddlewares))
}
@@ -601,8 +594,6 @@ func replaceBaseInIndex(indexPageBytes []byte, basePath string) []byte {
func replaceLicense(indexPageBytes []byte) []byte {
indexPageStr := string(indexPageBytes)
newPlan := fmt.Sprintf("<meta name=\"minio-license\" content=\"%s\" />", InstanceLicensePlan.String())
indexPageStr = strings.Replace(indexPageStr, "<meta name=\"minio-license\" content=\"agpl\"/>", newPlan, 1)
indexPageBytes = []byte(indexPageStr)
return indexPageBytes
}

View File

@@ -30,7 +30,6 @@
// - multipart/form-data
//
// Produces:
// - application/zip
// - application/octet-stream
// - application/json
//

View File

@@ -3829,65 +3829,6 @@ func init() {
}
}
},
"/profiling/start": {
"post": {
"tags": [
"Profile"
],
"summary": "Start recording profile data",
"operationId": "ProfilingStart",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/profilingStartRequest"
}
}
],
"responses": {
"201": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/startProfilingList"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/profiling/stop": {
"post": {
"produces": [
"application/zip"
],
"tags": [
"Profile"
],
"summary": "Stop and download profile data",
"operationId": "ProfilingStop",
"responses": {
"201": {
"description": "A successful response.",
"schema": {
"type": "file"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/releases": {
"get": {
"tags": [
@@ -4373,230 +4314,6 @@ func init() {
}
}
},
"/subnet/apikey": {
"get": {
"tags": [
"Subnet"
],
"summary": "Subnet api key",
"operationId": "SubnetApiKey",
"parameters": [
{
"type": "string",
"name": "token",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/apiKey"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/subnet/info": {
"get": {
"tags": [
"Subnet"
],
"summary": "Subnet info",
"operationId": "SubnetInfo",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/license"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/subnet/login": {
"post": {
"tags": [
"Subnet"
],
"summary": "Login to SUBNET",
"operationId": "SubnetLogin",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/subnetLoginRequest"
}
}
],
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/subnetLoginResponse"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/subnet/login/mfa": {
"post": {
"tags": [
"Subnet"
],
"summary": "Login to SUBNET using mfa",
"operationId": "SubnetLoginMFA",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/subnetLoginMFARequest"
}
}
],
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/subnetLoginResponse"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/subnet/register": {
"post": {
"tags": [
"Subnet"
],
"summary": "Register cluster with Subnet",
"operationId": "SubnetRegister",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/subnetRegisterRequest"
}
}
],
"responses": {
"200": {
"description": "A successful response."
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/subnet/registration-token": {
"get": {
"tags": [
"Subnet"
],
"summary": "SUBNET registraton token",
"operationId": "SubnetRegToken",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/SubnetRegTokenResponse"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/support/callhome": {
"get": {
"tags": [
"Support"
],
"summary": "Get Callhome current status",
"operationId": "GetCallHomeOptionValue",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/callHomeGetResponse"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
},
"put": {
"tags": [
"Support"
],
"summary": "Sets callhome status",
"operationId": "SetCallHomeStatus",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/callHomeSetStatus"
}
}
],
"responses": {
"204": {
"description": "A successful response."
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/user/policy": {
"get": {
"tags": [
@@ -5049,14 +4766,6 @@ func init() {
}
}
},
"SubnetRegTokenResponse": {
"type": "object",
"properties": {
"regToken": {
"type": "string"
}
}
},
"aUserPolicyResponse": {
"type": "object",
"properties": {
@@ -8075,97 +7784,6 @@ func init() {
}
}
},
"subnetLoginMFARequest": {
"type": "object",
"required": [
"username",
"otp",
"mfa_token"
],
"properties": {
"mfa_token": {
"type": "string"
},
"otp": {
"type": "string"
},
"username": {
"type": "string"
}
}
},
"subnetLoginRequest": {
"type": "object",
"properties": {
"apiKey": {
"type": "string"
},
"password": {
"type": "string"
},
"username": {
"type": "string"
}
}
},
"subnetLoginResponse": {
"type": "object",
"properties": {
"access_token": {
"type": "string"
},
"mfa_token": {
"type": "string"
},
"organizations": {
"type": "array",
"items": {
"$ref": "#/definitions/subnetOrganization"
}
},
"registered": {
"type": "boolean"
}
}
},
"subnetOrganization": {
"type": "object",
"properties": {
"accountId": {
"type": "integer"
},
"company": {
"type": "string"
},
"isAccountOwner": {
"type": "boolean"
},
"shortName": {
"type": "string"
},
"subscriptionStatus": {
"type": "string"
},
"userId": {
"type": "integer"
}
}
},
"subnetRegisterRequest": {
"type": "object",
"required": [
"token",
"account_id"
],
"properties": {
"account_id": {
"type": "string"
},
"token": {
"type": "string"
}
}
},
"tier": {
"type": "object",
"properties": {
@@ -12593,65 +12211,6 @@ func init() {
}
}
},
"/profiling/start": {
"post": {
"tags": [
"Profile"
],
"summary": "Start recording profile data",
"operationId": "ProfilingStart",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/profilingStartRequest"
}
}
],
"responses": {
"201": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/startProfilingList"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/profiling/stop": {
"post": {
"produces": [
"application/zip"
],
"tags": [
"Profile"
],
"summary": "Stop and download profile data",
"operationId": "ProfilingStop",
"responses": {
"201": {
"description": "A successful response.",
"schema": {
"type": "file"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/releases": {
"get": {
"tags": [
@@ -13145,230 +12704,6 @@ func init() {
}
}
},
"/subnet/apikey": {
"get": {
"tags": [
"Subnet"
],
"summary": "Subnet api key",
"operationId": "SubnetApiKey",
"parameters": [
{
"type": "string",
"name": "token",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/apiKey"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/subnet/info": {
"get": {
"tags": [
"Subnet"
],
"summary": "Subnet info",
"operationId": "SubnetInfo",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/license"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/subnet/login": {
"post": {
"tags": [
"Subnet"
],
"summary": "Login to SUBNET",
"operationId": "SubnetLogin",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/subnetLoginRequest"
}
}
],
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/subnetLoginResponse"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/subnet/login/mfa": {
"post": {
"tags": [
"Subnet"
],
"summary": "Login to SUBNET using mfa",
"operationId": "SubnetLoginMFA",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/subnetLoginMFARequest"
}
}
],
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/subnetLoginResponse"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/subnet/register": {
"post": {
"tags": [
"Subnet"
],
"summary": "Register cluster with Subnet",
"operationId": "SubnetRegister",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/subnetRegisterRequest"
}
}
],
"responses": {
"200": {
"description": "A successful response."
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/subnet/registration-token": {
"get": {
"tags": [
"Subnet"
],
"summary": "SUBNET registraton token",
"operationId": "SubnetRegToken",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/SubnetRegTokenResponse"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/support/callhome": {
"get": {
"tags": [
"Support"
],
"summary": "Get Callhome current status",
"operationId": "GetCallHomeOptionValue",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/callHomeGetResponse"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
},
"put": {
"tags": [
"Support"
],
"summary": "Sets callhome status",
"operationId": "SetCallHomeStatus",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/callHomeSetStatus"
}
}
],
"responses": {
"204": {
"description": "A successful response."
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/ApiError"
}
}
}
}
},
"/user/policy": {
"get": {
"tags": [
@@ -13929,14 +13264,6 @@ func init() {
}
}
},
"SubnetRegTokenResponse": {
"type": "object",
"properties": {
"regToken": {
"type": "string"
}
}
},
"WidgetDetailsOptions": {
"type": "object",
"properties": {
@@ -16987,97 +16314,6 @@ func init() {
}
}
},
"subnetLoginMFARequest": {
"type": "object",
"required": [
"username",
"otp",
"mfa_token"
],
"properties": {
"mfa_token": {
"type": "string"
},
"otp": {
"type": "string"
},
"username": {
"type": "string"
}
}
},
"subnetLoginRequest": {
"type": "object",
"properties": {
"apiKey": {
"type": "string"
},
"password": {
"type": "string"
},
"username": {
"type": "string"
}
}
},
"subnetLoginResponse": {
"type": "object",
"properties": {
"access_token": {
"type": "string"
},
"mfa_token": {
"type": "string"
},
"organizations": {
"type": "array",
"items": {
"$ref": "#/definitions/subnetOrganization"
}
},
"registered": {
"type": "boolean"
}
}
},
"subnetOrganization": {
"type": "object",
"properties": {
"accountId": {
"type": "integer"
},
"company": {
"type": "string"
},
"isAccountOwner": {
"type": "boolean"
},
"shortName": {
"type": "string"
},
"subscriptionStatus": {
"type": "string"
},
"userId": {
"type": "integer"
}
}
},
"subnetRegisterRequest": {
"type": "object",
"required": [
"token",
"account_id"
],
"properties": {
"account_id": {
"type": "string"
},
"token": {
"type": "string"
}
}
},
"tier": {
"type": "object",
"properties": {

View File

@@ -1,81 +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 api
import (
"net/http"
"os"
"github.com/minio/pkg/v3/licverifier"
"github.com/minio/pkg/v3/subnet"
)
type SubnetPlan int
const (
PlanAGPL SubnetPlan = iota
PlanStandard
PlanEnterprise
PlanEnterpriseLite
PlanEnterprisePlus
)
func (sp SubnetPlan) String() string {
switch sp {
case PlanStandard:
return "standard"
case PlanEnterprise:
return "enterprise"
case PlanEnterpriseLite:
return "enterprise-lite"
case PlanEnterprisePlus:
return "enterprise-plus"
default:
return "agpl"
}
}
var InstanceLicensePlan = PlanAGPL
func getLicenseInfo(client http.Client, license string) (*licverifier.LicenseInfo, error) {
lv := subnet.LicenseValidator{
Client: client,
ExpiryGracePeriod: 0,
}
lv.Init(getConsoleDevMode())
return lv.ParseLicense(license)
}
func fetchLicensePlan() {
client := GetConsoleHTTPClient("127.0.0.1")
licenseInfo, err := getLicenseInfo(*client, os.Getenv(EnvSubnetLicense))
if err != nil {
return
}
switch licenseInfo.Plan {
case "STANDARD":
InstanceLicensePlan = PlanStandard
case "ENTERPRISE":
InstanceLicensePlan = PlanEnterprise
case "ENTERPRISE-LITE":
InstanceLicensePlan = PlanEnterpriseLite
case "ENTERPRISE-PLUS":
InstanceLicensePlan = PlanEnterprisePlus
default:
InstanceLicensePlan = PlanAGPL
}
}

View File

@@ -24,7 +24,6 @@ package operations
import (
"fmt"
"io"
"net/http"
"strings"
@@ -48,14 +47,11 @@ import (
"github.com/minio/console/api/operations/logging"
"github.com/minio/console/api/operations/object"
"github.com/minio/console/api/operations/policy"
"github.com/minio/console/api/operations/profile"
"github.com/minio/console/api/operations/public"
"github.com/minio/console/api/operations/release"
"github.com/minio/console/api/operations/service"
"github.com/minio/console/api/operations/service_account"
"github.com/minio/console/api/operations/site_replication"
"github.com/minio/console/api/operations/subnet"
"github.com/minio/console/api/operations/support"
"github.com/minio/console/api/operations/system"
"github.com/minio/console/api/operations/tiering"
"github.com/minio/console/api/operations/user"
@@ -83,9 +79,6 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI {
JSONConsumer: runtime.JSONConsumer(),
MultipartformConsumer: runtime.DiscardConsumer,
ApplicationZipProducer: runtime.ProducerFunc(func(w io.Writer, data interface{}) error {
return errors.NotImplemented("applicationZip producer has not yet been implemented")
}),
BinProducer: runtime.ByteStreamProducer(),
JSONProducer: runtime.JSONProducer(),
@@ -251,9 +244,6 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI {
BucketGetBucketVersioningHandler: bucket.GetBucketVersioningHandlerFunc(func(params bucket.GetBucketVersioningParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation bucket.GetBucketVersioning has not yet been implemented")
}),
SupportGetCallHomeOptionValueHandler: support.GetCallHomeOptionValueHandlerFunc(func(params support.GetCallHomeOptionValueParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation support.GetCallHomeOptionValue has not yet been implemented")
}),
IdpGetConfigurationHandler: idp.GetConfigurationHandlerFunc(func(params idp.GetConfigurationParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation idp.GetConfiguration has not yet been implemented")
}),
@@ -401,12 +391,6 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI {
ConfigurationPostConfigsImportHandler: configuration.PostConfigsImportHandlerFunc(func(params configuration.PostConfigsImportParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation configuration.PostConfigsImport has not yet been implemented")
}),
ProfileProfilingStartHandler: profile.ProfilingStartHandlerFunc(func(params profile.ProfilingStartParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation profile.ProfilingStart has not yet been implemented")
}),
ProfileProfilingStopHandler: profile.ProfilingStopHandlerFunc(func(params profile.ProfilingStopParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation profile.ProfilingStop has not yet been implemented")
}),
BucketPutBucketTagsHandler: bucket.PutBucketTagsHandlerFunc(func(params bucket.PutBucketTagsParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation bucket.PutBucketTags has not yet been implemented")
}),
@@ -458,9 +442,6 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI {
BucketSetBucketVersioningHandler: bucket.SetBucketVersioningHandlerFunc(func(params bucket.SetBucketVersioningParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation bucket.SetBucketVersioning has not yet been implemented")
}),
SupportSetCallHomeStatusHandler: support.SetCallHomeStatusHandlerFunc(func(params support.SetCallHomeStatusParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation support.SetCallHomeStatus has not yet been implemented")
}),
ConfigurationSetConfigHandler: configuration.SetConfigHandlerFunc(func(params configuration.SetConfigParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation configuration.SetConfig has not yet been implemented")
}),
@@ -485,24 +466,6 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI {
SiteReplicationSiteReplicationRemoveHandler: site_replication.SiteReplicationRemoveHandlerFunc(func(params site_replication.SiteReplicationRemoveParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation site_replication.SiteReplicationRemove has not yet been implemented")
}),
SubnetSubnetAPIKeyHandler: subnet.SubnetAPIKeyHandlerFunc(func(params subnet.SubnetAPIKeyParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation subnet.SubnetAPIKey has not yet been implemented")
}),
SubnetSubnetInfoHandler: subnet.SubnetInfoHandlerFunc(func(params subnet.SubnetInfoParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation subnet.SubnetInfo has not yet been implemented")
}),
SubnetSubnetLoginHandler: subnet.SubnetLoginHandlerFunc(func(params subnet.SubnetLoginParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation subnet.SubnetLogin has not yet been implemented")
}),
SubnetSubnetLoginMFAHandler: subnet.SubnetLoginMFAHandlerFunc(func(params subnet.SubnetLoginMFAParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation subnet.SubnetLoginMFA has not yet been implemented")
}),
SubnetSubnetRegTokenHandler: subnet.SubnetRegTokenHandlerFunc(func(params subnet.SubnetRegTokenParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation subnet.SubnetRegToken has not yet been implemented")
}),
SubnetSubnetRegisterHandler: subnet.SubnetRegisterHandlerFunc(func(params subnet.SubnetRegisterParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation subnet.SubnetRegister has not yet been implemented")
}),
TieringTiersListHandler: tiering.TiersListHandlerFunc(func(params tiering.TiersListParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation tiering.TiersList has not yet been implemented")
}),
@@ -575,9 +538,6 @@ type ConsoleAPI struct {
// - multipart/form-data
MultipartformConsumer runtime.Consumer
// ApplicationZipProducer registers a producer for the following mime types:
// - application/zip
ApplicationZipProducer runtime.Producer
// BinProducer registers a producer for the following mime types:
// - application/octet-stream
BinProducer runtime.Producer
@@ -704,8 +664,6 @@ type ConsoleAPI struct {
BucketGetBucketRewindHandler bucket.GetBucketRewindHandler
// BucketGetBucketVersioningHandler sets the operation handler for the get bucket versioning operation
BucketGetBucketVersioningHandler bucket.GetBucketVersioningHandler
// SupportGetCallHomeOptionValueHandler sets the operation handler for the get call home option value operation
SupportGetCallHomeOptionValueHandler support.GetCallHomeOptionValueHandler
// IdpGetConfigurationHandler sets the operation handler for the get configuration operation
IdpGetConfigurationHandler idp.GetConfigurationHandler
// IdpGetLDAPEntitiesHandler sets the operation handler for the get l d a p entities operation
@@ -804,10 +762,6 @@ type ConsoleAPI struct {
ObjectPostBucketsBucketNameObjectsUploadHandler object.PostBucketsBucketNameObjectsUploadHandler
// ConfigurationPostConfigsImportHandler sets the operation handler for the post configs import operation
ConfigurationPostConfigsImportHandler configuration.PostConfigsImportHandler
// ProfileProfilingStartHandler sets the operation handler for the profiling start operation
ProfileProfilingStartHandler profile.ProfilingStartHandler
// ProfileProfilingStopHandler sets the operation handler for the profiling stop operation
ProfileProfilingStopHandler profile.ProfilingStopHandler
// BucketPutBucketTagsHandler sets the operation handler for the put bucket tags operation
BucketPutBucketTagsHandler bucket.PutBucketTagsHandler
// ObjectPutObjectLegalHoldHandler sets the operation handler for the put object legal hold operation
@@ -842,8 +796,6 @@ type ConsoleAPI struct {
BucketSetBucketRetentionConfigHandler bucket.SetBucketRetentionConfigHandler
// BucketSetBucketVersioningHandler sets the operation handler for the set bucket versioning operation
BucketSetBucketVersioningHandler bucket.SetBucketVersioningHandler
// SupportSetCallHomeStatusHandler sets the operation handler for the set call home status operation
SupportSetCallHomeStatusHandler support.SetCallHomeStatusHandler
// ConfigurationSetConfigHandler sets the operation handler for the set config operation
ConfigurationSetConfigHandler configuration.SetConfigHandler
// BucketSetMultiBucketReplicationHandler sets the operation handler for the set multi bucket replication operation
@@ -860,18 +812,6 @@ type ConsoleAPI struct {
SiteReplicationSiteReplicationInfoAddHandler site_replication.SiteReplicationInfoAddHandler
// SiteReplicationSiteReplicationRemoveHandler sets the operation handler for the site replication remove operation
SiteReplicationSiteReplicationRemoveHandler site_replication.SiteReplicationRemoveHandler
// SubnetSubnetAPIKeyHandler sets the operation handler for the subnet Api key operation
SubnetSubnetAPIKeyHandler subnet.SubnetAPIKeyHandler
// SubnetSubnetInfoHandler sets the operation handler for the subnet info operation
SubnetSubnetInfoHandler subnet.SubnetInfoHandler
// SubnetSubnetLoginHandler sets the operation handler for the subnet login operation
SubnetSubnetLoginHandler subnet.SubnetLoginHandler
// SubnetSubnetLoginMFAHandler sets the operation handler for the subnet login m f a operation
SubnetSubnetLoginMFAHandler subnet.SubnetLoginMFAHandler
// SubnetSubnetRegTokenHandler sets the operation handler for the subnet reg token operation
SubnetSubnetRegTokenHandler subnet.SubnetRegTokenHandler
// SubnetSubnetRegisterHandler sets the operation handler for the subnet register operation
SubnetSubnetRegisterHandler subnet.SubnetRegisterHandler
// TieringTiersListHandler sets the operation handler for the tiers list operation
TieringTiersListHandler tiering.TiersListHandler
// TieringTiersListNamesHandler sets the operation handler for the tiers list names operation
@@ -966,9 +906,6 @@ func (o *ConsoleAPI) Validate() error {
unregistered = append(unregistered, "MultipartformConsumer")
}
if o.ApplicationZipProducer == nil {
unregistered = append(unregistered, "ApplicationZipProducer")
}
if o.BinProducer == nil {
unregistered = append(unregistered, "BinProducer")
}
@@ -1145,9 +1082,6 @@ func (o *ConsoleAPI) Validate() error {
if o.BucketGetBucketVersioningHandler == nil {
unregistered = append(unregistered, "bucket.GetBucketVersioningHandler")
}
if o.SupportGetCallHomeOptionValueHandler == nil {
unregistered = append(unregistered, "support.GetCallHomeOptionValueHandler")
}
if o.IdpGetConfigurationHandler == nil {
unregistered = append(unregistered, "idp.GetConfigurationHandler")
}
@@ -1295,12 +1229,6 @@ func (o *ConsoleAPI) Validate() error {
if o.ConfigurationPostConfigsImportHandler == nil {
unregistered = append(unregistered, "configuration.PostConfigsImportHandler")
}
if o.ProfileProfilingStartHandler == nil {
unregistered = append(unregistered, "profile.ProfilingStartHandler")
}
if o.ProfileProfilingStopHandler == nil {
unregistered = append(unregistered, "profile.ProfilingStopHandler")
}
if o.BucketPutBucketTagsHandler == nil {
unregistered = append(unregistered, "bucket.PutBucketTagsHandler")
}
@@ -1352,9 +1280,6 @@ func (o *ConsoleAPI) Validate() error {
if o.BucketSetBucketVersioningHandler == nil {
unregistered = append(unregistered, "bucket.SetBucketVersioningHandler")
}
if o.SupportSetCallHomeStatusHandler == nil {
unregistered = append(unregistered, "support.SetCallHomeStatusHandler")
}
if o.ConfigurationSetConfigHandler == nil {
unregistered = append(unregistered, "configuration.SetConfigHandler")
}
@@ -1379,24 +1304,6 @@ func (o *ConsoleAPI) Validate() error {
if o.SiteReplicationSiteReplicationRemoveHandler == nil {
unregistered = append(unregistered, "site_replication.SiteReplicationRemoveHandler")
}
if o.SubnetSubnetAPIKeyHandler == nil {
unregistered = append(unregistered, "subnet.SubnetAPIKeyHandler")
}
if o.SubnetSubnetInfoHandler == nil {
unregistered = append(unregistered, "subnet.SubnetInfoHandler")
}
if o.SubnetSubnetLoginHandler == nil {
unregistered = append(unregistered, "subnet.SubnetLoginHandler")
}
if o.SubnetSubnetLoginMFAHandler == nil {
unregistered = append(unregistered, "subnet.SubnetLoginMFAHandler")
}
if o.SubnetSubnetRegTokenHandler == nil {
unregistered = append(unregistered, "subnet.SubnetRegTokenHandler")
}
if o.SubnetSubnetRegisterHandler == nil {
unregistered = append(unregistered, "subnet.SubnetRegisterHandler")
}
if o.TieringTiersListHandler == nil {
unregistered = append(unregistered, "tiering.TiersListHandler")
}
@@ -1488,8 +1395,6 @@ func (o *ConsoleAPI) ProducersFor(mediaTypes []string) map[string]runtime.Produc
result := make(map[string]runtime.Producer, len(mediaTypes))
for _, mt := range mediaTypes {
switch mt {
case "application/zip":
result["application/zip"] = o.ApplicationZipProducer
case "application/octet-stream":
result["application/octet-stream"] = o.BinProducer
case "application/json":
@@ -1753,10 +1658,6 @@ func (o *ConsoleAPI) initHandlerCache() {
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/support/callhome"] = support.NewGetCallHomeOptionValue(o.context, o.SupportGetCallHomeOptionValueHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/idp/{type}/{name}"] = idp.NewGetConfiguration(o.context, o.IdpGetConfigurationHandler)
if o.handlers["POST"] == nil {
o.handlers["POST"] = make(map[string]http.Handler)
@@ -1950,14 +1851,6 @@ func (o *ConsoleAPI) initHandlerCache() {
o.handlers["POST"] = make(map[string]http.Handler)
}
o.handlers["POST"]["/configs/import"] = configuration.NewPostConfigsImport(o.context, o.ConfigurationPostConfigsImportHandler)
if o.handlers["POST"] == nil {
o.handlers["POST"] = make(map[string]http.Handler)
}
o.handlers["POST"]["/profiling/start"] = profile.NewProfilingStart(o.context, o.ProfileProfilingStartHandler)
if o.handlers["POST"] == nil {
o.handlers["POST"] = make(map[string]http.Handler)
}
o.handlers["POST"]["/profiling/stop"] = profile.NewProfilingStop(o.context, o.ProfileProfilingStopHandler)
if o.handlers["PUT"] == nil {
o.handlers["PUT"] = make(map[string]http.Handler)
}
@@ -2029,10 +1922,6 @@ func (o *ConsoleAPI) initHandlerCache() {
if o.handlers["PUT"] == nil {
o.handlers["PUT"] = make(map[string]http.Handler)
}
o.handlers["PUT"]["/support/callhome"] = support.NewSetCallHomeStatus(o.context, o.SupportSetCallHomeStatusHandler)
if o.handlers["PUT"] == nil {
o.handlers["PUT"] = make(map[string]http.Handler)
}
o.handlers["PUT"]["/configs/{name}"] = configuration.NewSetConfig(o.context, o.ConfigurationSetConfigHandler)
if o.handlers["POST"] == nil {
o.handlers["POST"] = make(map[string]http.Handler)
@@ -2065,30 +1954,6 @@ func (o *ConsoleAPI) initHandlerCache() {
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/subnet/apikey"] = subnet.NewSubnetAPIKey(o.context, o.SubnetSubnetAPIKeyHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/subnet/info"] = subnet.NewSubnetInfo(o.context, o.SubnetSubnetInfoHandler)
if o.handlers["POST"] == nil {
o.handlers["POST"] = make(map[string]http.Handler)
}
o.handlers["POST"]["/subnet/login"] = subnet.NewSubnetLogin(o.context, o.SubnetSubnetLoginHandler)
if o.handlers["POST"] == nil {
o.handlers["POST"] = make(map[string]http.Handler)
}
o.handlers["POST"]["/subnet/login/mfa"] = subnet.NewSubnetLoginMFA(o.context, o.SubnetSubnetLoginMFAHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/subnet/registration-token"] = subnet.NewSubnetRegToken(o.context, o.SubnetSubnetRegTokenHandler)
if o.handlers["POST"] == nil {
o.handlers["POST"] = make(map[string]http.Handler)
}
o.handlers["POST"]["/subnet/register"] = subnet.NewSubnetRegister(o.context, o.SubnetSubnetRegisterHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/admin/tiers"] = tiering.NewTiersList(o.context, o.TieringTiersListHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)

View File

@@ -1,88 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 profile
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"net/http"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models"
)
// ProfilingStartHandlerFunc turns a function with the right signature into a profiling start handler
type ProfilingStartHandlerFunc func(ProfilingStartParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn ProfilingStartHandlerFunc) Handle(params ProfilingStartParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// ProfilingStartHandler interface for that can handle valid profiling start params
type ProfilingStartHandler interface {
Handle(ProfilingStartParams, *models.Principal) middleware.Responder
}
// NewProfilingStart creates a new http.Handler for the profiling start operation
func NewProfilingStart(ctx *middleware.Context, handler ProfilingStartHandler) *ProfilingStart {
return &ProfilingStart{Context: ctx, Handler: handler}
}
/*
ProfilingStart swagger:route POST /profiling/start Profile profilingStart
Start recording profile data
*/
type ProfilingStart struct {
Context *middleware.Context
Handler ProfilingStartHandler
}
func (o *ProfilingStart) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewProfilingStartParams()
uprinc, aCtx, err := o.Context.Authorize(r, route)
if err != nil {
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
if aCtx != nil {
*r = *aCtx
}
var principal *models.Principal
if uprinc != nil {
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
}
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params, principal) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -1,101 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 profile
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"io"
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/validate"
"github.com/minio/console/models"
)
// NewProfilingStartParams creates a new ProfilingStartParams object
//
// There are no default values defined in the spec.
func NewProfilingStartParams() ProfilingStartParams {
return ProfilingStartParams{}
}
// ProfilingStartParams contains all the bound params for the profiling start operation
// typically these are obtained from a http.Request
//
// swagger:parameters ProfilingStart
type ProfilingStartParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
/*
Required: true
In: body
*/
Body *models.ProfilingStartRequest
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
// for simple values it will use straight method calls.
//
// To ensure default values, the struct must have been initialized with NewProfilingStartParams() beforehand.
func (o *ProfilingStartParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
if runtime.HasBody(r) {
defer r.Body.Close()
var body models.ProfilingStartRequest
if err := route.Consumer.Consume(r.Body, &body); err != nil {
if err == io.EOF {
res = append(res, errors.Required("body", "body", ""))
} else {
res = append(res, errors.NewParseError("body", "body", "", err))
}
} else {
// validate body object
if err := body.Validate(route.Formats); err != nil {
res = append(res, err)
}
ctx := validate.WithOperationRequest(r.Context())
if err := body.ContextValidate(ctx, route.Formats); err != nil {
res = append(res, err)
}
if len(res) == 0 {
o.Body = &body
}
}
} else {
res = append(res, errors.Required("body", "body", ""))
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,135 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 profile
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/runtime"
"github.com/minio/console/models"
)
// ProfilingStartCreatedCode is the HTTP code returned for type ProfilingStartCreated
const ProfilingStartCreatedCode int = 201
/*
ProfilingStartCreated A successful response.
swagger:response profilingStartCreated
*/
type ProfilingStartCreated struct {
/*
In: Body
*/
Payload *models.StartProfilingList `json:"body,omitempty"`
}
// NewProfilingStartCreated creates ProfilingStartCreated with default headers values
func NewProfilingStartCreated() *ProfilingStartCreated {
return &ProfilingStartCreated{}
}
// WithPayload adds the payload to the profiling start created response
func (o *ProfilingStartCreated) WithPayload(payload *models.StartProfilingList) *ProfilingStartCreated {
o.Payload = payload
return o
}
// SetPayload sets the payload to the profiling start created response
func (o *ProfilingStartCreated) SetPayload(payload *models.StartProfilingList) {
o.Payload = payload
}
// WriteResponse to the client
func (o *ProfilingStartCreated) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(201)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}
/*
ProfilingStartDefault Generic error response.
swagger:response profilingStartDefault
*/
type ProfilingStartDefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.APIError `json:"body,omitempty"`
}
// NewProfilingStartDefault creates ProfilingStartDefault with default headers values
func NewProfilingStartDefault(code int) *ProfilingStartDefault {
if code <= 0 {
code = 500
}
return &ProfilingStartDefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the profiling start default response
func (o *ProfilingStartDefault) WithStatusCode(code int) *ProfilingStartDefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the profiling start default response
func (o *ProfilingStartDefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the profiling start default response
func (o *ProfilingStartDefault) WithPayload(payload *models.APIError) *ProfilingStartDefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the profiling start default response
func (o *ProfilingStartDefault) SetPayload(payload *models.APIError) {
o.Payload = payload
}
// WriteResponse to the client
func (o *ProfilingStartDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(o._statusCode)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}

View File

@@ -1,104 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 profile
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"errors"
"net/url"
golangswaggerpaths "path"
)
// ProfilingStartURL generates an URL for the profiling start operation
type ProfilingStartURL struct {
_basePath string
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *ProfilingStartURL) WithBasePath(bp string) *ProfilingStartURL {
o.SetBasePath(bp)
return o
}
// SetBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *ProfilingStartURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *ProfilingStartURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/profiling/start"
_basePath := o._basePath
if _basePath == "" {
_basePath = "/api/v1"
}
_result.Path = golangswaggerpaths.Join(_basePath, _path)
return &_result, nil
}
// Must is a helper function to panic when the url builder returns an error
func (o *ProfilingStartURL) Must(u *url.URL, err error) *url.URL {
if err != nil {
panic(err)
}
if u == nil {
panic("url can't be nil")
}
return u
}
// String returns the string representation of the path with query string
func (o *ProfilingStartURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *ProfilingStartURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on ProfilingStartURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on ProfilingStartURL")
}
base, err := o.Build()
if err != nil {
return nil, err
}
base.Scheme = scheme
base.Host = host
return base, nil
}
// StringFull returns the string representation of a complete url
func (o *ProfilingStartURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -1,88 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 profile
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"net/http"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models"
)
// ProfilingStopHandlerFunc turns a function with the right signature into a profiling stop handler
type ProfilingStopHandlerFunc func(ProfilingStopParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn ProfilingStopHandlerFunc) Handle(params ProfilingStopParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// ProfilingStopHandler interface for that can handle valid profiling stop params
type ProfilingStopHandler interface {
Handle(ProfilingStopParams, *models.Principal) middleware.Responder
}
// NewProfilingStop creates a new http.Handler for the profiling stop operation
func NewProfilingStop(ctx *middleware.Context, handler ProfilingStopHandler) *ProfilingStop {
return &ProfilingStop{Context: ctx, Handler: handler}
}
/*
ProfilingStop swagger:route POST /profiling/stop Profile profilingStop
Stop and download profile data
*/
type ProfilingStop struct {
Context *middleware.Context
Handler ProfilingStopHandler
}
func (o *ProfilingStop) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewProfilingStopParams()
uprinc, aCtx, err := o.Context.Authorize(r, route)
if err != nil {
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
if aCtx != nil {
*r = *aCtx
}
var principal *models.Principal
if uprinc != nil {
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
}
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params, principal) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -1,63 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 profile
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime/middleware"
)
// NewProfilingStopParams creates a new ProfilingStopParams object
//
// There are no default values defined in the spec.
func NewProfilingStopParams() ProfilingStopParams {
return ProfilingStopParams{}
}
// ProfilingStopParams contains all the bound params for the profiling stop operation
// typically these are obtained from a http.Request
//
// swagger:parameters ProfilingStop
type ProfilingStopParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
// for simple values it will use straight method calls.
//
// To ensure default values, the struct must have been initialized with NewProfilingStopParams() beforehand.
func (o *ProfilingStopParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,134 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 profile
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"io"
"net/http"
"github.com/go-openapi/runtime"
"github.com/minio/console/models"
)
// ProfilingStopCreatedCode is the HTTP code returned for type ProfilingStopCreated
const ProfilingStopCreatedCode int = 201
/*
ProfilingStopCreated A successful response.
swagger:response profilingStopCreated
*/
type ProfilingStopCreated struct {
/*
In: Body
*/
Payload io.ReadCloser `json:"body,omitempty"`
}
// NewProfilingStopCreated creates ProfilingStopCreated with default headers values
func NewProfilingStopCreated() *ProfilingStopCreated {
return &ProfilingStopCreated{}
}
// WithPayload adds the payload to the profiling stop created response
func (o *ProfilingStopCreated) WithPayload(payload io.ReadCloser) *ProfilingStopCreated {
o.Payload = payload
return o
}
// SetPayload sets the payload to the profiling stop created response
func (o *ProfilingStopCreated) SetPayload(payload io.ReadCloser) {
o.Payload = payload
}
// WriteResponse to the client
func (o *ProfilingStopCreated) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(201)
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
/*
ProfilingStopDefault Generic error response.
swagger:response profilingStopDefault
*/
type ProfilingStopDefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.APIError `json:"body,omitempty"`
}
// NewProfilingStopDefault creates ProfilingStopDefault with default headers values
func NewProfilingStopDefault(code int) *ProfilingStopDefault {
if code <= 0 {
code = 500
}
return &ProfilingStopDefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the profiling stop default response
func (o *ProfilingStopDefault) WithStatusCode(code int) *ProfilingStopDefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the profiling stop default response
func (o *ProfilingStopDefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the profiling stop default response
func (o *ProfilingStopDefault) WithPayload(payload *models.APIError) *ProfilingStopDefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the profiling stop default response
func (o *ProfilingStopDefault) SetPayload(payload *models.APIError) {
o.Payload = payload
}
// WriteResponse to the client
func (o *ProfilingStopDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(o._statusCode)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}

View File

@@ -1,104 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 profile
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"errors"
"net/url"
golangswaggerpaths "path"
)
// ProfilingStopURL generates an URL for the profiling stop operation
type ProfilingStopURL struct {
_basePath string
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *ProfilingStopURL) WithBasePath(bp string) *ProfilingStopURL {
o.SetBasePath(bp)
return o
}
// SetBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *ProfilingStopURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *ProfilingStopURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/profiling/stop"
_basePath := o._basePath
if _basePath == "" {
_basePath = "/api/v1"
}
_result.Path = golangswaggerpaths.Join(_basePath, _path)
return &_result, nil
}
// Must is a helper function to panic when the url builder returns an error
func (o *ProfilingStopURL) Must(u *url.URL, err error) *url.URL {
if err != nil {
panic(err)
}
if u == nil {
panic("url can't be nil")
}
return u
}
// String returns the string representation of the path with query string
func (o *ProfilingStopURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *ProfilingStopURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on ProfilingStopURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on ProfilingStopURL")
}
base, err := o.Build()
if err != nil {
return nil, err
}
base.Scheme = scheme
base.Host = host
return base, nil
}
// StringFull returns the string representation of a complete url
func (o *ProfilingStopURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -1,88 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"net/http"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models"
)
// SubnetAPIKeyHandlerFunc turns a function with the right signature into a subnet Api key handler
type SubnetAPIKeyHandlerFunc func(SubnetAPIKeyParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn SubnetAPIKeyHandlerFunc) Handle(params SubnetAPIKeyParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// SubnetAPIKeyHandler interface for that can handle valid subnet Api key params
type SubnetAPIKeyHandler interface {
Handle(SubnetAPIKeyParams, *models.Principal) middleware.Responder
}
// NewSubnetAPIKey creates a new http.Handler for the subnet Api key operation
func NewSubnetAPIKey(ctx *middleware.Context, handler SubnetAPIKeyHandler) *SubnetAPIKey {
return &SubnetAPIKey{Context: ctx, Handler: handler}
}
/*
SubnetAPIKey swagger:route GET /subnet/apikey Subnet subnetApiKey
Subnet api key
*/
type SubnetAPIKey struct {
Context *middleware.Context
Handler SubnetAPIKeyHandler
}
func (o *SubnetAPIKey) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewSubnetAPIKeyParams()
uprinc, aCtx, err := o.Context.Authorize(r, route)
if err != nil {
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
if aCtx != nil {
*r = *aCtx
}
var principal *models.Principal
if uprinc != nil {
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
}
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params, principal) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -1,99 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/validate"
)
// NewSubnetAPIKeyParams creates a new SubnetAPIKeyParams object
//
// There are no default values defined in the spec.
func NewSubnetAPIKeyParams() SubnetAPIKeyParams {
return SubnetAPIKeyParams{}
}
// SubnetAPIKeyParams contains all the bound params for the subnet Api key operation
// typically these are obtained from a http.Request
//
// swagger:parameters SubnetApiKey
type SubnetAPIKeyParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
/*
Required: true
In: query
*/
Token string
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
// for simple values it will use straight method calls.
//
// To ensure default values, the struct must have been initialized with NewSubnetAPIKeyParams() beforehand.
func (o *SubnetAPIKeyParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
qs := runtime.Values(r.URL.Query())
qToken, qhkToken, _ := qs.GetOK("token")
if err := o.bindToken(qToken, qhkToken, route.Formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// bindToken binds and validates parameter Token from query.
func (o *SubnetAPIKeyParams) bindToken(rawData []string, hasKey bool, formats strfmt.Registry) error {
if !hasKey {
return errors.Required("token", "query", rawData)
}
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: true
// AllowEmptyValue: false
if err := validate.RequiredString("token", "query", raw); err != nil {
return err
}
o.Token = raw
return nil
}

View File

@@ -1,135 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/runtime"
"github.com/minio/console/models"
)
// SubnetAPIKeyOKCode is the HTTP code returned for type SubnetAPIKeyOK
const SubnetAPIKeyOKCode int = 200
/*
SubnetAPIKeyOK A successful response.
swagger:response subnetApiKeyOK
*/
type SubnetAPIKeyOK struct {
/*
In: Body
*/
Payload *models.APIKey `json:"body,omitempty"`
}
// NewSubnetAPIKeyOK creates SubnetAPIKeyOK with default headers values
func NewSubnetAPIKeyOK() *SubnetAPIKeyOK {
return &SubnetAPIKeyOK{}
}
// WithPayload adds the payload to the subnet Api key o k response
func (o *SubnetAPIKeyOK) WithPayload(payload *models.APIKey) *SubnetAPIKeyOK {
o.Payload = payload
return o
}
// SetPayload sets the payload to the subnet Api key o k response
func (o *SubnetAPIKeyOK) SetPayload(payload *models.APIKey) {
o.Payload = payload
}
// WriteResponse to the client
func (o *SubnetAPIKeyOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(200)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}
/*
SubnetAPIKeyDefault Generic error response.
swagger:response subnetApiKeyDefault
*/
type SubnetAPIKeyDefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.APIError `json:"body,omitempty"`
}
// NewSubnetAPIKeyDefault creates SubnetAPIKeyDefault with default headers values
func NewSubnetAPIKeyDefault(code int) *SubnetAPIKeyDefault {
if code <= 0 {
code = 500
}
return &SubnetAPIKeyDefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the subnet Api key default response
func (o *SubnetAPIKeyDefault) WithStatusCode(code int) *SubnetAPIKeyDefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the subnet Api key default response
func (o *SubnetAPIKeyDefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the subnet Api key default response
func (o *SubnetAPIKeyDefault) WithPayload(payload *models.APIError) *SubnetAPIKeyDefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the subnet Api key default response
func (o *SubnetAPIKeyDefault) SetPayload(payload *models.APIError) {
o.Payload = payload
}
// WriteResponse to the client
func (o *SubnetAPIKeyDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(o._statusCode)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}

View File

@@ -1,117 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"errors"
"net/url"
golangswaggerpaths "path"
)
// SubnetAPIKeyURL generates an URL for the subnet Api key operation
type SubnetAPIKeyURL struct {
Token string
_basePath string
// avoid unkeyed usage
_ struct{}
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *SubnetAPIKeyURL) WithBasePath(bp string) *SubnetAPIKeyURL {
o.SetBasePath(bp)
return o
}
// SetBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *SubnetAPIKeyURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *SubnetAPIKeyURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/subnet/apikey"
_basePath := o._basePath
if _basePath == "" {
_basePath = "/api/v1"
}
_result.Path = golangswaggerpaths.Join(_basePath, _path)
qs := make(url.Values)
tokenQ := o.Token
if tokenQ != "" {
qs.Set("token", tokenQ)
}
_result.RawQuery = qs.Encode()
return &_result, nil
}
// Must is a helper function to panic when the url builder returns an error
func (o *SubnetAPIKeyURL) Must(u *url.URL, err error) *url.URL {
if err != nil {
panic(err)
}
if u == nil {
panic("url can't be nil")
}
return u
}
// String returns the string representation of the path with query string
func (o *SubnetAPIKeyURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *SubnetAPIKeyURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on SubnetAPIKeyURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on SubnetAPIKeyURL")
}
base, err := o.Build()
if err != nil {
return nil, err
}
base.Scheme = scheme
base.Host = host
return base, nil
}
// StringFull returns the string representation of a complete url
func (o *SubnetAPIKeyURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -1,88 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"net/http"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models"
)
// SubnetInfoHandlerFunc turns a function with the right signature into a subnet info handler
type SubnetInfoHandlerFunc func(SubnetInfoParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn SubnetInfoHandlerFunc) Handle(params SubnetInfoParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// SubnetInfoHandler interface for that can handle valid subnet info params
type SubnetInfoHandler interface {
Handle(SubnetInfoParams, *models.Principal) middleware.Responder
}
// NewSubnetInfo creates a new http.Handler for the subnet info operation
func NewSubnetInfo(ctx *middleware.Context, handler SubnetInfoHandler) *SubnetInfo {
return &SubnetInfo{Context: ctx, Handler: handler}
}
/*
SubnetInfo swagger:route GET /subnet/info Subnet subnetInfo
Subnet info
*/
type SubnetInfo struct {
Context *middleware.Context
Handler SubnetInfoHandler
}
func (o *SubnetInfo) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewSubnetInfoParams()
uprinc, aCtx, err := o.Context.Authorize(r, route)
if err != nil {
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
if aCtx != nil {
*r = *aCtx
}
var principal *models.Principal
if uprinc != nil {
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
}
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params, principal) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -1,63 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime/middleware"
)
// NewSubnetInfoParams creates a new SubnetInfoParams object
//
// There are no default values defined in the spec.
func NewSubnetInfoParams() SubnetInfoParams {
return SubnetInfoParams{}
}
// SubnetInfoParams contains all the bound params for the subnet info operation
// typically these are obtained from a http.Request
//
// swagger:parameters SubnetInfo
type SubnetInfoParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
// for simple values it will use straight method calls.
//
// To ensure default values, the struct must have been initialized with NewSubnetInfoParams() beforehand.
func (o *SubnetInfoParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,135 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/runtime"
"github.com/minio/console/models"
)
// SubnetInfoOKCode is the HTTP code returned for type SubnetInfoOK
const SubnetInfoOKCode int = 200
/*
SubnetInfoOK A successful response.
swagger:response subnetInfoOK
*/
type SubnetInfoOK struct {
/*
In: Body
*/
Payload *models.License `json:"body,omitempty"`
}
// NewSubnetInfoOK creates SubnetInfoOK with default headers values
func NewSubnetInfoOK() *SubnetInfoOK {
return &SubnetInfoOK{}
}
// WithPayload adds the payload to the subnet info o k response
func (o *SubnetInfoOK) WithPayload(payload *models.License) *SubnetInfoOK {
o.Payload = payload
return o
}
// SetPayload sets the payload to the subnet info o k response
func (o *SubnetInfoOK) SetPayload(payload *models.License) {
o.Payload = payload
}
// WriteResponse to the client
func (o *SubnetInfoOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(200)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}
/*
SubnetInfoDefault Generic error response.
swagger:response subnetInfoDefault
*/
type SubnetInfoDefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.APIError `json:"body,omitempty"`
}
// NewSubnetInfoDefault creates SubnetInfoDefault with default headers values
func NewSubnetInfoDefault(code int) *SubnetInfoDefault {
if code <= 0 {
code = 500
}
return &SubnetInfoDefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the subnet info default response
func (o *SubnetInfoDefault) WithStatusCode(code int) *SubnetInfoDefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the subnet info default response
func (o *SubnetInfoDefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the subnet info default response
func (o *SubnetInfoDefault) WithPayload(payload *models.APIError) *SubnetInfoDefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the subnet info default response
func (o *SubnetInfoDefault) SetPayload(payload *models.APIError) {
o.Payload = payload
}
// WriteResponse to the client
func (o *SubnetInfoDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(o._statusCode)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}

View File

@@ -1,104 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"errors"
"net/url"
golangswaggerpaths "path"
)
// SubnetInfoURL generates an URL for the subnet info operation
type SubnetInfoURL struct {
_basePath string
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *SubnetInfoURL) WithBasePath(bp string) *SubnetInfoURL {
o.SetBasePath(bp)
return o
}
// SetBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *SubnetInfoURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *SubnetInfoURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/subnet/info"
_basePath := o._basePath
if _basePath == "" {
_basePath = "/api/v1"
}
_result.Path = golangswaggerpaths.Join(_basePath, _path)
return &_result, nil
}
// Must is a helper function to panic when the url builder returns an error
func (o *SubnetInfoURL) Must(u *url.URL, err error) *url.URL {
if err != nil {
panic(err)
}
if u == nil {
panic("url can't be nil")
}
return u
}
// String returns the string representation of the path with query string
func (o *SubnetInfoURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *SubnetInfoURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on SubnetInfoURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on SubnetInfoURL")
}
base, err := o.Build()
if err != nil {
return nil, err
}
base.Scheme = scheme
base.Host = host
return base, nil
}
// StringFull returns the string representation of a complete url
func (o *SubnetInfoURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -1,88 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"net/http"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models"
)
// SubnetLoginHandlerFunc turns a function with the right signature into a subnet login handler
type SubnetLoginHandlerFunc func(SubnetLoginParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn SubnetLoginHandlerFunc) Handle(params SubnetLoginParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// SubnetLoginHandler interface for that can handle valid subnet login params
type SubnetLoginHandler interface {
Handle(SubnetLoginParams, *models.Principal) middleware.Responder
}
// NewSubnetLogin creates a new http.Handler for the subnet login operation
func NewSubnetLogin(ctx *middleware.Context, handler SubnetLoginHandler) *SubnetLogin {
return &SubnetLogin{Context: ctx, Handler: handler}
}
/*
SubnetLogin swagger:route POST /subnet/login Subnet subnetLogin
Login to SUBNET
*/
type SubnetLogin struct {
Context *middleware.Context
Handler SubnetLoginHandler
}
func (o *SubnetLogin) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewSubnetLoginParams()
uprinc, aCtx, err := o.Context.Authorize(r, route)
if err != nil {
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
if aCtx != nil {
*r = *aCtx
}
var principal *models.Principal
if uprinc != nil {
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
}
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params, principal) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -1,88 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"net/http"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models"
)
// SubnetLoginMFAHandlerFunc turns a function with the right signature into a subnet login m f a handler
type SubnetLoginMFAHandlerFunc func(SubnetLoginMFAParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn SubnetLoginMFAHandlerFunc) Handle(params SubnetLoginMFAParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// SubnetLoginMFAHandler interface for that can handle valid subnet login m f a params
type SubnetLoginMFAHandler interface {
Handle(SubnetLoginMFAParams, *models.Principal) middleware.Responder
}
// NewSubnetLoginMFA creates a new http.Handler for the subnet login m f a operation
func NewSubnetLoginMFA(ctx *middleware.Context, handler SubnetLoginMFAHandler) *SubnetLoginMFA {
return &SubnetLoginMFA{Context: ctx, Handler: handler}
}
/*
SubnetLoginMFA swagger:route POST /subnet/login/mfa Subnet subnetLoginMFA
Login to SUBNET using mfa
*/
type SubnetLoginMFA struct {
Context *middleware.Context
Handler SubnetLoginMFAHandler
}
func (o *SubnetLoginMFA) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewSubnetLoginMFAParams()
uprinc, aCtx, err := o.Context.Authorize(r, route)
if err != nil {
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
if aCtx != nil {
*r = *aCtx
}
var principal *models.Principal
if uprinc != nil {
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
}
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params, principal) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -1,101 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"io"
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/validate"
"github.com/minio/console/models"
)
// NewSubnetLoginMFAParams creates a new SubnetLoginMFAParams object
//
// There are no default values defined in the spec.
func NewSubnetLoginMFAParams() SubnetLoginMFAParams {
return SubnetLoginMFAParams{}
}
// SubnetLoginMFAParams contains all the bound params for the subnet login m f a operation
// typically these are obtained from a http.Request
//
// swagger:parameters SubnetLoginMFA
type SubnetLoginMFAParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
/*
Required: true
In: body
*/
Body *models.SubnetLoginMFARequest
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
// for simple values it will use straight method calls.
//
// To ensure default values, the struct must have been initialized with NewSubnetLoginMFAParams() beforehand.
func (o *SubnetLoginMFAParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
if runtime.HasBody(r) {
defer r.Body.Close()
var body models.SubnetLoginMFARequest
if err := route.Consumer.Consume(r.Body, &body); err != nil {
if err == io.EOF {
res = append(res, errors.Required("body", "body", ""))
} else {
res = append(res, errors.NewParseError("body", "body", "", err))
}
} else {
// validate body object
if err := body.Validate(route.Formats); err != nil {
res = append(res, err)
}
ctx := validate.WithOperationRequest(r.Context())
if err := body.ContextValidate(ctx, route.Formats); err != nil {
res = append(res, err)
}
if len(res) == 0 {
o.Body = &body
}
}
} else {
res = append(res, errors.Required("body", "body", ""))
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,135 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/runtime"
"github.com/minio/console/models"
)
// SubnetLoginMFAOKCode is the HTTP code returned for type SubnetLoginMFAOK
const SubnetLoginMFAOKCode int = 200
/*
SubnetLoginMFAOK A successful response.
swagger:response subnetLoginMFAOK
*/
type SubnetLoginMFAOK struct {
/*
In: Body
*/
Payload *models.SubnetLoginResponse `json:"body,omitempty"`
}
// NewSubnetLoginMFAOK creates SubnetLoginMFAOK with default headers values
func NewSubnetLoginMFAOK() *SubnetLoginMFAOK {
return &SubnetLoginMFAOK{}
}
// WithPayload adds the payload to the subnet login m f a o k response
func (o *SubnetLoginMFAOK) WithPayload(payload *models.SubnetLoginResponse) *SubnetLoginMFAOK {
o.Payload = payload
return o
}
// SetPayload sets the payload to the subnet login m f a o k response
func (o *SubnetLoginMFAOK) SetPayload(payload *models.SubnetLoginResponse) {
o.Payload = payload
}
// WriteResponse to the client
func (o *SubnetLoginMFAOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(200)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}
/*
SubnetLoginMFADefault Generic error response.
swagger:response subnetLoginMFADefault
*/
type SubnetLoginMFADefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.APIError `json:"body,omitempty"`
}
// NewSubnetLoginMFADefault creates SubnetLoginMFADefault with default headers values
func NewSubnetLoginMFADefault(code int) *SubnetLoginMFADefault {
if code <= 0 {
code = 500
}
return &SubnetLoginMFADefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the subnet login m f a default response
func (o *SubnetLoginMFADefault) WithStatusCode(code int) *SubnetLoginMFADefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the subnet login m f a default response
func (o *SubnetLoginMFADefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the subnet login m f a default response
func (o *SubnetLoginMFADefault) WithPayload(payload *models.APIError) *SubnetLoginMFADefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the subnet login m f a default response
func (o *SubnetLoginMFADefault) SetPayload(payload *models.APIError) {
o.Payload = payload
}
// WriteResponse to the client
func (o *SubnetLoginMFADefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(o._statusCode)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}

View File

@@ -1,104 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"errors"
"net/url"
golangswaggerpaths "path"
)
// SubnetLoginMFAURL generates an URL for the subnet login m f a operation
type SubnetLoginMFAURL struct {
_basePath string
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *SubnetLoginMFAURL) WithBasePath(bp string) *SubnetLoginMFAURL {
o.SetBasePath(bp)
return o
}
// SetBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *SubnetLoginMFAURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *SubnetLoginMFAURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/subnet/login/mfa"
_basePath := o._basePath
if _basePath == "" {
_basePath = "/api/v1"
}
_result.Path = golangswaggerpaths.Join(_basePath, _path)
return &_result, nil
}
// Must is a helper function to panic when the url builder returns an error
func (o *SubnetLoginMFAURL) Must(u *url.URL, err error) *url.URL {
if err != nil {
panic(err)
}
if u == nil {
panic("url can't be nil")
}
return u
}
// String returns the string representation of the path with query string
func (o *SubnetLoginMFAURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *SubnetLoginMFAURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on SubnetLoginMFAURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on SubnetLoginMFAURL")
}
base, err := o.Build()
if err != nil {
return nil, err
}
base.Scheme = scheme
base.Host = host
return base, nil
}
// StringFull returns the string representation of a complete url
func (o *SubnetLoginMFAURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -1,101 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"io"
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/validate"
"github.com/minio/console/models"
)
// NewSubnetLoginParams creates a new SubnetLoginParams object
//
// There are no default values defined in the spec.
func NewSubnetLoginParams() SubnetLoginParams {
return SubnetLoginParams{}
}
// SubnetLoginParams contains all the bound params for the subnet login operation
// typically these are obtained from a http.Request
//
// swagger:parameters SubnetLogin
type SubnetLoginParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
/*
Required: true
In: body
*/
Body *models.SubnetLoginRequest
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
// for simple values it will use straight method calls.
//
// To ensure default values, the struct must have been initialized with NewSubnetLoginParams() beforehand.
func (o *SubnetLoginParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
if runtime.HasBody(r) {
defer r.Body.Close()
var body models.SubnetLoginRequest
if err := route.Consumer.Consume(r.Body, &body); err != nil {
if err == io.EOF {
res = append(res, errors.Required("body", "body", ""))
} else {
res = append(res, errors.NewParseError("body", "body", "", err))
}
} else {
// validate body object
if err := body.Validate(route.Formats); err != nil {
res = append(res, err)
}
ctx := validate.WithOperationRequest(r.Context())
if err := body.ContextValidate(ctx, route.Formats); err != nil {
res = append(res, err)
}
if len(res) == 0 {
o.Body = &body
}
}
} else {
res = append(res, errors.Required("body", "body", ""))
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,135 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/runtime"
"github.com/minio/console/models"
)
// SubnetLoginOKCode is the HTTP code returned for type SubnetLoginOK
const SubnetLoginOKCode int = 200
/*
SubnetLoginOK A successful response.
swagger:response subnetLoginOK
*/
type SubnetLoginOK struct {
/*
In: Body
*/
Payload *models.SubnetLoginResponse `json:"body,omitempty"`
}
// NewSubnetLoginOK creates SubnetLoginOK with default headers values
func NewSubnetLoginOK() *SubnetLoginOK {
return &SubnetLoginOK{}
}
// WithPayload adds the payload to the subnet login o k response
func (o *SubnetLoginOK) WithPayload(payload *models.SubnetLoginResponse) *SubnetLoginOK {
o.Payload = payload
return o
}
// SetPayload sets the payload to the subnet login o k response
func (o *SubnetLoginOK) SetPayload(payload *models.SubnetLoginResponse) {
o.Payload = payload
}
// WriteResponse to the client
func (o *SubnetLoginOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(200)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}
/*
SubnetLoginDefault Generic error response.
swagger:response subnetLoginDefault
*/
type SubnetLoginDefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.APIError `json:"body,omitempty"`
}
// NewSubnetLoginDefault creates SubnetLoginDefault with default headers values
func NewSubnetLoginDefault(code int) *SubnetLoginDefault {
if code <= 0 {
code = 500
}
return &SubnetLoginDefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the subnet login default response
func (o *SubnetLoginDefault) WithStatusCode(code int) *SubnetLoginDefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the subnet login default response
func (o *SubnetLoginDefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the subnet login default response
func (o *SubnetLoginDefault) WithPayload(payload *models.APIError) *SubnetLoginDefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the subnet login default response
func (o *SubnetLoginDefault) SetPayload(payload *models.APIError) {
o.Payload = payload
}
// WriteResponse to the client
func (o *SubnetLoginDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(o._statusCode)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}

View File

@@ -1,104 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"errors"
"net/url"
golangswaggerpaths "path"
)
// SubnetLoginURL generates an URL for the subnet login operation
type SubnetLoginURL struct {
_basePath string
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *SubnetLoginURL) WithBasePath(bp string) *SubnetLoginURL {
o.SetBasePath(bp)
return o
}
// SetBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *SubnetLoginURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *SubnetLoginURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/subnet/login"
_basePath := o._basePath
if _basePath == "" {
_basePath = "/api/v1"
}
_result.Path = golangswaggerpaths.Join(_basePath, _path)
return &_result, nil
}
// Must is a helper function to panic when the url builder returns an error
func (o *SubnetLoginURL) Must(u *url.URL, err error) *url.URL {
if err != nil {
panic(err)
}
if u == nil {
panic("url can't be nil")
}
return u
}
// String returns the string representation of the path with query string
func (o *SubnetLoginURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *SubnetLoginURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on SubnetLoginURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on SubnetLoginURL")
}
base, err := o.Build()
if err != nil {
return nil, err
}
base.Scheme = scheme
base.Host = host
return base, nil
}
// StringFull returns the string representation of a complete url
func (o *SubnetLoginURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -1,88 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"net/http"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models"
)
// SubnetRegTokenHandlerFunc turns a function with the right signature into a subnet reg token handler
type SubnetRegTokenHandlerFunc func(SubnetRegTokenParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn SubnetRegTokenHandlerFunc) Handle(params SubnetRegTokenParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// SubnetRegTokenHandler interface for that can handle valid subnet reg token params
type SubnetRegTokenHandler interface {
Handle(SubnetRegTokenParams, *models.Principal) middleware.Responder
}
// NewSubnetRegToken creates a new http.Handler for the subnet reg token operation
func NewSubnetRegToken(ctx *middleware.Context, handler SubnetRegTokenHandler) *SubnetRegToken {
return &SubnetRegToken{Context: ctx, Handler: handler}
}
/*
SubnetRegToken swagger:route GET /subnet/registration-token Subnet subnetRegToken
SUBNET registraton token
*/
type SubnetRegToken struct {
Context *middleware.Context
Handler SubnetRegTokenHandler
}
func (o *SubnetRegToken) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewSubnetRegTokenParams()
uprinc, aCtx, err := o.Context.Authorize(r, route)
if err != nil {
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
if aCtx != nil {
*r = *aCtx
}
var principal *models.Principal
if uprinc != nil {
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
}
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params, principal) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -1,63 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime/middleware"
)
// NewSubnetRegTokenParams creates a new SubnetRegTokenParams object
//
// There are no default values defined in the spec.
func NewSubnetRegTokenParams() SubnetRegTokenParams {
return SubnetRegTokenParams{}
}
// SubnetRegTokenParams contains all the bound params for the subnet reg token operation
// typically these are obtained from a http.Request
//
// swagger:parameters SubnetRegToken
type SubnetRegTokenParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
// for simple values it will use straight method calls.
//
// To ensure default values, the struct must have been initialized with NewSubnetRegTokenParams() beforehand.
func (o *SubnetRegTokenParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,135 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/runtime"
"github.com/minio/console/models"
)
// SubnetRegTokenOKCode is the HTTP code returned for type SubnetRegTokenOK
const SubnetRegTokenOKCode int = 200
/*
SubnetRegTokenOK A successful response.
swagger:response subnetRegTokenOK
*/
type SubnetRegTokenOK struct {
/*
In: Body
*/
Payload *models.SubnetRegTokenResponse `json:"body,omitempty"`
}
// NewSubnetRegTokenOK creates SubnetRegTokenOK with default headers values
func NewSubnetRegTokenOK() *SubnetRegTokenOK {
return &SubnetRegTokenOK{}
}
// WithPayload adds the payload to the subnet reg token o k response
func (o *SubnetRegTokenOK) WithPayload(payload *models.SubnetRegTokenResponse) *SubnetRegTokenOK {
o.Payload = payload
return o
}
// SetPayload sets the payload to the subnet reg token o k response
func (o *SubnetRegTokenOK) SetPayload(payload *models.SubnetRegTokenResponse) {
o.Payload = payload
}
// WriteResponse to the client
func (o *SubnetRegTokenOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(200)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}
/*
SubnetRegTokenDefault Generic error response.
swagger:response subnetRegTokenDefault
*/
type SubnetRegTokenDefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.APIError `json:"body,omitempty"`
}
// NewSubnetRegTokenDefault creates SubnetRegTokenDefault with default headers values
func NewSubnetRegTokenDefault(code int) *SubnetRegTokenDefault {
if code <= 0 {
code = 500
}
return &SubnetRegTokenDefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the subnet reg token default response
func (o *SubnetRegTokenDefault) WithStatusCode(code int) *SubnetRegTokenDefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the subnet reg token default response
func (o *SubnetRegTokenDefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the subnet reg token default response
func (o *SubnetRegTokenDefault) WithPayload(payload *models.APIError) *SubnetRegTokenDefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the subnet reg token default response
func (o *SubnetRegTokenDefault) SetPayload(payload *models.APIError) {
o.Payload = payload
}
// WriteResponse to the client
func (o *SubnetRegTokenDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(o._statusCode)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}

View File

@@ -1,104 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"errors"
"net/url"
golangswaggerpaths "path"
)
// SubnetRegTokenURL generates an URL for the subnet reg token operation
type SubnetRegTokenURL struct {
_basePath string
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *SubnetRegTokenURL) WithBasePath(bp string) *SubnetRegTokenURL {
o.SetBasePath(bp)
return o
}
// SetBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *SubnetRegTokenURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *SubnetRegTokenURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/subnet/registration-token"
_basePath := o._basePath
if _basePath == "" {
_basePath = "/api/v1"
}
_result.Path = golangswaggerpaths.Join(_basePath, _path)
return &_result, nil
}
// Must is a helper function to panic when the url builder returns an error
func (o *SubnetRegTokenURL) Must(u *url.URL, err error) *url.URL {
if err != nil {
panic(err)
}
if u == nil {
panic("url can't be nil")
}
return u
}
// String returns the string representation of the path with query string
func (o *SubnetRegTokenURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *SubnetRegTokenURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on SubnetRegTokenURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on SubnetRegTokenURL")
}
base, err := o.Build()
if err != nil {
return nil, err
}
base.Scheme = scheme
base.Host = host
return base, nil
}
// StringFull returns the string representation of a complete url
func (o *SubnetRegTokenURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -1,88 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"net/http"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models"
)
// SubnetRegisterHandlerFunc turns a function with the right signature into a subnet register handler
type SubnetRegisterHandlerFunc func(SubnetRegisterParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn SubnetRegisterHandlerFunc) Handle(params SubnetRegisterParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// SubnetRegisterHandler interface for that can handle valid subnet register params
type SubnetRegisterHandler interface {
Handle(SubnetRegisterParams, *models.Principal) middleware.Responder
}
// NewSubnetRegister creates a new http.Handler for the subnet register operation
func NewSubnetRegister(ctx *middleware.Context, handler SubnetRegisterHandler) *SubnetRegister {
return &SubnetRegister{Context: ctx, Handler: handler}
}
/*
SubnetRegister swagger:route POST /subnet/register Subnet subnetRegister
Register cluster with Subnet
*/
type SubnetRegister struct {
Context *middleware.Context
Handler SubnetRegisterHandler
}
func (o *SubnetRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewSubnetRegisterParams()
uprinc, aCtx, err := o.Context.Authorize(r, route)
if err != nil {
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
if aCtx != nil {
*r = *aCtx
}
var principal *models.Principal
if uprinc != nil {
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
}
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params, principal) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -1,101 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"io"
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/validate"
"github.com/minio/console/models"
)
// NewSubnetRegisterParams creates a new SubnetRegisterParams object
//
// There are no default values defined in the spec.
func NewSubnetRegisterParams() SubnetRegisterParams {
return SubnetRegisterParams{}
}
// SubnetRegisterParams contains all the bound params for the subnet register operation
// typically these are obtained from a http.Request
//
// swagger:parameters SubnetRegister
type SubnetRegisterParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
/*
Required: true
In: body
*/
Body *models.SubnetRegisterRequest
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
// for simple values it will use straight method calls.
//
// To ensure default values, the struct must have been initialized with NewSubnetRegisterParams() beforehand.
func (o *SubnetRegisterParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
if runtime.HasBody(r) {
defer r.Body.Close()
var body models.SubnetRegisterRequest
if err := route.Consumer.Consume(r.Body, &body); err != nil {
if err == io.EOF {
res = append(res, errors.Required("body", "body", ""))
} else {
res = append(res, errors.NewParseError("body", "body", "", err))
}
} else {
// validate body object
if err := body.Validate(route.Formats); err != nil {
res = append(res, err)
}
ctx := validate.WithOperationRequest(r.Context())
if err := body.ContextValidate(ctx, route.Formats); err != nil {
res = append(res, err)
}
if len(res) == 0 {
o.Body = &body
}
}
} else {
res = append(res, errors.Required("body", "body", ""))
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,115 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/runtime"
"github.com/minio/console/models"
)
// SubnetRegisterOKCode is the HTTP code returned for type SubnetRegisterOK
const SubnetRegisterOKCode int = 200
/*
SubnetRegisterOK A successful response.
swagger:response subnetRegisterOK
*/
type SubnetRegisterOK struct {
}
// NewSubnetRegisterOK creates SubnetRegisterOK with default headers values
func NewSubnetRegisterOK() *SubnetRegisterOK {
return &SubnetRegisterOK{}
}
// WriteResponse to the client
func (o *SubnetRegisterOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
rw.WriteHeader(200)
}
/*
SubnetRegisterDefault Generic error response.
swagger:response subnetRegisterDefault
*/
type SubnetRegisterDefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.APIError `json:"body,omitempty"`
}
// NewSubnetRegisterDefault creates SubnetRegisterDefault with default headers values
func NewSubnetRegisterDefault(code int) *SubnetRegisterDefault {
if code <= 0 {
code = 500
}
return &SubnetRegisterDefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the subnet register default response
func (o *SubnetRegisterDefault) WithStatusCode(code int) *SubnetRegisterDefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the subnet register default response
func (o *SubnetRegisterDefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the subnet register default response
func (o *SubnetRegisterDefault) WithPayload(payload *models.APIError) *SubnetRegisterDefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the subnet register default response
func (o *SubnetRegisterDefault) SetPayload(payload *models.APIError) {
o.Payload = payload
}
// WriteResponse to the client
func (o *SubnetRegisterDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(o._statusCode)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}

View File

@@ -1,104 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"errors"
"net/url"
golangswaggerpaths "path"
)
// SubnetRegisterURL generates an URL for the subnet register operation
type SubnetRegisterURL struct {
_basePath string
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *SubnetRegisterURL) WithBasePath(bp string) *SubnetRegisterURL {
o.SetBasePath(bp)
return o
}
// SetBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *SubnetRegisterURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *SubnetRegisterURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/subnet/register"
_basePath := o._basePath
if _basePath == "" {
_basePath = "/api/v1"
}
_result.Path = golangswaggerpaths.Join(_basePath, _path)
return &_result, nil
}
// Must is a helper function to panic when the url builder returns an error
func (o *SubnetRegisterURL) Must(u *url.URL, err error) *url.URL {
if err != nil {
panic(err)
}
if u == nil {
panic("url can't be nil")
}
return u
}
// String returns the string representation of the path with query string
func (o *SubnetRegisterURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *SubnetRegisterURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on SubnetRegisterURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on SubnetRegisterURL")
}
base, err := o.Build()
if err != nil {
return nil, err
}
base.Scheme = scheme
base.Host = host
return base, nil
}
// StringFull returns the string representation of a complete url
func (o *SubnetRegisterURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -1,88 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 support
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"net/http"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models"
)
// GetCallHomeOptionValueHandlerFunc turns a function with the right signature into a get call home option value handler
type GetCallHomeOptionValueHandlerFunc func(GetCallHomeOptionValueParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn GetCallHomeOptionValueHandlerFunc) Handle(params GetCallHomeOptionValueParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// GetCallHomeOptionValueHandler interface for that can handle valid get call home option value params
type GetCallHomeOptionValueHandler interface {
Handle(GetCallHomeOptionValueParams, *models.Principal) middleware.Responder
}
// NewGetCallHomeOptionValue creates a new http.Handler for the get call home option value operation
func NewGetCallHomeOptionValue(ctx *middleware.Context, handler GetCallHomeOptionValueHandler) *GetCallHomeOptionValue {
return &GetCallHomeOptionValue{Context: ctx, Handler: handler}
}
/*
GetCallHomeOptionValue swagger:route GET /support/callhome Support getCallHomeOptionValue
Get Callhome current status
*/
type GetCallHomeOptionValue struct {
Context *middleware.Context
Handler GetCallHomeOptionValueHandler
}
func (o *GetCallHomeOptionValue) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewGetCallHomeOptionValueParams()
uprinc, aCtx, err := o.Context.Authorize(r, route)
if err != nil {
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
if aCtx != nil {
*r = *aCtx
}
var principal *models.Principal
if uprinc != nil {
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
}
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params, principal) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -1,63 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 support
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime/middleware"
)
// NewGetCallHomeOptionValueParams creates a new GetCallHomeOptionValueParams object
//
// There are no default values defined in the spec.
func NewGetCallHomeOptionValueParams() GetCallHomeOptionValueParams {
return GetCallHomeOptionValueParams{}
}
// GetCallHomeOptionValueParams contains all the bound params for the get call home option value operation
// typically these are obtained from a http.Request
//
// swagger:parameters GetCallHomeOptionValue
type GetCallHomeOptionValueParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
// for simple values it will use straight method calls.
//
// To ensure default values, the struct must have been initialized with NewGetCallHomeOptionValueParams() beforehand.
func (o *GetCallHomeOptionValueParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,135 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 support
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/runtime"
"github.com/minio/console/models"
)
// GetCallHomeOptionValueOKCode is the HTTP code returned for type GetCallHomeOptionValueOK
const GetCallHomeOptionValueOKCode int = 200
/*
GetCallHomeOptionValueOK A successful response.
swagger:response getCallHomeOptionValueOK
*/
type GetCallHomeOptionValueOK struct {
/*
In: Body
*/
Payload *models.CallHomeGetResponse `json:"body,omitempty"`
}
// NewGetCallHomeOptionValueOK creates GetCallHomeOptionValueOK with default headers values
func NewGetCallHomeOptionValueOK() *GetCallHomeOptionValueOK {
return &GetCallHomeOptionValueOK{}
}
// WithPayload adds the payload to the get call home option value o k response
func (o *GetCallHomeOptionValueOK) WithPayload(payload *models.CallHomeGetResponse) *GetCallHomeOptionValueOK {
o.Payload = payload
return o
}
// SetPayload sets the payload to the get call home option value o k response
func (o *GetCallHomeOptionValueOK) SetPayload(payload *models.CallHomeGetResponse) {
o.Payload = payload
}
// WriteResponse to the client
func (o *GetCallHomeOptionValueOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(200)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}
/*
GetCallHomeOptionValueDefault Generic error response.
swagger:response getCallHomeOptionValueDefault
*/
type GetCallHomeOptionValueDefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.APIError `json:"body,omitempty"`
}
// NewGetCallHomeOptionValueDefault creates GetCallHomeOptionValueDefault with default headers values
func NewGetCallHomeOptionValueDefault(code int) *GetCallHomeOptionValueDefault {
if code <= 0 {
code = 500
}
return &GetCallHomeOptionValueDefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the get call home option value default response
func (o *GetCallHomeOptionValueDefault) WithStatusCode(code int) *GetCallHomeOptionValueDefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the get call home option value default response
func (o *GetCallHomeOptionValueDefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the get call home option value default response
func (o *GetCallHomeOptionValueDefault) WithPayload(payload *models.APIError) *GetCallHomeOptionValueDefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the get call home option value default response
func (o *GetCallHomeOptionValueDefault) SetPayload(payload *models.APIError) {
o.Payload = payload
}
// WriteResponse to the client
func (o *GetCallHomeOptionValueDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(o._statusCode)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}

View File

@@ -1,104 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 support
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"errors"
"net/url"
golangswaggerpaths "path"
)
// GetCallHomeOptionValueURL generates an URL for the get call home option value operation
type GetCallHomeOptionValueURL struct {
_basePath string
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *GetCallHomeOptionValueURL) WithBasePath(bp string) *GetCallHomeOptionValueURL {
o.SetBasePath(bp)
return o
}
// SetBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *GetCallHomeOptionValueURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *GetCallHomeOptionValueURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/support/callhome"
_basePath := o._basePath
if _basePath == "" {
_basePath = "/api/v1"
}
_result.Path = golangswaggerpaths.Join(_basePath, _path)
return &_result, nil
}
// Must is a helper function to panic when the url builder returns an error
func (o *GetCallHomeOptionValueURL) Must(u *url.URL, err error) *url.URL {
if err != nil {
panic(err)
}
if u == nil {
panic("url can't be nil")
}
return u
}
// String returns the string representation of the path with query string
func (o *GetCallHomeOptionValueURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *GetCallHomeOptionValueURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on GetCallHomeOptionValueURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on GetCallHomeOptionValueURL")
}
base, err := o.Build()
if err != nil {
return nil, err
}
base.Scheme = scheme
base.Host = host
return base, nil
}
// StringFull returns the string representation of a complete url
func (o *GetCallHomeOptionValueURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -1,88 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 support
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"net/http"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models"
)
// SetCallHomeStatusHandlerFunc turns a function with the right signature into a set call home status handler
type SetCallHomeStatusHandlerFunc func(SetCallHomeStatusParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn SetCallHomeStatusHandlerFunc) Handle(params SetCallHomeStatusParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// SetCallHomeStatusHandler interface for that can handle valid set call home status params
type SetCallHomeStatusHandler interface {
Handle(SetCallHomeStatusParams, *models.Principal) middleware.Responder
}
// NewSetCallHomeStatus creates a new http.Handler for the set call home status operation
func NewSetCallHomeStatus(ctx *middleware.Context, handler SetCallHomeStatusHandler) *SetCallHomeStatus {
return &SetCallHomeStatus{Context: ctx, Handler: handler}
}
/*
SetCallHomeStatus swagger:route PUT /support/callhome Support setCallHomeStatus
Sets callhome status
*/
type SetCallHomeStatus struct {
Context *middleware.Context
Handler SetCallHomeStatusHandler
}
func (o *SetCallHomeStatus) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewSetCallHomeStatusParams()
uprinc, aCtx, err := o.Context.Authorize(r, route)
if err != nil {
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
if aCtx != nil {
*r = *aCtx
}
var principal *models.Principal
if uprinc != nil {
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
}
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params, principal) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -1,101 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 support
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"io"
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/validate"
"github.com/minio/console/models"
)
// NewSetCallHomeStatusParams creates a new SetCallHomeStatusParams object
//
// There are no default values defined in the spec.
func NewSetCallHomeStatusParams() SetCallHomeStatusParams {
return SetCallHomeStatusParams{}
}
// SetCallHomeStatusParams contains all the bound params for the set call home status operation
// typically these are obtained from a http.Request
//
// swagger:parameters SetCallHomeStatus
type SetCallHomeStatusParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
/*
Required: true
In: body
*/
Body *models.CallHomeSetStatus
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
// for simple values it will use straight method calls.
//
// To ensure default values, the struct must have been initialized with NewSetCallHomeStatusParams() beforehand.
func (o *SetCallHomeStatusParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
if runtime.HasBody(r) {
defer r.Body.Close()
var body models.CallHomeSetStatus
if err := route.Consumer.Consume(r.Body, &body); err != nil {
if err == io.EOF {
res = append(res, errors.Required("body", "body", ""))
} else {
res = append(res, errors.NewParseError("body", "body", "", err))
}
} else {
// validate body object
if err := body.Validate(route.Formats); err != nil {
res = append(res, err)
}
ctx := validate.WithOperationRequest(r.Context())
if err := body.ContextValidate(ctx, route.Formats); err != nil {
res = append(res, err)
}
if len(res) == 0 {
o.Body = &body
}
}
} else {
res = append(res, errors.Required("body", "body", ""))
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,115 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 support
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/runtime"
"github.com/minio/console/models"
)
// SetCallHomeStatusNoContentCode is the HTTP code returned for type SetCallHomeStatusNoContent
const SetCallHomeStatusNoContentCode int = 204
/*
SetCallHomeStatusNoContent A successful response.
swagger:response setCallHomeStatusNoContent
*/
type SetCallHomeStatusNoContent struct {
}
// NewSetCallHomeStatusNoContent creates SetCallHomeStatusNoContent with default headers values
func NewSetCallHomeStatusNoContent() *SetCallHomeStatusNoContent {
return &SetCallHomeStatusNoContent{}
}
// WriteResponse to the client
func (o *SetCallHomeStatusNoContent) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
rw.WriteHeader(204)
}
/*
SetCallHomeStatusDefault Generic error response.
swagger:response setCallHomeStatusDefault
*/
type SetCallHomeStatusDefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.APIError `json:"body,omitempty"`
}
// NewSetCallHomeStatusDefault creates SetCallHomeStatusDefault with default headers values
func NewSetCallHomeStatusDefault(code int) *SetCallHomeStatusDefault {
if code <= 0 {
code = 500
}
return &SetCallHomeStatusDefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the set call home status default response
func (o *SetCallHomeStatusDefault) WithStatusCode(code int) *SetCallHomeStatusDefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the set call home status default response
func (o *SetCallHomeStatusDefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the set call home status default response
func (o *SetCallHomeStatusDefault) WithPayload(payload *models.APIError) *SetCallHomeStatusDefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the set call home status default response
func (o *SetCallHomeStatusDefault) SetPayload(payload *models.APIError) {
o.Payload = payload
}
// WriteResponse to the client
func (o *SetCallHomeStatusDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(o._statusCode)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}

View File

@@ -1,104 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 support
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"errors"
"net/url"
golangswaggerpaths "path"
)
// SetCallHomeStatusURL generates an URL for the set call home status operation
type SetCallHomeStatusURL struct {
_basePath string
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *SetCallHomeStatusURL) WithBasePath(bp string) *SetCallHomeStatusURL {
o.SetBasePath(bp)
return o
}
// SetBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *SetCallHomeStatusURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *SetCallHomeStatusURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/support/callhome"
_basePath := o._basePath
if _basePath == "" {
_basePath = "/api/v1"
}
_result.Path = golangswaggerpaths.Join(_basePath, _path)
return &_result, nil
}
// Must is a helper function to panic when the url builder returns an error
func (o *SetCallHomeStatusURL) Must(u *url.URL, err error) *url.URL {
if err != nil {
panic(err)
}
if u == nil {
panic("url can't be nil")
}
return u
}
// String returns the string representation of the path with query string
func (o *SetCallHomeStatusURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *SetCallHomeStatusURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on SetCallHomeStatusURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on SetCallHomeStatusURL")
}
base, err := o.Build()
if err != nil {
return nil, err
}
base.Scheme = scheme
base.Host = host
return base, nil
}
// StringFull returns the string representation of a complete url
func (o *SetCallHomeStatusURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -1,232 +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 api
import (
"errors"
"fmt"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/api/operations"
"github.com/minio/console/api/operations/support"
"github.com/minio/console/models"
"github.com/minio/console/pkg/subnet"
"golang.org/x/net/context"
)
type ConfigurationSetItem struct {
Value string
Enable bool
}
func registerSupportHandlers(api *operations.ConsoleAPI) {
// callhome handlers
api.SupportGetCallHomeOptionValueHandler = support.GetCallHomeOptionValueHandlerFunc(func(params support.GetCallHomeOptionValueParams, session *models.Principal) middleware.Responder {
callhomeResp, err := getCallHomeOptionResponse(session, params)
if err != nil {
return support.NewGetCallHomeOptionValueDefault(err.Code).WithPayload(err.APIError)
}
return support.NewGetCallHomeOptionValueOK().WithPayload(callhomeResp)
})
api.SupportSetCallHomeStatusHandler = support.SetCallHomeStatusHandlerFunc(func(params support.SetCallHomeStatusParams, session *models.Principal) middleware.Responder {
err := editCallHomeOptionResponse(session, params)
if err != nil {
return support.NewSetCallHomeStatusDefault(err.Code).WithPayload(err.APIError)
}
return support.NewSetCallHomeStatusNoContent()
})
}
// getCallHomeOptionResponse returns the selected option value
func getCallHomeOptionResponse(session *models.Principal, params support.GetCallHomeOptionValueParams) (*models.CallHomeGetResponse, *CodedAPIError) {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
minioClient := AdminClient{Client: mAdmin}
response, err := getCallHomeRule(ctx, minioClient)
if err != nil {
return nil, ErrorWithContext(ctx, err)
}
return response, nil
}
func getCallHomeRule(ctx context.Context, client MinioAdmin) (*models.CallHomeGetResponse, error) {
// We verify if callhome SubSys is supported
supportedSubSys, err := minioConfigSupportsSubSys(ctx, client, "callhome")
if err != nil {
return nil, err
}
var returnResponse models.CallHomeGetResponse
// SubSys is not supported, hence callhome is disabled.
if !supportedSubSys {
returnResponse.DiagnosticsStatus = false
returnResponse.LogsStatus = false
return &returnResponse, nil
}
diagnosticsProps, err := getConfig(ctx, client, "callhome")
if err != nil {
return nil, err
}
diagnosticsSt := true
for _, properties := range diagnosticsProps {
for _, property := range properties.KeyValues {
if property.Key == "enable" {
diagnosticsSt = property.Value == "on"
}
}
}
loggerSt := true
loggerProps, err := getConfig(ctx, client, "logger_webhook:subnet")
// Logger not defined, then it is disabled.
if err != nil {
loggerSt = false
} else {
for _, logger := range loggerProps {
for _, property := range logger.KeyValues {
if property.Key == "enable" {
loggerSt = property.Value == "on"
}
}
}
}
returnModel := models.CallHomeGetResponse{DiagnosticsStatus: diagnosticsSt, LogsStatus: loggerSt}
return &returnModel, nil
}
// editCallHomeOptionResponse returns if there was an error setting the option
func editCallHomeOptionResponse(session *models.Principal, params support.SetCallHomeStatusParams) *CodedAPIError {
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
defer cancel()
mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session)
if err != nil {
return ErrorWithContext(ctx, err)
}
minioClient := AdminClient{Client: mAdmin}
err = setCallHomeConfiguration(ctx, minioClient, *params.Body.DiagState, *params.Body.LogsState)
if err != nil {
return ErrorWithContext(ctx, err)
}
return nil
}
func configureCallHomeDiagnostics(ctx context.Context, client MinioAdmin, diagState bool) error {
// We verify if callhome SubSys is supported
supportedSubSys, err := minioConfigSupportsSubSys(ctx, client, "callhome")
if err != nil {
return err
}
// SubSys is not supported, hence callhome not available
if !supportedSubSys {
return errors.New("your version of MinIO doesn't support this configuration")
}
enableStr := "off"
if diagState {
enableStr = "on"
}
configStr := "callhome enable=" + enableStr
_, err = client.setConfigKV(ctx, configStr)
if err != nil {
return err
}
return nil
}
func configureCallHomeLogs(ctx context.Context, client MinioAdmin, logState bool, apiKey string) error {
var configStr string
if logState {
configStr = fmt.Sprintf("logger_webhook:subnet endpoint=%s auth_token=%s enable=on",
subnet.LogWebhookURL(), apiKey)
} else {
configStr = "logger_webhook:subnet enable=off"
}
// Call set config API
_, err := client.setConfigKV(ctx, configStr)
if err != nil {
return err
}
return nil
}
func setCallHomeConfiguration(ctx context.Context, client MinioAdmin, diagState, logsState bool) error {
tokenConfig, err := GetSubnetKeyFromMinIOConfig(ctx, client)
if err != nil {
return err
}
apiKey := tokenConfig.APIKey
if len(apiKey) == 0 {
return errors.New("please register this cluster in subnet to continue")
}
err = configureCallHomeDiagnostics(ctx, client, diagState)
if err != nil {
return err
}
err = configureCallHomeLogs(ctx, client, logsState, apiKey)
if err != nil {
return err
}
return nil
}
func minioConfigSupportsSubSys(ctx context.Context, client MinioAdmin, subSys string) (bool, error) {
help, err := client.helpConfigKVGlobal(ctx, false)
if err != nil {
return false, err
}
for _, h := range help.KeysHelp {
if h.Key == subSys {
return true, nil
}
}
return false, nil
}

View File

@@ -1,382 +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 api
import (
"context"
"errors"
"testing"
"github.com/minio/console/models"
"github.com/minio/madmin-go/v3"
)
func Test_getCallHomeRule(t *testing.T) {
type args struct {
ctx context.Context
session *models.Principal
}
ctx := context.Background()
tests := []struct {
name string
args args
helpConfigKVGlobal func(envOnly bool) (madmin.Help, error)
helpConfigKV func(subSys, key string, envOnly bool) (madmin.Help, error)
getConfigKV func(key string) ([]byte, error)
want *models.CallHomeGetResponse
wantErr bool
}{
{
name: "subsys is not supported, dont crash / return anything",
args: args{
ctx: ctx,
session: nil,
},
helpConfigKV: func(_, _ string, _ bool) (madmin.Help, error) {
return madmin.Help{}, errors.New("feature is not supported")
},
getConfigKV: func(_ string) ([]byte, error) {
return []byte{}, nil
},
helpConfigKVGlobal: func(_ bool) (madmin.Help, error) {
return madmin.Help{
SubSys: "",
Description: "",
MultipleTargets: false,
KeysHelp: madmin.HelpKVS{},
}, nil
},
want: nil,
wantErr: false,
},
{
name: "callhome enabled",
args: args{
ctx: ctx,
session: nil,
},
helpConfigKVGlobal: func(_ bool) (madmin.Help, error) {
return madmin.Help{
SubSys: "",
Description: "",
MultipleTargets: false,
KeysHelp: madmin.HelpKVS{
{Key: "callhome", Description: "enable callhome for the cluster", Optional: true, Type: "string", MultipleTargets: false},
},
}, nil
},
helpConfigKV: func(_, _ string, _ bool) (madmin.Help, error) {
return madmin.Help{
SubSys: "callhome",
Description: "enable callhome for the cluster",
MultipleTargets: false,
KeysHelp: madmin.HelpKVS{
{Key: "frequency", Type: "duration", Optional: true, MultipleTargets: false},
{Key: "enable", Type: "on|off", Optional: true, MultipleTargets: false},
},
}, nil
},
getConfigKV: func(_ string) ([]byte, error) {
return []byte(`callhome:_ frequency=24h enable=on`), nil
},
want: &models.CallHomeGetResponse{
DiagnosticsStatus: true,
},
wantErr: false,
},
{
name: "callhome is disabled",
args: args{
ctx: ctx,
session: nil,
},
helpConfigKVGlobal: func(_ bool) (madmin.Help, error) {
return madmin.Help{
SubSys: "",
Description: "",
MultipleTargets: false,
KeysHelp: madmin.HelpKVS{
{Key: "callhome", Description: "enable callhome for the cluster", Optional: true, Type: "string", MultipleTargets: false},
},
}, nil
},
helpConfigKV: func(_, _ string, _ bool) (madmin.Help, error) {
return madmin.Help{
SubSys: "callhome",
Description: "enable callhome for the cluster",
MultipleTargets: false,
KeysHelp: madmin.HelpKVS{
{Key: "frequency", Type: "duration", Optional: true, MultipleTargets: false},
{Key: "enable", Type: "on|off", Optional: true, MultipleTargets: false},
},
}, nil
},
getConfigKV: func(_ string) ([]byte, error) {
return []byte(`callhome:_ frequency=24h enable=off`), nil
},
want: &models.CallHomeGetResponse{
DiagnosticsStatus: false,
},
wantErr: false,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(_ *testing.T) {
adminClient := AdminClientMock{}
minioGetConfigKVMock = tt.getConfigKV
minioHelpConfigKVMock = tt.helpConfigKV
minioHelpConfigKVGlobalMock = tt.helpConfigKVGlobal
response, err := getCallHomeRule(tt.args.ctx, adminClient)
if (err != nil) != tt.wantErr {
t.Errorf("getCallHomeRule() error = %v, wantErr %v", err, tt.wantErr)
return
}
if tt.want != nil {
if response.DiagnosticsStatus != tt.want.DiagnosticsStatus {
t.Errorf("getCallHomeRule() got status = %v, want status %v", response.DiagnosticsStatus, tt.want.DiagnosticsStatus)
}
}
})
}
}
func Test_setCallHomeConfiguration(t *testing.T) {
type args struct {
ctx context.Context
session *models.Principal
diagState bool
}
ctx := context.Background()
tests := []struct {
name string
args args
helpConfigKVGlobal func(envOnly bool) (madmin.Help, error)
helpConfigKV func(subSys, key string, envOnly bool) (madmin.Help, error)
getConfigKV func(key string) ([]byte, error)
setConfigEnv func(kv string) (restart bool, err error)
wantErr bool
error error
}{
{
name: "subsys is not supported, return error",
args: args{
ctx: ctx,
session: nil,
diagState: false,
},
helpConfigKV: func(_, _ string, _ bool) (madmin.Help, error) {
return madmin.Help{}, errors.New("feature is not supported")
},
getConfigKV: func(_ string) ([]byte, error) {
return []byte{}, nil
},
helpConfigKVGlobal: func(_ bool) (madmin.Help, error) {
return madmin.Help{
SubSys: "",
Description: "",
MultipleTargets: false,
KeysHelp: madmin.HelpKVS{},
}, nil
},
setConfigEnv: func(_ string) (restart bool, err error) {
return false, nil
},
wantErr: true,
error: errors.New("unable to find subnet configuration"),
},
{
name: "cluster not registered",
args: args{
ctx: ctx,
session: nil,
diagState: false,
},
helpConfigKV: func(_, _ string, _ bool) (madmin.Help, error) {
return madmin.Help{
SubSys: "subnet",
Description: "set subnet config for the cluster e.g. api key",
MultipleTargets: false,
KeysHelp: madmin.HelpKVS{
{Key: "license", Type: "string", Optional: true, MultipleTargets: false},
{Key: "api_key", Type: "string", Optional: true, MultipleTargets: false},
{Key: "proxy", Type: "string", Optional: true, MultipleTargets: false},
},
}, nil
},
getConfigKV: func(_ string) ([]byte, error) {
return []byte(`subnet license= api_key= proxy=http://127.0.0.1 `), nil
},
helpConfigKVGlobal: func(_ bool) (madmin.Help, error) {
return madmin.Help{
SubSys: "",
Description: "",
MultipleTargets: false,
KeysHelp: madmin.HelpKVS{
{Key: "callhome", Description: "enable callhome for the cluster", Optional: true, Type: "string", MultipleTargets: false},
},
}, nil
},
setConfigEnv: func(_ string) (restart bool, err error) {
return false, nil
},
wantErr: true,
error: errors.New("please register this cluster in subnet to continue"),
},
{
name: "enable without errors",
args: args{
ctx: ctx,
session: nil,
diagState: true,
},
helpConfigKV: func(_, _ string, _ bool) (madmin.Help, error) {
return madmin.Help{
SubSys: "subnet",
Description: "set subnet config for the cluster e.g. api key",
MultipleTargets: false,
KeysHelp: madmin.HelpKVS{
{Key: "license", Type: "string", Optional: true, MultipleTargets: false},
{Key: "api_key", Type: "string", Optional: true, MultipleTargets: false},
{Key: "proxy", Type: "string", Optional: true, MultipleTargets: false},
},
}, nil
},
getConfigKV: func(_ string) ([]byte, error) {
return []byte(`subnet license= api_key=testAPIKey proxy=http://127.0.0.1 `), nil
},
helpConfigKVGlobal: func(_ bool) (madmin.Help, error) {
return madmin.Help{
SubSys: "",
Description: "",
MultipleTargets: false,
KeysHelp: madmin.HelpKVS{
{Key: "callhome", Description: "enable callhome for the cluster", Optional: true, Type: "string", MultipleTargets: false},
},
}, nil
},
setConfigEnv: func(_ string) (restart bool, err error) {
return false, nil
},
wantErr: false,
error: nil,
},
{
name: "disable without errors",
args: args{
ctx: ctx,
session: nil,
diagState: false,
},
helpConfigKV: func(_, _ string, _ bool) (madmin.Help, error) {
return madmin.Help{
SubSys: "subnet",
Description: "set subnet config for the cluster e.g. api key",
MultipleTargets: false,
KeysHelp: madmin.HelpKVS{
{Key: "license", Type: "string", Optional: true, MultipleTargets: false},
{Key: "api_key", Type: "string", Optional: true, MultipleTargets: false},
{Key: "proxy", Type: "string", Optional: true, MultipleTargets: false},
},
}, nil
},
getConfigKV: func(_ string) ([]byte, error) {
return []byte(`subnet license= api_key=testAPIKey proxy=http://127.0.0.1 `), nil
},
helpConfigKVGlobal: func(_ bool) (madmin.Help, error) {
return madmin.Help{
SubSys: "",
Description: "",
MultipleTargets: false,
KeysHelp: madmin.HelpKVS{
{Key: "callhome", Description: "enable callhome for the cluster", Optional: true, Type: "string", MultipleTargets: false},
},
}, nil
},
setConfigEnv: func(_ string) (restart bool, err error) {
return false, nil
},
wantErr: false,
error: nil,
},
{
name: "Error setting diagState",
args: args{
ctx: ctx,
session: nil,
diagState: false,
},
helpConfigKV: func(_, _ string, _ bool) (madmin.Help, error) {
return madmin.Help{
SubSys: "subnet",
Description: "set subnet config for the cluster e.g. api key",
MultipleTargets: false,
KeysHelp: madmin.HelpKVS{
{Key: "license", Type: "string", Optional: true, MultipleTargets: false},
{Key: "api_key", Type: "string", Optional: true, MultipleTargets: false},
{Key: "proxy", Type: "string", Optional: true, MultipleTargets: false},
},
}, nil
},
getConfigKV: func(_ string) ([]byte, error) {
return []byte(`subnet license= api_key=testAPIKey proxy=http://127.0.0.1 `), nil
},
helpConfigKVGlobal: func(_ bool) (madmin.Help, error) {
return madmin.Help{
SubSys: "",
Description: "",
MultipleTargets: false,
KeysHelp: madmin.HelpKVS{
{Key: "callhome", Description: "enable callhome for the cluster", Optional: true, Type: "string", MultipleTargets: false},
},
}, nil
},
setConfigEnv: func(_ string) (restart bool, err error) {
return false, errors.New("new error detected")
},
wantErr: true,
error: errors.New("new error detected"),
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(_ *testing.T) {
adminClient := AdminClientMock{}
minioGetConfigKVMock = tt.getConfigKV
minioHelpConfigKVMock = tt.helpConfigKV
minioHelpConfigKVGlobalMock = tt.helpConfigKVGlobal
minioSetConfigKVMock = tt.setConfigEnv
err := setCallHomeConfiguration(tt.args.ctx, adminClient, tt.args.diagState, false)
if (err != nil) != tt.wantErr {
t.Errorf("setCallHomeConfiguration() error = %v, wantErr %v", err, tt.wantErr)
return
}
if tt.wantErr {
if tt.error.Error() != err.Error() {
t.Errorf("setCallHomeConfiguration() error mismatch, error = %v, wantErr %v", err.Error(), tt.error.Error())
return
}
}
})
}
}

View File

@@ -23,17 +23,12 @@ import (
"log"
"net"
"net/http"
"strconv"
"strings"
"time"
"github.com/minio/madmin-go/v3"
"github.com/minio/console/pkg/utils"
errorsApi "github.com/go-openapi/errors"
"github.com/minio/console/models"
"github.com/minio/console/pkg/auth"
"github.com/minio/console/pkg/utils"
"github.com/minio/websocket"
)
@@ -65,13 +60,6 @@ type ConsoleWebsocket interface {
watch(options watchOptions)
}
type wsS3Client struct {
// websocket connection.
conn wsConn
// mcClient
client MCClient
}
// ConsoleWebSocketMClient interface of a Websocket Client
type ConsoleWebsocketMClient interface {
objectManager(options objectsListOpts)
@@ -188,42 +176,6 @@ func serveWS(w http.ResponseWriter, req *http.Request) {
}
switch {
case strings.HasPrefix(wsPath, `/trace`):
wsAdminClient, err := newWebSocketAdminClient(conn, session, clientIP)
if err != nil {
ErrorWithContext(ctx, err)
closeWsConn(conn)
return
}
calls := req.URL.Query().Get("calls")
threshold, _ := strconv.ParseInt(req.URL.Query().Get("threshold"), 10, 64)
onlyErrors := req.URL.Query().Get("onlyErrors")
stCode, errorStCode := strconv.ParseInt(req.URL.Query().Get("statusCode"), 10, 64)
method := req.URL.Query().Get("method")
funcName := req.URL.Query().Get("funcname")
path := req.URL.Query().Get("path")
statusCode := int64(0)
if errorStCode == nil {
statusCode = stCode
}
traceRequestItem := TraceRequest{
s3: strings.Contains(calls, "s3") || strings.Contains(calls, "all"),
internal: strings.Contains(calls, "internal") || strings.Contains(calls, "all"),
storage: strings.Contains(calls, "storage") || strings.Contains(calls, "all"),
os: strings.Contains(calls, "os") || strings.Contains(calls, "all"),
onlyErrors: onlyErrors == "yes",
threshold: threshold,
statusCode: statusCode,
method: method,
funcName: funcName,
path: path,
}
go wsAdminClient.trace(ctx, traceRequestItem)
case strings.HasPrefix(wsPath, `/console`):
wsAdminClient, err := newWebSocketAdminClient(conn, session, clientIP)
@@ -240,63 +192,6 @@ func serveWS(w http.ResponseWriter, req *http.Request) {
logType: logType,
}
go wsAdminClient.console(ctx, logRequestItem)
case strings.HasPrefix(wsPath, `/health-info`):
deadline, err := getHealthInfoOptionsFromReq(req)
if err != nil {
ErrorWithContext(ctx, fmt.Errorf("error getting health info options: %v", err))
closeWsConn(conn)
return
}
wsAdminClient, err := newWebSocketAdminClient(conn, session, clientIP)
if err != nil {
ErrorWithContext(ctx, err)
closeWsConn(conn)
return
}
go wsAdminClient.healthInfo(ctx, deadline)
case strings.HasPrefix(wsPath, `/watch`):
wOptions, err := getWatchOptionsFromReq(req)
if err != nil {
ErrorWithContext(ctx, fmt.Errorf("error getting watch options: %v", err))
closeWsConn(conn)
return
}
wsS3Client, err := newWebSocketS3Client(conn, session, wOptions.BucketName, "", clientIP)
if err != nil {
ErrorWithContext(ctx, err)
closeWsConn(conn)
return
}
go wsS3Client.watch(ctx, wOptions)
case strings.HasPrefix(wsPath, `/speedtest`):
speedtestOpts, err := getSpeedtestOptionsFromReq(req)
if err != nil {
ErrorWithContext(ctx, fmt.Errorf("error getting speedtest options: %v", err))
closeWsConn(conn)
return
}
wsAdminClient, err := newWebSocketAdminClient(conn, session, clientIP)
if err != nil {
ErrorWithContext(ctx, err)
closeWsConn(conn)
return
}
go wsAdminClient.speedtest(ctx, speedtestOpts)
case strings.HasPrefix(wsPath, `/profile`):
pOptions, err := getProfileOptionsFromReq(req)
if err != nil {
ErrorWithContext(ctx, fmt.Errorf("error getting profile options: %v", err))
closeWsConn(conn)
return
}
wsAdminClient, err := newWebSocketAdminClient(conn, session, clientIP)
if err != nil {
ErrorWithContext(ctx, err)
closeWsConn(conn)
return
}
go wsAdminClient.profile(ctx, pOptions)
case strings.HasPrefix(wsPath, `/objectManager`):
wsMinioClient, err := newWebSocketMinioClient(conn, session, clientIP)
if err != nil {
@@ -334,26 +229,6 @@ func newWebSocketAdminClient(conn *websocket.Conn, autClaims *models.Principal,
return wsAdminClient, nil
}
// newWebSocketS3Client returns a wsAdminClient authenticated as Console admin
func newWebSocketS3Client(conn *websocket.Conn, claims *models.Principal, bucketName, prefix, clientIP string) (*wsS3Client, error) {
// Only start Websocket Interaction after user has been
// authenticated with MinIO
s3Client, err := newS3BucketClient(claims, bucketName, prefix, clientIP)
if err != nil {
LogError("error creating S3Client:", err)
return nil, err
}
// create a websocket connection interface implementation
// defining the connection to be used
wsConnection := wsConn{conn: conn}
// create a s3Client interface implementation
// defining the client to be used
mcS3C := mcClient{client: s3Client}
// create websocket client and handle request
wsS3Client := &wsS3Client{conn: wsConnection, client: mcS3C}
return wsS3Client, nil
}
func newWebSocketMinioClient(conn *websocket.Conn, claims *models.Principal, clientIP string) (*wsMinioClient, error) {
mClient, err := newMinioClient(claims, clientIP)
if err != nil {
@@ -438,23 +313,6 @@ func closeWsConn(conn *websocket.Conn) {
conn.Close()
}
// trace serves madmin.ServiceTraceInfo
// on a Websocket connection.
func (wsc *wsAdminClient) trace(ctx context.Context, traceRequestItem TraceRequest) {
defer func() {
LogInfo("trace stopped")
// close connection after return
wsc.conn.close()
}()
LogInfo("trace started")
ctx = wsReadClientCtx(ctx, wsc.conn)
err := startTraceInfo(ctx, wsc.conn, wsc.client, traceRequestItem)
sendWsCloseMessage(wsc.conn, err)
}
// console serves madmin.GetLogs
// on a Websocket connection.
func (wsc *wsAdminClient) console(ctx context.Context, logRequestItem LogRequest) {
@@ -472,65 +330,6 @@ func (wsc *wsAdminClient) console(ctx context.Context, logRequestItem LogRequest
sendWsCloseMessage(wsc.conn, err)
}
func (wsc *wsS3Client) watch(ctx context.Context, params *watchOptions) {
defer func() {
LogInfo("watch stopped")
// close connection after return
wsc.conn.close()
}()
LogInfo("watch started")
ctx = wsReadClientCtx(ctx, wsc.conn)
err := startWatch(ctx, wsc.conn, wsc.client, params)
sendWsCloseMessage(wsc.conn, err)
}
func (wsc *wsAdminClient) healthInfo(ctx context.Context, deadline *time.Duration) {
defer func() {
LogInfo("health info stopped")
// close connection after return
wsc.conn.close()
}()
LogInfo("health info started")
ctx = wsReadClientCtx(ctx, wsc.conn)
err := startHealthInfo(ctx, wsc.conn, wsc.client, deadline)
sendWsCloseMessage(wsc.conn, err)
}
func (wsc *wsAdminClient) speedtest(ctx context.Context, opts *madmin.SpeedtestOpts) {
defer func() {
LogInfo("speedtest stopped")
// close connection after return
wsc.conn.close()
}()
LogInfo("speedtest started")
ctx = wsReadClientCtx(ctx, wsc.conn)
err := startSpeedtest(ctx, wsc.conn, wsc.client, opts)
sendWsCloseMessage(wsc.conn, err)
}
func (wsc *wsAdminClient) profile(ctx context.Context, opts *profileOptions) {
defer func() {
LogInfo("profile stopped")
// close connection after return
wsc.conn.close()
}()
LogInfo("profile started")
ctx = wsReadClientCtx(ctx, wsc.conn)
err := startProfiling(ctx, wsc.conn, wsc.client, opts)
sendWsCloseMessage(wsc.conn, err)
}
// sendWsCloseMessage sends Websocket Connection Close Message indicating the Status Code
// see https://tools.ietf.org/html/rfc6455#page-45
func sendWsCloseMessage(conn WSConn, err error) {

View File

@@ -74,7 +74,7 @@ type AddBucketLifecycle struct {
TransitionDays int32 `json:"transition_days,omitempty"`
// ILM Rule type (Expiry or transition)
// Enum: ["expiry","transition"]
// Enum: [expiry transition]
Type string `json:"type,omitempty"`
}

View File

@@ -73,7 +73,7 @@ type AddMultiBucketLifecycle struct {
// ILM Rule type (Expiry or transition)
// Required: true
// Enum: ["expiry","transition"]
// Enum: [expiry transition]
Type *string `json:"type"`
}

View File

@@ -39,7 +39,7 @@ import (
type AdminInfoResponse struct {
// advanced metrics status
// Enum: ["not configured","available","unavailable"]
// Enum: [not configured available unavailable]
AdvancedMetricsStatus string `json:"advancedMetricsStatus,omitempty"`
// backend

View File

@@ -382,7 +382,7 @@ type BucketDetailsQuota struct {
Quota int64 `json:"quota,omitempty"`
// type
// Enum: ["hard"]
// Enum: [hard]
Type string `json:"type,omitempty"`
}

View File

@@ -41,7 +41,7 @@ type BucketQuota struct {
Quota int64 `json:"quota,omitempty"`
// type
// Enum: ["hard"]
// Enum: [hard]
Type string `json:"type,omitempty"`
}

View File

@@ -68,14 +68,14 @@ type BucketReplicationRule struct {
Priority int32 `json:"priority,omitempty"`
// status
// Enum: ["Enabled","Disabled"]
// Enum: [Enabled Disabled]
Status string `json:"status,omitempty"`
// storage class
StorageClass string `json:"storageClass,omitempty"`
// sync mode
// Enum: ["async","sync"]
// Enum: [async sync]
SyncMode *string `json:"syncMode,omitempty"`
// tags

View File

@@ -61,7 +61,7 @@ type CreateRemoteBucket struct {
SourceBucket *string `json:"sourceBucket"`
// sync mode
// Enum: ["async","sync"]
// Enum: [async sync]
SyncMode *string `json:"syncMode,omitempty"`
// target bucket

View File

@@ -45,7 +45,7 @@ type LoginDetails struct {
IsK8S bool `json:"isK8S,omitempty"`
// login strategy
// Enum: ["form","redirect","service-account","redirect-service-account"]
// Enum: [form redirect service-account redirect-service-account]
LoginStrategy string `json:"loginStrategy,omitempty"`
// redirect rules

View File

@@ -83,7 +83,7 @@ type MultiBucketReplication struct {
StorageClass string `json:"storageClass,omitempty"`
// sync mode
// Enum: ["async","sync"]
// Enum: [async sync]
SyncMode *string `json:"syncMode,omitempty"`
// tags

View File

@@ -57,7 +57,7 @@ type RemoteBucket struct {
SecretKey string `json:"secretKey,omitempty"`
// service
// Enum: ["replication"]
// Enum: [replication]
Service string `json:"service,omitempty"`
// source bucket

View File

@@ -63,7 +63,7 @@ type SessionResponse struct {
ServerEndPoint string `json:"serverEndPoint,omitempty"`
// status
// Enum: ["ok"]
// Enum: [ok]
Status string `json:"status,omitempty"`
}

View File

@@ -45,7 +45,7 @@ type SetBucketQuota struct {
Enabled *bool `json:"enabled"`
// quota type
// Enum: ["hard"]
// Enum: [hard]
QuotaType string `json:"quota_type,omitempty"`
}

View File

@@ -1,122 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// SubnetLoginMFARequest subnet login m f a request
//
// swagger:model subnetLoginMFARequest
type SubnetLoginMFARequest struct {
// mfa token
// Required: true
MfaToken *string `json:"mfa_token"`
// otp
// Required: true
Otp *string `json:"otp"`
// username
// Required: true
Username *string `json:"username"`
}
// Validate validates this subnet login m f a request
func (m *SubnetLoginMFARequest) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateMfaToken(formats); err != nil {
res = append(res, err)
}
if err := m.validateOtp(formats); err != nil {
res = append(res, err)
}
if err := m.validateUsername(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *SubnetLoginMFARequest) validateMfaToken(formats strfmt.Registry) error {
if err := validate.Required("mfa_token", "body", m.MfaToken); err != nil {
return err
}
return nil
}
func (m *SubnetLoginMFARequest) validateOtp(formats strfmt.Registry) error {
if err := validate.Required("otp", "body", m.Otp); err != nil {
return err
}
return nil
}
func (m *SubnetLoginMFARequest) validateUsername(formats strfmt.Registry) error {
if err := validate.Required("username", "body", m.Username); err != nil {
return err
}
return nil
}
// ContextValidate validates this subnet login m f a request based on context it is used
func (m *SubnetLoginMFARequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *SubnetLoginMFARequest) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *SubnetLoginMFARequest) UnmarshalBinary(b []byte) error {
var res SubnetLoginMFARequest
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -1,73 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// SubnetLoginRequest subnet login request
//
// swagger:model subnetLoginRequest
type SubnetLoginRequest struct {
// api key
APIKey string `json:"apiKey,omitempty"`
// password
Password string `json:"password,omitempty"`
// username
Username string `json:"username,omitempty"`
}
// Validate validates this subnet login request
func (m *SubnetLoginRequest) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this subnet login request based on context it is used
func (m *SubnetLoginRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *SubnetLoginRequest) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *SubnetLoginRequest) UnmarshalBinary(b []byte) error {
var res SubnetLoginRequest
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -1,147 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// SubnetLoginResponse subnet login response
//
// swagger:model subnetLoginResponse
type SubnetLoginResponse struct {
// access token
AccessToken string `json:"access_token,omitempty"`
// mfa token
MfaToken string `json:"mfa_token,omitempty"`
// organizations
Organizations []*SubnetOrganization `json:"organizations"`
// registered
Registered bool `json:"registered,omitempty"`
}
// Validate validates this subnet login response
func (m *SubnetLoginResponse) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateOrganizations(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *SubnetLoginResponse) validateOrganizations(formats strfmt.Registry) error {
if swag.IsZero(m.Organizations) { // not required
return nil
}
for i := 0; i < len(m.Organizations); i++ {
if swag.IsZero(m.Organizations[i]) { // not required
continue
}
if m.Organizations[i] != nil {
if err := m.Organizations[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("organizations" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("organizations" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// ContextValidate validate this subnet login response based on the context it is used
func (m *SubnetLoginResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateOrganizations(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *SubnetLoginResponse) contextValidateOrganizations(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Organizations); i++ {
if m.Organizations[i] != nil {
if swag.IsZero(m.Organizations[i]) { // not required
return nil
}
if err := m.Organizations[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("organizations" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("organizations" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// MarshalBinary interface implementation
func (m *SubnetLoginResponse) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *SubnetLoginResponse) UnmarshalBinary(b []byte) error {
var res SubnetLoginResponse
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -1,82 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// SubnetOrganization subnet organization
//
// swagger:model subnetOrganization
type SubnetOrganization struct {
// account Id
AccountID int64 `json:"accountId,omitempty"`
// company
Company string `json:"company,omitempty"`
// is account owner
IsAccountOwner bool `json:"isAccountOwner,omitempty"`
// short name
ShortName string `json:"shortName,omitempty"`
// subscription status
SubscriptionStatus string `json:"subscriptionStatus,omitempty"`
// user Id
UserID int64 `json:"userId,omitempty"`
}
// Validate validates this subnet organization
func (m *SubnetOrganization) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this subnet organization based on context it is used
func (m *SubnetOrganization) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *SubnetOrganization) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *SubnetOrganization) UnmarshalBinary(b []byte) error {
var res SubnetOrganization
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -1,67 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// SubnetRegTokenResponse subnet reg token response
//
// swagger:model SubnetRegTokenResponse
type SubnetRegTokenResponse struct {
// reg token
RegToken string `json:"regToken,omitempty"`
}
// Validate validates this subnet reg token response
func (m *SubnetRegTokenResponse) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this subnet reg token response based on context it is used
func (m *SubnetRegTokenResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *SubnetRegTokenResponse) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *SubnetRegTokenResponse) UnmarshalBinary(b []byte) error {
var res SubnetRegTokenResponse
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -1,105 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// 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 models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// SubnetRegisterRequest subnet register request
//
// swagger:model subnetRegisterRequest
type SubnetRegisterRequest struct {
// account id
// Required: true
AccountID *string `json:"account_id"`
// token
// Required: true
Token *string `json:"token"`
}
// Validate validates this subnet register request
func (m *SubnetRegisterRequest) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateAccountID(formats); err != nil {
res = append(res, err)
}
if err := m.validateToken(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *SubnetRegisterRequest) validateAccountID(formats strfmt.Registry) error {
if err := validate.Required("account_id", "body", m.AccountID); err != nil {
return err
}
return nil
}
func (m *SubnetRegisterRequest) validateToken(formats strfmt.Registry) error {
if err := validate.Required("token", "body", m.Token); err != nil {
return err
}
return nil
}
// ContextValidate validates this subnet register request based on context it is used
func (m *SubnetRegisterRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *SubnetRegisterRequest) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *SubnetRegisterRequest) UnmarshalBinary(b []byte) error {
var res SubnetRegisterRequest
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -53,7 +53,7 @@ type Tier struct {
Status bool `json:"status,omitempty"`
// type
// Enum: ["s3","gcs","azure","minio","unsupported"]
// Enum: [s3 gcs azure minio unsupported]
Type string `json:"type,omitempty"`
}

View File

@@ -72,7 +72,7 @@ type UpdateBucketLifecycle struct {
// ILM Rule type (Expiry or transition)
// Required: true
// Enum: ["expiry","transition"]
// Enum: [expiry transition]
Type *string `json:"type"`
}

View File

@@ -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
}

View File

@@ -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)
}
})
}
}

View File

@@ -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"
)

View File

@@ -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
}

View File

@@ -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,
},
}
}

View File

@@ -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)
}
})
}
}

View File

@@ -2287,160 +2287,6 @@ paths:
$ref: "#/definitions/ApiError"
tags:
- Service
/profiling/start:
post:
summary: Start recording profile data
operationId: ProfilingStart
parameters:
- name: body
in: body
required: true
schema:
$ref: "#/definitions/profilingStartRequest"
responses:
201:
description: A successful response.
schema:
$ref: "#/definitions/startProfilingList"
default:
description: Generic error response.
schema:
$ref: "#/definitions/ApiError"
tags:
- Profile
/profiling/stop:
post:
summary: Stop and download profile data
operationId: ProfilingStop
produces:
- application/zip
responses:
201:
description: A successful response.
schema:
type: file
default:
description: Generic error response.
schema:
$ref: "#/definitions/ApiError"
tags:
- Profile
/subnet/registration-token:
get:
summary: SUBNET registraton token
operationId: SubnetRegToken
responses:
200:
description: A successful response.
schema:
$ref: "#/definitions/SubnetRegTokenResponse"
default:
description: Generic error response.
schema:
$ref: "#/definitions/ApiError"
tags:
- Subnet
/subnet/info:
get:
summary: Subnet info
operationId: SubnetInfo
responses:
200:
description: A successful response.
schema:
$ref: "#/definitions/license"
default:
description: Generic error response.
schema:
$ref: "#/definitions/ApiError"
tags:
- Subnet
/subnet/apikey:
get:
summary: Subnet api key
operationId: SubnetApiKey
parameters:
- name: token
in: query
required: true
type: string
responses:
200:
description: A successful response.
schema:
$ref: "#/definitions/apiKey"
default:
description: Generic error response.
schema:
$ref: "#/definitions/ApiError"
tags:
- Subnet
/subnet/register:
post:
summary: Register cluster with Subnet
operationId: SubnetRegister
parameters:
- name: body
in: body
required: true
schema:
$ref: "#/definitions/subnetRegisterRequest"
responses:
200:
description: A successful response.
# schema:
# $ref: "#/definitions/subnetRegisterResponse"
default:
description: Generic error response.
schema:
$ref: "#/definitions/ApiError"
tags:
- Subnet
/subnet/login:
post:
summary: Login to SUBNET
operationId: SubnetLogin
parameters:
- name: body
in: body
required: true
schema:
$ref: "#/definitions/subnetLoginRequest"
responses:
200:
description: A successful response.
schema:
$ref: "#/definitions/subnetLoginResponse"
default:
description: Generic error response.
schema:
$ref: "#/definitions/ApiError"
tags:
- Subnet
/subnet/login/mfa:
post:
summary: Login to SUBNET using mfa
operationId: SubnetLoginMFA
parameters:
- name: body
in: body
required: true
schema:
$ref: "#/definitions/subnetLoginMFARequest"
responses:
200:
description: A successful response.
schema:
$ref: "#/definitions/subnetLoginResponse"
default:
description: Generic error response.
schema:
$ref: "#/definitions/ApiError"
tags:
- Subnet
/admin/info:
get:
@@ -3280,41 +3126,6 @@ paths:
tags:
- release
/support/callhome:
get:
summary: Get Callhome current status
operationId: GetCallHomeOptionValue
responses:
200:
description: A successful response.
schema:
$ref: "#/definitions/callHomeGetResponse"
default:
description: Generic error response.
schema:
$ref: "#/definitions/ApiError"
tags:
- Support
put:
summary: Sets callhome status
operationId: SetCallHomeStatus
parameters:
- name: body
in: body
required: true
schema:
$ref: "#/definitions/callHomeSetStatus"
responses:
204:
description: A successful response.
default:
description: Generic error response.
schema:
$ref: "#/definitions/ApiError"
tags:
- Support
/download-shared-object/{url}:
get:
summary: Downloads an object from a presigned url
@@ -5455,77 +5266,6 @@ definitions:
type: object
additionalProperties: true
subnetLoginResponse:
type: object
properties:
access_token:
type: string
organizations:
type: array
items:
$ref: "#/definitions/subnetOrganization"
mfa_token:
type: string
registered:
type: boolean
subnetLoginRequest:
type: object
properties:
username:
type: string
password:
type: string
apiKey:
type: string
subnetLoginMFARequest:
type: object
required:
- username
- otp
- mfa_token
properties:
username:
type: string
otp:
type: string
mfa_token:
type: string
subnetRegisterRequest:
type: object
required:
- token
- account_id
properties:
token:
type: string
account_id:
type: string
SubnetRegTokenResponse:
type: object
properties:
regToken:
type: string
subnetOrganization:
type: object
properties:
userId:
type: integer
accountId:
type: integer
subscriptionStatus:
type: string
isAccountOwner:
type: boolean
company:
type: string
shortName:
type: string
permissionResource:
type: object
properties:

View File

@@ -22,7 +22,6 @@
"react-pdf": "^9.1.0",
"react-redux": "^8.1.3",
"react-router-dom": "6.25.1",
"react-use-websocket": "^4.8.1",
"react-virtualized": "^9.22.5",
"react-window": "^1.8.10",
"react-window-infinite-loader": "^1.0.9",

View File

@@ -1236,43 +1236,6 @@ export interface Metadata {
objectMetadata?: Record<string, any>;
}
export interface SubnetLoginResponse {
access_token?: string;
organizations?: SubnetOrganization[];
mfa_token?: string;
registered?: boolean;
}
export interface SubnetLoginRequest {
username?: string;
password?: string;
apiKey?: string;
}
export interface SubnetLoginMFARequest {
username: string;
otp: string;
mfa_token: string;
}
export interface SubnetRegisterRequest {
token: string;
account_id: string;
}
export interface SubnetRegTokenResponse {
regToken?: string;
}
export interface SubnetOrganization {
userId?: number;
accountId?: number;
subscriptionStatus?: string;
isAccountOwner?: boolean;
company?: string;
shortName?: string;
}
export interface PermissionResource {
resource?: string;
conditionOperator?: string;
@@ -3997,164 +3960,6 @@ export class Api<
...params,
}),
};
profiling = {
/**
* No description
*
* @tags Profile
* @name ProfilingStart
* @summary Start recording profile data
* @request POST:/profiling/start
* @secure
*/
profilingStart: (body: ProfilingStartRequest, params: RequestParams = {}) =>
this.request<StartProfilingList, ApiError>({
path: `/profiling/start`,
method: "POST",
body: body,
secure: true,
type: ContentType.Json,
format: "json",
...params,
}),
/**
* No description
*
* @tags Profile
* @name ProfilingStop
* @summary Stop and download profile data
* @request POST:/profiling/stop
* @secure
*/
profilingStop: (params: RequestParams = {}) =>
this.request<File, ApiError>({
path: `/profiling/stop`,
method: "POST",
secure: true,
...params,
}),
};
subnet = {
/**
* No description
*
* @tags Subnet
* @name SubnetRegToken
* @summary SUBNET registraton token
* @request GET:/subnet/registration-token
* @secure
*/
subnetRegToken: (params: RequestParams = {}) =>
this.request<SubnetRegTokenResponse, ApiError>({
path: `/subnet/registration-token`,
method: "GET",
secure: true,
format: "json",
...params,
}),
/**
* No description
*
* @tags Subnet
* @name SubnetInfo
* @summary Subnet info
* @request GET:/subnet/info
* @secure
*/
subnetInfo: (params: RequestParams = {}) =>
this.request<License, ApiError>({
path: `/subnet/info`,
method: "GET",
secure: true,
format: "json",
...params,
}),
/**
* No description
*
* @tags Subnet
* @name SubnetApiKey
* @summary Subnet api key
* @request GET:/subnet/apikey
* @secure
*/
subnetApiKey: (
query: {
token: string;
},
params: RequestParams = {},
) =>
this.request<ApiKey, ApiError>({
path: `/subnet/apikey`,
method: "GET",
query: query,
secure: true,
format: "json",
...params,
}),
/**
* No description
*
* @tags Subnet
* @name SubnetRegister
* @summary Register cluster with Subnet
* @request POST:/subnet/register
* @secure
*/
subnetRegister: (body: SubnetRegisterRequest, params: RequestParams = {}) =>
this.request<void, ApiError>({
path: `/subnet/register`,
method: "POST",
body: body,
secure: true,
type: ContentType.Json,
...params,
}),
/**
* No description
*
* @tags Subnet
* @name SubnetLogin
* @summary Login to SUBNET
* @request POST:/subnet/login
* @secure
*/
subnetLogin: (body: SubnetLoginRequest, params: RequestParams = {}) =>
this.request<SubnetLoginResponse, ApiError>({
path: `/subnet/login`,
method: "POST",
body: body,
secure: true,
type: ContentType.Json,
format: "json",
...params,
}),
/**
* No description
*
* @tags Subnet
* @name SubnetLoginMfa
* @summary Login to SUBNET using mfa
* @request POST:/subnet/login/mfa
* @secure
*/
subnetLoginMfa: (body: SubnetLoginMFARequest, params: RequestParams = {}) =>
this.request<SubnetLoginResponse, ApiError>({
path: `/subnet/login/mfa`,
method: "POST",
body: body,
secure: true,
type: ContentType.Json,
format: "json",
...params,
}),
};
admin = {
/**
* No description
@@ -4975,44 +4780,6 @@ export class Api<
...params,
}),
};
support = {
/**
* No description
*
* @tags Support
* @name GetCallHomeOptionValue
* @summary Get Callhome current status
* @request GET:/support/callhome
* @secure
*/
getCallHomeOptionValue: (params: RequestParams = {}) =>
this.request<CallHomeGetResponse, ApiError>({
path: `/support/callhome`,
method: "GET",
secure: true,
format: "json",
...params,
}),
/**
* No description
*
* @tags Support
* @name SetCallHomeStatus
* @summary Sets callhome status
* @request PUT:/support/callhome
* @secure
*/
setCallHomeStatus: (body: CallHomeSetStatus, params: RequestParams = {}) =>
this.request<void, ApiError>({
path: `/support/callhome`,
method: "PUT",
body: body,
secure: true,
type: ContentType.Json,
...params,
}),
};
downloadSharedObject = {
/**
* No description

View File

@@ -183,15 +183,6 @@ export const IAM_PAGES = {
KMS_KEYS_ADD: "/kms/add-key/",
KMS_KEYS_IMPORT: "/kms/import-key/",
/* Support */
TOOLS: "/support",
REGISTER_SUPPORT: "/support/register",
TOOLS_DIAGNOSTICS: "/support/diagnostics",
TOOLS_SPEEDTEST: "/support/speedtest",
CALL_HOME: "/support/call-home",
PROFILE: "/support/profile",
SUPPORT_INSPECT: "/support/inspect",
/** License **/
LICENSE: "/license",
/* Settings **/
@@ -389,15 +380,6 @@ export const IAM_PAGES_PERMISSIONS = {
IAM_SCOPES.ADMIN_SET_TIER, // display "add tier" button / shows add service tier page
IAM_SCOPES.ADMIN_LIST_TIERS, // display tiers list
],
[IAM_PAGES.TOOLS]: [
IAM_SCOPES.S3_LISTEN_NOTIFICATIONS, // displays watch notifications
IAM_SCOPES.S3_LISTEN_BUCKET_NOTIFICATIONS, // display watch notifications
IAM_SCOPES.ADMIN_GET_CONSOLE_LOG, // display minio console logs
IAM_SCOPES.ADMIN_SERVER_TRACE, // display minio trace
IAM_SCOPES.ADMIN_HEAL, // display heal
IAM_SCOPES.ADMIN_HEALTH_INFO, // display diagnostics / display speedtest / display audit log
IAM_SCOPES.ADMIN_SERVER_INFO, // display diagnostics
],
[IAM_PAGES.TOOLS_LOGS]: [IAM_SCOPES.ADMIN_GET_CONSOLE_LOG],
[IAM_PAGES.TOOLS_AUDITLOGS]: [IAM_SCOPES.ADMIN_HEALTH_INFO],
[IAM_PAGES.TOOLS_WATCH]: [
@@ -405,18 +387,6 @@ export const IAM_PAGES_PERMISSIONS = {
IAM_SCOPES.S3_LISTEN_BUCKET_NOTIFICATIONS, // display watch notifications
],
[IAM_PAGES.TOOLS_TRACE]: [IAM_SCOPES.ADMIN_SERVER_TRACE],
[IAM_PAGES.TOOLS_DIAGNOSTICS]: [
IAM_SCOPES.ADMIN_HEALTH_INFO,
IAM_SCOPES.ADMIN_SERVER_INFO,
],
[IAM_PAGES.TOOLS_SPEEDTEST]: [IAM_SCOPES.ADMIN_HEALTH_INFO],
[IAM_PAGES.REGISTER_SUPPORT]: [
IAM_SCOPES.ADMIN_SERVER_INFO,
IAM_SCOPES.ADMIN_CONFIG_UPDATE,
],
[IAM_PAGES.CALL_HOME]: [IAM_SCOPES.ADMIN_HEALTH_INFO],
[IAM_PAGES.PROFILE]: [IAM_SCOPES.ADMIN_HEALTH_INFO],
[IAM_PAGES.SUPPORT_INSPECT]: [IAM_SCOPES.ADMIN_HEALTH_INFO],
[IAM_PAGES.LICENSE]: [
IAM_SCOPES.ADMIN_SERVER_INFO,
IAM_SCOPES.ADMIN_CONFIG_UPDATE,

View File

@@ -64,15 +64,6 @@ export const clearSession = () => {
deleteCookie("idp-refresh-token");
};
// timeFromDate gets time string from date input
export const timeFromDate = (d: Date) => {
let h = d.getHours() < 10 ? `0${d.getHours()}` : `${d.getHours()}`;
let m = d.getMinutes() < 10 ? `0${d.getMinutes()}` : `${d.getMinutes()}`;
let s = d.getSeconds() < 10 ? `0${d.getSeconds()}` : `${d.getSeconds()}`;
return `${h}:${m}:${s}:${d.getMilliseconds()}`;
};
// units to be used in a dropdown
export const k8sScalarUnitsExcluding = (exclude?: string[]) => {
return k8sUnits

View File

@@ -17,7 +17,6 @@
import React, { useEffect, useState } from "react";
import get from "lodash/get";
import { AddIcon, Box, Loader, Tag } from "mds";
import { Bucket } from "../../../Watch/types";
import { ErrorResponseHandler } from "../../../../../common/types";
import { IAM_SCOPES } from "../../../../../common/SecureComponent/permissions";
import { SecureComponent } from "../../../../../common/SecureComponent";
@@ -37,6 +36,15 @@ type BucketTagProps = {
bucketName: string;
};
interface Details {
tags: object;
}
interface Bucket {
details: Details;
name: string;
}
const BucketTags = ({ bucketName }: BucketTagProps) => {
const dispatch = useAppDispatch();

View File

@@ -1,140 +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/>.
import React, { Fragment, useEffect, useState } from "react";
import { DrivesIcon, Loader, SectionTitle, VersionIcon, Grid } from "mds";
import { api } from "api";
import { ServerProperties } from "api/consoleApi";
interface ITestWrapper {
title: any;
children: any;
}
const TestWrapper = ({ title, children }: ITestWrapper) => {
const [version, setVersion] = useState<string>("N/A");
const [totalNodes, setTotalNodes] = useState<number>(0);
const [totalDrives, setTotalDrives] = useState<number>(0);
const [loading, setLoading] = useState<boolean>(true);
useEffect(() => {
if (loading) {
api.admin
.adminInfo({
defaultOnly: true,
})
.then((res) => {
const totalServers = res.data.servers?.length;
setTotalNodes(totalServers || 0);
if (res.data.servers && res.data.servers.length > 0) {
setVersion(res.data.servers[0].version || "N/A");
const totalServers = res.data.servers.reduce(
(prevTotal: number, currentElement: ServerProperties) => {
let c = currentElement.drives
? currentElement.drives.length
: 0;
return prevTotal + c;
},
0,
);
setTotalDrives(totalServers);
}
setLoading(false);
})
.catch(() => {
setLoading(false);
});
}
}, [loading]);
return (
<Grid item xs={12}>
<SectionTitle separator>{title}</SectionTitle>
<Grid item xs={12}>
<Grid
item
xs={12}
sx={{
padding: 0,
marginBottom: 25,
}}
>
<Grid
container
sx={{
padding: 25,
}}
>
{!loading ? (
<Fragment>
<Grid
item
xs={12}
md={4}
sx={{
fontSize: 18,
display: "flex",
alignItems: "center",
"& svg": {
marginRight: 10,
},
}}
>
<DrivesIcon /> <strong>{totalNodes}</strong>
&nbsp;nodes,&nbsp;
<strong>{totalDrives}</strong>&nbsp; drives
</Grid>
<Grid
item
xs={12}
md={4}
sx={{
fontSize: 12,
justifyContent: "center",
alignSelf: "center",
alignItems: "center",
display: "flex",
}}
>
<span
style={{
marginRight: 20,
}}
>
<VersionIcon />
</span>{" "}
MinIO VERSION&nbsp;<strong>{version}</strong>
</Grid>
</Fragment>
) : (
<Fragment>
<Grid item xs={12} sx={{ textAlign: "center" }}>
<Loader style={{ width: 25, height: 25 }} />
</Grid>
</Fragment>
)}
</Grid>
</Grid>
{children}
</Grid>
</Grid>
);
};
export default TestWrapper;

View File

@@ -49,10 +49,6 @@ import MenuWrapper from "./Menu/MenuWrapper";
import LoadingComponent from "../../common/LoadingComponent";
import ComponentsScreen from "./Common/ComponentsScreen";
const Trace = React.lazy(() => import("./Trace/Trace"));
const Watch = React.lazy(() => import("./Watch/Watch"));
const HealthInfo = React.lazy(() => import("./HealthInfo/HealthInfo"));
const EventDestinations = React.lazy(
() => import("./EventDestinations/EventDestinations"),
);
@@ -79,11 +75,8 @@ const LogsSearchMain = React.lazy(
);
const GroupsDetails = React.lazy(() => import("./Groups/GroupsDetails"));
const Tools = React.lazy(() => import("./Tools/Tools"));
const IconsScreen = React.lazy(() => import("./Common/IconsScreen"));
const Speedtest = React.lazy(() => import("./Speedtest/Speedtest"));
const ObjectManager = React.lazy(
() => import("./Common/ObjectManager/ObjectManager"),
);
@@ -278,15 +271,6 @@ const Console = () => {
);
},
},
{
component: Watch,
path: IAM_PAGES.TOOLS_WATCH,
},
{
component: Speedtest,
path: IAM_PAGES.TOOLS_SPEEDTEST,
},
{
component: Users,
path: IAM_PAGES.USERS,
@@ -336,14 +320,6 @@ const Console = () => {
component: IDPOpenIDConfigurationDetails,
path: IAM_PAGES.IDP_OPENID_CONFIGURATIONS_VIEW,
},
{
component: Trace,
path: IAM_PAGES.TOOLS_TRACE,
},
{
component: HealthInfo,
path: IAM_PAGES.TOOLS_DIAGNOSTICS,
},
{
component: ErrorLogs,
path: IAM_PAGES.TOOLS_LOGS,
@@ -352,10 +328,6 @@ const Console = () => {
component: LogsSearchMain,
path: IAM_PAGES.TOOLS_AUDITLOGS,
},
{
component: Tools,
path: IAM_PAGES.TOOLS,
},
{
component: ConfigurationOptions,
path: IAM_PAGES.SETTINGS,

View File

@@ -1,342 +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/>.
import React, { Fragment, useEffect, useState } from "react";
import { useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import { Box, Button, Grid, HelpBox, InfoIcon, Loader, PageLayout } from "mds";
import {
DiagStatError,
DiagStatInProgress,
DiagStatSuccess,
HealthInfoMessage,
ReportMessage,
} from "./types";
import { AppState, useAppDispatch } from "../../../store";
import {
WSCloseAbnormalClosure,
WSCloseInternalServerErr,
WSClosePolicyViolation,
wsProtocol,
} from "../../../utils/wsUtils";
import { setHelpName, setServerDiagStat } from "../../../systemSlice";
import {
healthInfoMessageReceived,
healthInfoResetMessage,
} from "./healthInfoSlice";
import { registeredCluster } from "../../../config";
import TestWrapper from "../Common/TestWrapper/TestWrapper";
import RegisterCluster from "../Support/RegisterCluster";
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";
import HelpMenu from "../HelpMenu";
const HealthInfo = () => {
const dispatch = useAppDispatch();
const navigate = useNavigate();
const message = useSelector((state: AppState) => state.healthInfo.message);
const serverDiagnosticStatus = useSelector(
(state: AppState) => state.system.serverDiagnosticStatus,
);
const [startDiagnostic, setStartDiagnostic] = useState(false);
const [downloadDisabled, setDownloadDisabled] = useState(true);
const [localMessage, setMessage] = useState<string>("");
const [buttonStartText, setButtonStartText] = useState<string>(
"Start Health Report",
);
const [title, setTitle] = useState<string>("Health Report");
const [diagFileContent, setDiagFileContent] = useState<string>("");
const [subnetResponse, setSubnetResponse] = useState<string>("");
const clusterRegistered = registeredCluster();
const download = () => {
let element = document.createElement("a");
element.setAttribute(
"href",
`data:application/gzip;base64,${diagFileContent}`,
);
element.setAttribute("download", "diagnostic.json.gz");
element.style.display = "none";
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
};
useEffect(() => {
if (serverDiagnosticStatus === DiagStatInProgress) {
setTitle("Health Report in progress...");
setMessage(
"Health Report started. Please do not refresh page during diagnosis.",
);
return;
}
if (serverDiagnosticStatus === DiagStatSuccess) {
setTitle("Health Report complete");
setMessage("Health Report file is ready to be downloaded.");
setButtonStartText("Start Health Report");
return;
}
if (serverDiagnosticStatus === DiagStatError) {
setTitle("Error");
setMessage("An error occurred while getting the Health Report file.");
setButtonStartText("Retry Health Report");
return;
}
}, [serverDiagnosticStatus, startDiagnostic]);
useEffect(() => {
if (
serverDiagnosticStatus === DiagStatSuccess &&
message !== ({} as HealthInfoMessage)
) {
// Allow download of diagnostics file only when
// it succeded fetching all the results and info is not empty.
setDownloadDisabled(false);
}
if (serverDiagnosticStatus === DiagStatInProgress) {
// Disable Start Health Report and Disable Download buttons
// if a Diagnosis is in progress.
setDownloadDisabled(true);
}
setStartDiagnostic(false);
}, [serverDiagnosticStatus, message]);
useEffect(() => {
if (startDiagnostic) {
dispatch(healthInfoResetMessage());
setDiagFileContent("");
const url = new URL(window.location.toString());
const isDev = process.env.NODE_ENV === "development";
const port = isDev ? "9090" : url.port;
const wsProt = wsProtocol(url.protocol);
// check if we are using base path, if not this always is `/`
const baseLocation = new URL(document.baseURI);
const baseUrl = baseLocation.pathname;
const socket = new WebSocket(
`${wsProt}://${url.hostname}:${port}${baseUrl}ws/health-info?deadline=1h`,
);
let interval: any | null = null;
if (socket !== null) {
socket.onopen = () => {
console.log("WebSocket Client Connected");
socket.send("ok");
interval = setInterval(() => {
socket.send("ok");
}, 10 * 1000);
setMessage(
"Health Report started. Please do not refresh page during diagnosis.",
);
dispatch(setServerDiagStat(DiagStatInProgress));
};
socket.onmessage = (message: MessageEvent) => {
let m: ReportMessage = JSON.parse(message.data.toString());
if (m.serverHealthInfo) {
dispatch(healthInfoMessageReceived(m.serverHealthInfo));
}
if (m.encoded !== "") {
setDiagFileContent(m.encoded);
}
if (m.subnetResponse) {
setSubnetResponse(m.subnetResponse);
}
};
socket.onerror = (error) => {
console.error("error closing websocket:", error);
socket.close(1000);
clearInterval(interval);
dispatch(setServerDiagStat(DiagStatError));
};
socket.onclose = (event: CloseEvent) => {
clearInterval(interval);
if (
event.code === WSCloseInternalServerErr ||
event.code === WSClosePolicyViolation ||
event.code === WSCloseAbnormalClosure
) {
// handle close with error
console.log("connection closed by server with code:", event.code);
setMessage(
"An error occurred while getting the Health Report file.",
);
dispatch(setServerDiagStat(DiagStatError));
} else {
console.log("connection closed by server");
setMessage("Health Report file is ready to be downloaded.");
dispatch(setServerDiagStat(DiagStatSuccess));
}
};
}
} else {
// reset start status
setStartDiagnostic(false);
}
}, [startDiagnostic, dispatch]);
const startDiagnosticAction = () => {
if (!clusterRegistered) {
navigate("/support/register");
return;
}
setStartDiagnostic(true);
};
useEffect(() => {
dispatch(setHelpName("health_info"));
}, [dispatch]);
return (
<Fragment>
<PageHeaderWrapper label="Health" actions={<HelpMenu />} />
<PageLayout>
{!clusterRegistered && <RegisterCluster compactMode />}
<Box withBorders>
<TestWrapper title={title}>
<Grid
container
sx={{
justifyContent: "flex-start",
gap: 20,
}}
>
<Grid
key="start-download"
item
xs={12}
sx={{
textAlign: "center",
marginBottom: 25,
}}
>
<h2>{localMessage}</h2>
<Box
sx={{
textAlign: "center",
marginBottom: 25,
}}
>
{" "}
{subnetResponse !== "" &&
!subnetResponse.toLowerCase().includes("error") && (
<Grid item xs={12}>
<strong>
Health report uploaded to SUBNET successfully!
</strong>
&nbsp;{" "}
<strong>
See the results on your{" "}
<a href={subnetResponse}>SUBNET Dashboard</a>{" "}
</strong>
</Grid>
)}
{(subnetResponse === "" ||
subnetResponse.toLowerCase().includes("error")) &&
serverDiagnosticStatus === DiagStatSuccess && (
<Grid item xs={12}>
<strong>
Something went wrong uploading your Health report to
SUBNET.
</strong>
&nbsp;{" "}
<strong>
Log into your{" "}
<a href="https://subnet.min.io">SUBNET Account</a> to
manually upload your Health report.
</strong>
</Grid>
)}
</Box>
{serverDiagnosticStatus === DiagStatInProgress ? (
<Box
sx={{
paddingTop: 8,
paddingLeft: 40,
}}
>
<Loader style={{ width: 25, height: 25 }} />
</Box>
) : (
<Fragment>
<Box
sx={{
display: "flex",
gap: 10,
alignItems: "center",
justifyContent: "center",
}}
>
<Box>
{serverDiagnosticStatus !== DiagStatError &&
!downloadDisabled && (
<Button
id={"download"}
type="submit"
variant="callAction"
onClick={() => download()}
disabled={downloadDisabled}
label={"Download"}
/>
)}
</Box>
<Box>
<Button
id="start-new-diagnostic"
type="submit"
variant={
!clusterRegistered ? "regular" : "callAction"
}
disabled={startDiagnostic || !clusterRegistered}
onClick={startDiagnosticAction}
label={buttonStartText}
/>
</Box>
</Box>
</Fragment>
)}
</Grid>
</Grid>
</TestWrapper>
</Box>
{!startDiagnostic && clusterRegistered && (
<Fragment>
<br />
<HelpBox
title={
"Cluster Health Report will be uploaded to SUBNET, and is viewable from your SUBNET Diagnostics dashboard."
}
iconComponent={<InfoIcon />}
help={
"If the Health report cannot be generated at this time, please wait a moment and try again."
}
/>
</Fragment>
)}
</PageLayout>
</Fragment>
);
};
export default HealthInfo;

View File

@@ -1,46 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { HealthInfoMessage } from "./types";
interface HealthInfoState {
message: HealthInfoMessage;
}
const initialState: HealthInfoState = {
message: {} as HealthInfoMessage,
};
const healthInfoSlice = createSlice({
name: "trace",
initialState,
reducers: {
healthInfoMessageReceived: (
state,
action: PayloadAction<HealthInfoMessage>,
) => {
state.message = action.payload;
},
healthInfoResetMessage: (state) => {
state.message = {} as HealthInfoMessage;
},
},
});
export const { healthInfoMessageReceived, healthInfoResetMessage } =
healthInfoSlice.actions;
export default healthInfoSlice.reducer;

View File

@@ -1,528 +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/>.
export const DiagStatError = "error";
export const DiagStatSuccess = "success";
export const DiagStatInProgress = "inProgress";
export interface HealthInfoMessage {
timestamp: string;
error: string;
perf: perfInfo;
minio: minioHealthInfo;
sys: sysHealthInfo;
}
export interface ReportMessage {
encoded: string;
serverHealthInfo: HealthInfoMessage;
subnetResponse: string;
}
interface perfInfo {
drives: serverDrivesInfo[];
net: serverNetHealthInfo[];
net_parallel: serverNetHealthInfo;
error: string;
}
interface serverDrivesInfo {
addr: string;
serial: drivePerfInfo[];
parallel: drivePerfInfo[];
error: string;
}
interface drivePerfInfo {
endpoint: string;
latency: diskLatency;
throughput: diskThroughput;
error: string;
}
interface diskLatency {
avg_secs: number;
percentile50_secs: number;
percentile90_secs: number;
percentile99_secs: number;
min_secs: number;
max_secs: number;
}
interface diskThroughput {
avg_bytes_per_sec: number;
percentile50_bytes_per_sec: number;
percentile90_bytes_per_sec: number;
percentile99_bytes_per_sec: number;
min_bytes_per_sec: number;
max_bytes_per_sec: number;
}
interface serverNetHealthInfo {
addr: string;
net: netPerfInfo[];
error: string;
}
interface netPerfInfo {
remote: string;
latency: netLatency;
throughput: netThroughput;
error: string;
}
interface netLatency {
avg_secs: number;
percentile50_secs: number;
percentile90_secs: number;
percentile99_secs: number;
min_secs: number;
max_secs: number;
}
interface netThroughput {
avg_bytes_per_sec: number;
percentile50_bytes_per_sec: number;
percentile90_bytes_per_sec: number;
percentile99_bytes_per_sec: number;
min_bytes_per_sec: number;
max_bytes_per_sec: number;
}
interface minioHealthInfo {
info: infoMessage;
config: any;
error: string;
}
interface infoMessage {
mode: string;
domain: string[];
region: string;
sqsARN: string[];
deploymentID: string;
buckets: buckets;
objects: objects;
usage: usage;
services: services;
backend: any;
servers: serverProperties[];
}
interface buckets {
count: number;
}
interface objects {
count: number;
}
interface usage {
size: number;
}
interface services {
vault: vault;
ldap: ldap;
logger: Map<string, status[]>[];
audit: Map<string, status[]>[];
notifications: Map<string, Map<string, status[]>[]>;
}
interface vault {
status: string;
encrypt: string;
decrypt: string;
}
interface ldap {
status: string;
}
interface status {
status: string;
}
interface serverProperties {
state: string;
endpoint: string;
uptime: number;
version: string;
commitID: string;
network: Map<string, string>;
drives: disk[];
}
interface disk {
endpoint: string;
rootDisk: boolean;
path: string;
healing: boolean;
state: string;
uuid: string;
model: string;
totalspace: number;
usedspace: number;
availspace: number;
readthroughput: number;
writethroughput: number;
readlatency: number;
writelatency: number;
utilization: number;
}
interface sysHealthInfo {
cpus: serverCpuInfo[];
drives: serverDiskHwInfo[];
osinfos: serverOsInfo[];
meminfos: serverMemInfo[];
procinfos: serverProcInfo[];
error: string;
}
interface serverCpuInfo {
addr: string;
cpu: cpuInfoStat[];
time: cpuTimeStat[];
error: string;
}
interface cpuInfoStat {
cpu: number;
vendorId: string;
family: string;
model: string;
stepping: number;
physicalId: string;
coreId: string;
cores: number;
modelName: string;
mhz: number;
cacheSize: number;
flags: string[];
microcode: string;
}
interface cpuTimeStat {
cpu: string;
user: number;
system: number;
idle: number;
nice: number;
iowait: number;
irq: number;
softirq: number;
steal: number;
guest: number;
guestNice: number;
}
interface serverDiskHwInfo {
addr: string;
usages: diskUsageStat[];
partitions: partitionStat[];
counters: Map<string, diskIOCountersStat>;
error: string;
}
interface diskUsageStat {
path: string;
fstype: string;
total: number;
free: number;
used: number;
usedPercent: number;
inodesTotal: number;
inodesUsed: number;
inodesFree: number;
inodesUsedPercent: number;
}
interface partitionStat {
device: string;
mountpoint: string;
fstype: string;
opts: string;
smartInfo: smartInfo;
}
interface smartInfo {
device: string;
scsi: scsiInfo;
nvme: nvmeInfo;
ata: ataInfo;
error: string;
}
interface scsiInfo {
scsiCapacityBytes: number;
scsiModeSenseBuf: string;
scsirespLen: number;
scsiBdLen: number;
scsiOffset: number;
sciRpm: number;
}
interface nvmeInfo {
serialNum: string;
vendorId: string;
firmwareVersion: string;
modelNum: string;
spareAvailable: string;
spareThreshold: string;
temperature: string;
criticalWarning: string;
maxDataTransferPages: number;
controllerBusyTime: number;
powerOnHours: number;
powerCycles: number;
unsafeShutdowns: number;
mediaAndDataIntgerityErrors: number;
dataUnitsReadBytes: number;
dataUnitsWrittenBytes: number;
hostReadCommands: number;
hostWriteCommands: number;
}
interface ataInfo {
scsiLuWWNDeviceID: string;
serialNum: string;
modelNum: string;
firmwareRevision: string;
RotationRate: string;
MajorVersion: string;
MinorVersion: string;
smartSupportAvailable: boolean;
smartSupportEnabled: boolean;
smartErrorLog: string;
transport: string;
}
interface diskIOCountersStat {
readCount: number;
mergedReadCount: number;
DriteCount: number;
mergedWriteCount: number;
readBytes: number;
writeBytes: number;
readTime: number;
writeTime: number;
iopsInProgress: number;
ioTime: number;
weightedIO: number;
name: string;
serialNumber: string;
label: string;
}
interface serverOsInfo {
addr: string;
info: infoStat;
sensors: temperatureStat[];
users: userStat[];
error: string;
}
interface infoStat {
hostname: string;
uptime: number;
bootTime: number;
procs: number;
os: string;
platform: string;
platformFamily: string;
platformVersion: string;
kernelVersion: string;
kernelArch: string;
virtualizationSystem: string;
virtualizationRole: string;
hostid: string;
}
interface temperatureStat {
sensorKey: string;
sensorTemperature: number;
}
interface userStat {
user: string;
terminal: string;
host: string;
started: number;
}
interface serverMemInfo {
addr: string;
swap: swapMemoryStat;
virtualmem: virtualMemoryStat;
error: string;
}
interface swapMemoryStat {
total: number;
used: number;
free: number;
usedPercent: number;
sin: number;
sout: number;
pgin: number;
pgout: number;
pgfault: number;
pgmajfault: number;
}
interface virtualMemoryStat {
total: number;
available: number;
used: number;
usedPercent: number;
free: number;
active: number;
inactive: number;
wired: number;
laundry: number;
buffers: number;
cached: number;
writeback: number;
dirty: number;
writebacktmp: number;
shared: number;
slab: number;
sreclaimable: number;
sunreclaim: number;
pagetables: number;
swapcached: number;
commitlimit: number;
committedas: number;
hightotal: number;
highfree: number;
lowtotal: number;
lowfree: number;
swaptotal: number;
swapfree: number;
mapped: number;
vmalloctotal: number;
vmallocused: number;
vmallocchunk: number;
hugepagestotal: number;
hugepagesfree: number;
hugepagesize: number;
}
interface serverProcInfo {
addr: string;
processes: sysProcess[];
error: string;
}
interface sysProcess {
pid: number;
background: boolean;
cpupercent: number;
children: number[];
cmd: string;
connections: nethwConnectionStat[];
createtime: number;
cwd: string;
exe: string;
gids: number[];
iocounters: processIOCountersStat;
isrunning: boolean;
meminfo: memoryInfoStat;
memmaps: any[];
mempercent: number;
name: string;
netiocounters: nethwIOCounterStat[];
nice: number;
numctxswitches: processNmCtxSwitchesStat;
numfds: number;
numthreads: number;
pagefaults: processPageFaultsStat;
parent: number;
ppid: number;
rlimit: processRLimitStat[];
status: string;
tgid: number;
cputimes: cpuTimeStat;
uids: number[];
username: string;
}
interface nethwConnectionStat {
fd: number;
family: number;
type: number;
localaddr: netAddr;
remoteaddr: netAddr;
status: string;
uids: number[];
pid: number;
}
interface netAddr {
ip: string;
port: number;
}
interface processIOCountersStat {
readCount: number;
writeCount: number;
readBytes: number;
writeBytes: number;
}
interface memoryInfoStat {
rss: number;
vms: number;
hwm: number;
data: number;
stack: number;
locked: number;
swap: number;
}
interface nethwIOCounterStat {
name: string;
bytesSent: number;
bytesRecv: number;
packetsSent: number;
packetsRecv: number;
errin: number;
errout: number;
dropin: number;
dropout: number;
fifoin: number;
fifoout: number;
}
interface processNmCtxSwitchesStat {
voluntary: number;
involuntary: number;
}
interface processPageFaultsStat {
minorFaults: number;
majorFaults: number;
childMinorFaults: number;
childMajorFaults: number;
}
interface processRLimitStat {
resource: number;
soft: number;
hard: number;
used: number;
}

View File

@@ -15,17 +15,13 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useCallback, useEffect, useState } from "react";
import { ArrowIcon, Button, PageLayout, ProgressBar, Grid } from "mds";
import { PageLayout, ProgressBar, Grid } from "mds";
import { SubnetInfo } from "./types";
import api from "../../../common/api";
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
import LicensePlans from "./LicensePlans";
import { useNavigate } from "react-router-dom";
import RegistrationStatusBanner from "../Support/RegistrationStatusBanner";
import withSuspense from "../Common/Components/withSuspense";
import { getLicenseConsent } from "./utils";
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";
import HelpMenu from "../HelpMenu";
import { setHelpName } from "../../../systemSlice";
import { useAppDispatch } from "../../../store";
@@ -34,7 +30,6 @@ const LicenseConsentModal = withSuspense(
);
const License = () => {
const navigate = useNavigate();
const [activateProductModal, setActivateProductModal] =
useState<boolean>(false);
@@ -126,38 +121,9 @@ const License = () => {
return (
<Fragment>
<PageHeaderWrapper
label="MinIO License and Support Plan"
actions={
<Fragment>
{!isRegistered && (
<Button
id={"login-with-subnet"}
onClick={() => navigate(IAM_PAGES.REGISTER_SUPPORT)}
style={{
fontSize: "14px",
display: "flex",
alignItems: "center",
textDecoration: "none",
}}
icon={<ArrowIcon />}
variant={"callAction"}
>
Register your cluster
</Button>
)}
<HelpMenu />
</Fragment>
}
/>
<PageHeaderWrapper label="MinIO License and Support Plan" />
<PageLayout>
<Grid item xs={12}>
{isRegistered && (
<RegistrationStatusBanner email={licenseInfo?.email} />
)}
</Grid>
<LicensePlans
activateProductModal={activateProductModal}
closeModalAndFetchLicenseInfo={closeModalAndFetchLicenseInfo}

View File

@@ -22,42 +22,3 @@ export interface SubnetInfo {
storage_capacity: number;
organization: string;
}
export interface SubnetLoginRequest {
username?: string;
password?: string;
apiKey?: string;
proxy?: string;
}
export interface SubnetRegisterRequest {
token: string;
account_id: string;
}
export interface SubnetOrganization {
userId: number;
accountId: number;
subscriptionStatus: string;
isAccountOwner: boolean;
shortName: string;
company: string;
}
export interface SubnetLoginResponse {
registered: boolean;
mfa_token: string;
access_token: string;
organizations: SubnetOrganization[];
}
export interface SubnetLoginWithMFARequest {
username: string;
otp: string;
mfa_token: string;
proxy?: string;
}
export interface SubnetRegTokenResponse {
regToken: string;
}

View File

@@ -1,455 +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/>.
import React, { Fragment, useState } from "react";
import get from "lodash/get";
import {
Button,
ComputerLineIcon,
DownloadIcon,
DownloadStatIcon,
JSONIcon,
StorageIcon,
UploadStatIcon,
VersionIcon,
Grid,
Box,
} from "mds";
import { IndvServerMetric, SpeedTestResponse, STServer } from "./types";
import { calculateBytes, prettyNumber } from "../../../common/utils";
import { Area, AreaChart, CartesianGrid, ResponsiveContainer } from "recharts";
import { cleanMetrics } from "./utils";
import CodeMirrorWrapper from "../Common/FormComponents/CodeMirrorWrapper/CodeMirrorWrapper";
import SpeedTestUnit from "./SpeedTestUnit";
import styled from "styled-components";
const STResultsContainer = styled.div(({ theme }) => ({
"& .actionButtons": {
textAlign: "right",
},
"& .descriptorLabel": {
fontWeight: "bold",
fontSize: 14,
},
"& .resultsContainer": {
backgroundColor: get(theme, "boxBackground", "#FBFAFA"),
borderTop: `${get(theme, "borderColor", "#E2E2E2")} 1px solid`,
marginTop: 30,
padding: 25,
},
"& .resultsIcon": {
display: "flex",
alignItems: "center",
"& svg": {
fill: get(theme, `screenTitle.iconColor`, "#07193E"),
},
},
"& .detailedItem": {
display: "flex",
alignItems: "center",
justifyContent: "flex-start",
},
"& .detailedVersion": {
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
},
"& .serversTable": {
width: "100%",
marginTop: 15,
"& thead > tr > th": {
textAlign: "left",
padding: 15,
fontSize: 14,
fontWeight: "bold",
},
"& tbody > tr": {
"&:last-of-type": {
"& > td": {
borderBottom: `${get(theme, "borderColor", "#E2E2E2")} 1px solid`,
},
},
"& > td": {
borderTop: `${get(theme, "borderColor", "#E2E2E2")} 1px solid`,
padding: 15,
fontSize: 14,
"&:first-of-type": {
borderLeft: `${get(theme, "borderColor", "#E2E2E2")} 1px solid`,
},
"&:last-of-type": {
borderRight: `${get(theme, "borderColor", "#E2E2E2")} 1px solid`,
},
},
},
},
"& .serverIcon": {
width: 55,
},
"& .serverValue": {
width: 140,
},
"& .serverHost": {
maxWidth: 540,
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
},
"& .tableOverflow": {
overflowX: "auto",
paddingBottom: 15,
},
"& .objectGeneral": {
marginTop: 15,
},
"& .download": {
"& .min-icon": {
width: 35,
height: 35,
color: get(theme, "signalColors.good", "#4CCB92"),
},
},
"& .upload": {
"& .min-icon": {
width: 35,
height: 35,
color: get(theme, "signalColors.info", "#2781B0"),
},
},
"& .versionIcon": {
color: get(theme, `screenTitle.iconColor`, "#07193E"),
marginRight: 20,
},
}));
interface ISTResults {
results: SpeedTestResponse[];
start: boolean;
}
const STResults = ({ results, start }: ISTResults) => {
const [jsonView, setJsonView] = useState<boolean>(false);
const finalRes = results[results.length - 1] || [];
const getServers: STServer[] = get(finalRes, "GETStats.servers", []) || [];
const putServers: STServer[] = get(finalRes, "PUTStats.servers", []) || [];
const getThroughput = get(finalRes, "GETStats.throughputPerSec", 0);
const getObjects = get(finalRes, "GETStats.objectsPerSec", 0);
const putThroughput = get(finalRes, "PUTStats.throughputPerSec", 0);
const putObjects = get(finalRes, "PUTStats.objectsPerSec", 0);
let statJoin: IndvServerMetric[] = [];
getServers.forEach((item) => {
const hostName = item.endpoint;
const putMetric = putServers.find((item) => item.endpoint === hostName);
let itemJoin: IndvServerMetric = {
getUnit: "-",
getValue: "N/A",
host: item.endpoint,
putUnit: "-",
putValue: "N/A",
};
if (item.err && item.err !== "") {
itemJoin.getError = item.err;
itemJoin.getUnit = "-";
itemJoin.getValue = "N/A";
} else {
const niceGet = calculateBytes(item.throughputPerSec.toString());
itemJoin.getUnit = niceGet.unit;
itemJoin.getValue = niceGet.total.toString();
}
if (putMetric) {
if (putMetric.err && putMetric.err !== "") {
itemJoin.putError = putMetric.err;
itemJoin.putUnit = "-";
itemJoin.putValue = "N/A";
} else {
const nicePut = calculateBytes(putMetric.throughputPerSec.toString());
itemJoin.putUnit = nicePut.unit;
itemJoin.putValue = nicePut.total.toString();
}
}
statJoin.push(itemJoin);
});
const downloadResults = () => {
const date = new Date();
let element = document.createElement("a");
element.setAttribute(
"href",
"data:text/plain;charset=utf-8," + JSON.stringify(finalRes),
);
element.setAttribute(
"download",
`speedtest_results-${date.toISOString()}.log`,
);
element.style.display = "none";
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
};
const toggleJSONView = () => {
setJsonView(!jsonView);
};
const finalResJSON = finalRes ? JSON.stringify(finalRes, null, 4) : "";
const clnMetrics = cleanMetrics(results);
return (
<STResultsContainer>
<Grid container className={"objectGeneral"}>
<Grid item xs={12} md={6} lg={6}>
<Grid container className={"objectGeneral"}>
<Grid item xs={12} md={6} lg={6}>
<SpeedTestUnit
icon={
<div className={"download"}>
<DownloadStatIcon />
</div>
}
title={"GET"}
throughput={`${getThroughput}`}
objects={getObjects}
/>
</Grid>
<Grid item xs={12} md={6} lg={6}>
<SpeedTestUnit
icon={
<div className={"upload"}>
<UploadStatIcon />
</div>
}
title={"PUT"}
throughput={`${putThroughput}`}
objects={putObjects}
/>
</Grid>
</Grid>
</Grid>
<Grid item xs={12} md={6} lg={6}>
<ResponsiveContainer width="99%">
<AreaChart data={clnMetrics}>
<defs>
<linearGradient id="colorPut" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stopColor="#2781B0" stopOpacity={0.9} />
<stop offset="95%" stopColor="#fff" stopOpacity={0} />
</linearGradient>
<linearGradient id="colorGet" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stopColor="#4CCB92" stopOpacity={0.9} />
<stop offset="95%" stopColor="#fff" stopOpacity={0} />
</linearGradient>
</defs>
<CartesianGrid
strokeDasharray={"0 0"}
strokeWidth={1}
strokeOpacity={0.5}
stroke={"#F1F1F1"}
vertical={false}
/>
<Area
type="monotone"
dataKey={"get"}
stroke={"#4CCB92"}
fill={"url(#colorGet)"}
fillOpacity={0.3}
strokeWidth={2}
dot={false}
/>
<Area
type="monotone"
dataKey={"put"}
stroke={"#2781B0"}
fill={"url(#colorPut)"}
fillOpacity={0.3}
strokeWidth={2}
dot={false}
/>
</AreaChart>
</ResponsiveContainer>
</Grid>
</Grid>
<br />
{clnMetrics.length > 1 && (
<Fragment>
<Grid container>
<Grid item xs={12} md={6} className={"descriptorLabel"}>
{start ? (
<Fragment>Preliminar Results:</Fragment>
) : (
<Fragment>
{jsonView ? "JSON Results:" : "Detailed Results:"}
</Fragment>
)}
</Grid>
<Grid
item
xs={12}
md={6}
sx={{ display: "flex", justifyContent: "right", gap: 8 }}
>
{!start && (
<Fragment>
<Button
id={"download-results"}
aria-label="Download Results"
onClick={downloadResults}
icon={<DownloadIcon />}
/>
&nbsp;
<Button
id={"toggle-json"}
aria-label="Toogle JSON"
onClick={toggleJSONView}
icon={<JSONIcon />}
/>
</Fragment>
)}
</Grid>
</Grid>
<Box withBorders useBackground sx={{ marginTop: 15 }}>
<Grid container>
{jsonView ? (
<Fragment>
<CodeMirrorWrapper value={finalResJSON} onChange={() => {}} />
</Fragment>
) : (
<Fragment>
<Grid
item
xs={12}
sm={12}
md={1}
lg={1}
className={"resultsIcon"}
>
<ComputerLineIcon width={45} />
</Grid>
<Grid
item
xs={12}
sm={6}
md={3}
lg={2}
className={"detailedItem"}
>
Nodes:&nbsp;<strong>{finalRes.servers}</strong>
</Grid>
<Grid
item
xs={12}
sm={6}
md={3}
lg={2}
className={"detailedItem"}
>
Drives:&nbsp;<strong>{finalRes.disks}</strong>
</Grid>
<Grid
item
xs={12}
sm={6}
md={3}
lg={2}
className={"detailedItem"}
>
Concurrent:&nbsp;<strong>{finalRes.concurrent}</strong>
</Grid>
<Grid
item
xs={12}
sm={12}
md={12}
lg={5}
className={"detailedVersion"}
>
<span className={"versionIcon"}>
<VersionIcon />
</span>{" "}
MinIO VERSION&nbsp;<strong>{finalRes.version}</strong>
</Grid>
<Grid item xs={12} className={"tableOverflow"}>
<table
className={"serversTable"}
cellSpacing={0}
cellPadding={0}
>
<thead>
<tr>
<th colSpan={2}>Servers</th>
<th>GET</th>
<th>PUT</th>
</tr>
</thead>
<tbody>
{statJoin.map((stats, index) => (
<tr key={`storage-${index.toString()}`}>
<td className={"serverIcon"}>
<StorageIcon />
</td>
<td className={"serverHost"}>{stats.host}</td>
{stats.getError && stats.getError !== "" ? (
<td>{stats.getError}</td>
) : (
<Fragment>
<td className={"serverValue"}>
{prettyNumber(parseFloat(stats.getValue))}
&nbsp;
{stats.getUnit}/s.
</td>
</Fragment>
)}
{stats.putError && stats.putError !== "" ? (
<td>{stats.putError}</td>
) : (
<Fragment>
<td className={"serverValue"}>
{prettyNumber(parseFloat(stats.putValue))}
&nbsp;
{stats.putUnit}/s.
</td>
</Fragment>
)}
</tr>
))}
</tbody>
</table>
</Grid>
</Fragment>
)}
</Grid>
</Box>
</Fragment>
)}
</STResultsContainer>
);
};
export default STResults;

View File

@@ -1,99 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React from "react";
import styled from "styled-components";
import get from "lodash/get";
import { calculateBytes } from "../../../common/utils";
const SpeedTestUnitBase = styled.table(({ theme }) => ({
"& .objectGeneralTitle": {
lineHeight: 1,
fontSize: 50,
color: get(theme, "mutedText", "#87888d"),
},
"& .generalUnit": {
color: get(theme, "fontColor", "#000"),
fontSize: 12,
fontWeight: "bold",
},
"& .testUnitRes": {
fontSize: 60,
color: get(theme, "signalColors.main", "#07193E"),
fontWeight: "bold",
textAlign: "right",
},
"& .metricValContainer": {
lineHeight: 1,
verticalAlign: "bottom",
},
"& .objectsUnitRes": {
fontSize: 22,
marginTop: 6,
color: get(theme, "mutedText", "#87888d"),
fontWeight: "bold",
textAlign: "right",
},
"& .objectsUnit": {
color: get(theme, "mutedText", "#87888d"),
fontSize: 16,
fontWeight: "bold",
},
"& .iconTd": {
verticalAlign: "bottom",
},
}));
const SpeedTestUnit = ({
title,
icon,
throughput,
objects,
}: {
title: any;
icon: any;
throughput: string;
objects: number;
}) => {
const avg = calculateBytes(throughput);
let total = "0";
let unit = "";
if (avg.total !== 0) {
total = avg.total.toString();
unit = `${avg.unit}/s`;
}
return (
<SpeedTestUnitBase>
<tr>
<td className={"objectGeneralTitle"}>{title}</td>
<td className={"iconTd"}>{icon}</td>
</tr>
<tr>
<td className={`metricValContainer testUnitRes`}>{total}</td>
<td className={`metricValContainer generalUnit`}>{unit}</td>
</tr>
<tr>
<td className={`metricValContainer objectsUnitRes`}>{objects}</td>
<td className={`metricValContainer objectsUnit`}>
{objects !== 0 && "Objs/S"}
</td>
</tr>
</SpeedTestUnitBase>
);
};
export default SpeedTestUnit;

View File

@@ -1,331 +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/>.
import React, { Fragment, useEffect, useState } from "react";
import { useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import {
Box,
Button,
Grid,
HelpBox,
InputBox,
Loader,
PageLayout,
SpeedtestIcon,
WarnIcon,
} from "mds";
import { DateTime } from "luxon";
import STResults from "./STResults";
import ProgressBarWrapper from "../Common/ProgressBarWrapper/ProgressBarWrapper";
import InputUnitMenu from "../Common/FormComponents/InputUnitMenu/InputUnitMenu";
import DistributedOnly from "../Common/DistributedOnly/DistributedOnly";
import RegisterCluster from "../Support/RegisterCluster";
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";
import HelpMenu from "../HelpMenu";
import { SecureComponent } from "../../../common/SecureComponent";
import { selDistSet, setHelpName } from "../../../systemSlice";
import { registeredCluster } from "../../../config";
import { useAppDispatch } from "../../../store";
import { wsProtocol } from "../../../utils/wsUtils";
import { SpeedTestResponse } from "./types";
import {
CONSOLE_UI_RESOURCE,
IAM_SCOPES,
} from "../../../common/SecureComponent/permissions";
const Speedtest = () => {
const distributedSetup = useSelector(selDistSet);
const navigate = useNavigate();
const [start, setStart] = useState<boolean>(false);
const [currStatus, setCurrStatus] = useState<SpeedTestResponse[] | null>(
null,
);
const [size, setSize] = useState<string>("64");
const [sizeUnit, setSizeUnit] = useState<string>("MB");
const [duration, setDuration] = useState<string>("10");
const [topDate, setTopDate] = useState<number>(0);
const [currentValue, setCurrentValue] = useState<number>(0);
const [totalSeconds, setTotalSeconds] = useState<number>(0);
const [speedometerValue, setSpeedometerValue] = useState<number>(0);
const clusterRegistered = registeredCluster();
useEffect(() => {
// begin watch if bucketName in bucketList and start pressed
if (start) {
const url = new URL(window.location.toString());
const isDev = process.env.NODE_ENV === "development";
const port = isDev ? "9090" : url.port;
// check if we are using base path, if not this always is `/`
const baseLocation = new URL(document.baseURI);
const baseUrl = baseLocation.pathname;
const wsProt = wsProtocol(url.protocol);
const socket = new WebSocket(
`${wsProt}://${url.hostname}:${port}${baseUrl}ws/speedtest?&size=${size}${sizeUnit}&duration=${duration}s`,
);
const baseDate = DateTime.now();
const currentTime = baseDate.toUnixInteger() / 1000;
const incrementDate =
baseDate.plus({ seconds: parseInt("10") * 2 }).toUnixInteger() / 1000;
const totalSeconds = (incrementDate - currentTime) / 1000;
setTopDate(incrementDate);
setCurrentValue(currentTime);
setTotalSeconds(totalSeconds);
let interval: any | null = null;
if (socket !== null) {
socket.onopen = () => {
console.log("WebSocket Client Connected");
socket.send("ok");
interval = setInterval(() => {
socket.send("ok");
}, 10 * 1000);
};
socket.onmessage = (message: MessageEvent) => {
const data: SpeedTestResponse = JSON.parse(message.data.toString());
setCurrStatus((prevStatus) => {
let prSt: SpeedTestResponse[] = [];
if (prevStatus) {
prSt = [...prevStatus];
}
const insertData = data.servers !== 0 ? [data] : [];
return [...prSt, ...insertData];
});
const currTime = DateTime.now().toUnixInteger() / 1000;
setCurrentValue(currTime);
};
socket.onclose = () => {
clearInterval(interval);
console.log("connection closed by server");
// reset start status
setStart(false);
};
return () => {
// close websocket on useEffect cleanup
socket.close(1000);
clearInterval(interval);
console.log("closing websockets");
};
}
} else {
// reset start status
setStart(false);
}
}, [size, sizeUnit, start, duration]);
useEffect(() => {
const actualSeconds = (topDate - currentValue) / 1000;
let percToDisplay = 100 - (actualSeconds * 100) / totalSeconds;
if (percToDisplay > 100) {
percToDisplay = 100;
}
setSpeedometerValue(percToDisplay);
}, [start, currentValue, topDate, totalSeconds]);
const stoppedLabel = currStatus !== null ? "Retest" : "Start";
const buttonLabel = start ? "Start" : stoppedLabel;
const startSpeedtestButton = () => {
if (!clusterRegistered) {
navigate("/support/register");
return;
}
setCurrStatus(null);
setStart(true);
};
const dispatch = useAppDispatch();
useEffect(() => {
dispatch(setHelpName("performance"));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<Fragment>
<PageHeaderWrapper label="Performance" actions={<HelpMenu />} />
<PageLayout>
{!clusterRegistered && <RegisterCluster compactMode />}
{!distributedSetup ? (
<DistributedOnly
iconComponent={<SpeedtestIcon />}
entity={"Speedtest"}
/>
) : (
<SecureComponent
scopes={[IAM_SCOPES.ADMIN_HEAL]}
resource={CONSOLE_UI_RESOURCE}
>
<Box withBorders>
<Grid container>
<Grid item md={3} sm={12}>
<Box
sx={{
fontSize: 13,
marginBottom: 8,
}}
>
{start ? (
<Fragment>
Speedtest in progress...
<Loader style={{ width: 15, height: 15 }} />
</Fragment>
) : (
<Fragment>
{currStatus && !start ? (
<b>Speed Test results:</b>
) : (
<b>Performance test</b>
)}
</Fragment>
)}
</Box>
<Box>
<ProgressBarWrapper
value={speedometerValue}
ready={currStatus !== null && !start}
indeterminate={start}
size={"small"}
/>
</Box>
</Grid>
<Grid item md={4} sm={12}>
<div style={{ marginLeft: 10, width: 300 }}>
<InputBox
id={"size"}
name={"size"}
label={"Object Size"}
onChange={(e) => {
setSize(e.target.value);
}}
noLabelMinWidth={true}
value={size}
disabled={start || !clusterRegistered}
overlayObject={
<InputUnitMenu
id={"size-unit"}
onUnitChange={setSizeUnit}
unitSelected={sizeUnit}
unitsList={[
{ label: "KiB", value: "KiB" },
{ label: "MiB", value: "MiB" },
{ label: "GiB", value: "GiB" },
]}
disabled={start || !clusterRegistered}
/>
}
/>
</div>
</Grid>
<Grid item md={4} sm={12}>
<div style={{ marginLeft: 10, width: 300 }}>
<InputBox
id={"duration"}
name={"duration"}
label={"Duration"}
onChange={(e) => {
if (e.target.validity.valid) {
setDuration(e.target.value);
}
}}
noLabelMinWidth={true}
value={duration}
disabled={start || !clusterRegistered}
overlayObject={
<InputUnitMenu
id={"size-unit"}
onUnitChange={() => {}}
unitSelected={"s"}
unitsList={[{ label: "s", value: "s" }]}
disabled={start || !clusterRegistered}
/>
}
pattern={"[0-9]*"}
/>
</div>
</Grid>
<Grid item md={1} sm={12} sx={{ textAlign: "center" }}>
<Button
onClick={startSpeedtestButton}
color="primary"
type="button"
id={"start-speed-test"}
variant={
clusterRegistered && currStatus !== null && !start
? "callAction"
: "regular"
}
disabled={
duration.trim() === "" ||
size.trim() === "" ||
start ||
!clusterRegistered
}
label={buttonLabel}
/>
</Grid>
</Grid>
<Grid container>
<Grid item xs={12}>
<Fragment>
<Grid item xs={12}>
{currStatus !== null && (
<Fragment>
<STResults results={currStatus} start={start} />
</Fragment>
)}
</Grid>
</Fragment>
</Grid>
</Grid>
</Box>
{!start && !currStatus && clusterRegistered && (
<Fragment>
<br />
<HelpBox
title={
"During the speed test all your production traffic will be temporarily suspended."
}
iconComponent={<WarnIcon />}
help={<Fragment />}
/>
</Fragment>
)}
</SecureComponent>
)}
</PageLayout>
</Fragment>
);
};
export default Speedtest;

View File

@@ -1,48 +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/>.
export interface SpeedTestResponse {
version: string;
servers: number;
disks: number;
size: number;
concurrent: number;
PUTStats?: STStats;
GETStats?: STStats;
}
interface STStats {
throughputPerSec: number;
objectsPerSec: number;
servers: STServer[] | null;
}
export interface STServer {
endpoint: string;
throughputPerSec: number;
objectsPerSec: number;
err: string;
}
export interface IndvServerMetric {
host: string;
getValue: string;
getUnit: string;
getError?: string;
putValue: string;
putUnit: string;
putError?: string;
}

View File

@@ -1,32 +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/>.
import { SpeedTestResponse } from "./types";
export const cleanMetrics = (results: SpeedTestResponse[]) => {
const cleanRes = results.filter(
(item) => item.version !== "0" && item.disks !== 0,
);
const states = cleanRes.map((itemRes) => {
return {
get: itemRes.GETStats?.throughputPerSec || 0,
put: itemRes.PUTStats?.throughputPerSec || 0,
};
});
return [{ get: 0, put: 0 }, ...states];
};

View File

@@ -1,142 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useCallback, useEffect, useState } from "react";
import { Box, Button, FormLayout, InputBox, OnlineRegistrationIcon } from "mds";
import { useNavigate } from "react-router-dom";
import { SubnetLoginRequest, SubnetLoginResponse } from "../License/types";
import { useAppDispatch } from "../../../store";
import {
setErrorSnackMessage,
setServerNeedsRestart,
} from "../../../systemSlice";
import { ErrorResponseHandler } from "../../../common/types";
import { modalStyleUtils } from "../Common/FormComponents/common/styleLibrary";
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
import GetApiKeyModal from "./GetApiKeyModal";
import RegisterHelpBox from "./RegisterHelpBox";
import api from "../../../common/api";
interface IApiKeyRegister {
registerEndpoint: string;
}
const ApiKeyRegister = ({ registerEndpoint }: IApiKeyRegister) => {
const navigate = useNavigate();
const [showApiKeyModal, setShowApiKeyModal] = useState(false);
const [apiKey, setApiKey] = useState("");
const [loading, setLoading] = useState(false);
const [fromModal, setFromModal] = useState(false);
const dispatch = useAppDispatch();
const onRegister = useCallback(() => {
if (loading) {
return;
}
setLoading(true);
let request: SubnetLoginRequest = { apiKey };
api
.invoke("POST", registerEndpoint, request)
.then((resp: SubnetLoginResponse) => {
setLoading(false);
if (resp && resp.registered) {
dispatch(setServerNeedsRestart(true));
navigate(IAM_PAGES.LICENSE);
}
})
.catch((err: ErrorResponseHandler) => {
dispatch(setErrorSnackMessage(err));
setLoading(false);
reset();
});
}, [apiKey, dispatch, loading, registerEndpoint, navigate]);
useEffect(() => {
if (fromModal) {
onRegister();
}
}, [fromModal, onRegister]);
const reset = () => {
setApiKey("");
setFromModal(false);
};
return (
<FormLayout
title={"Register cluster with API key"}
icon={<OnlineRegistrationIcon />}
containerPadding={false}
withBorders={false}
helpBox={<RegisterHelpBox />}
>
<Box
sx={{
fontSize: 14,
display: "flex",
flexFlow: "column",
marginBottom: "30px",
}}
>
Use your MinIO Subscription Network API Key to register this cluster.
</Box>
<Box
sx={{
flex: "1",
}}
>
<InputBox
id="api-key"
name="api-key"
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
setApiKey(event.target.value)
}
label="API Key"
value={apiKey}
/>
<Box sx={modalStyleUtils.modalButtonBar}>
<Button
id={"get-from-subnet"}
variant="regular"
disabled={loading}
onClick={() => setShowApiKeyModal(true)}
label={"Get from SUBNET"}
/>
<Button
id={"register"}
type="submit"
variant="callAction"
disabled={loading || apiKey.trim().length === 0}
onClick={() => onRegister()}
label={"Register"}
/>
</Box>
</Box>
<GetApiKeyModal
open={showApiKeyModal}
closeModal={() => setShowApiKeyModal(false)}
onSet={(value) => {
setApiKey(value);
setFromModal(true);
}}
/>
</FormLayout>
);
};
export default ApiKeyRegister;

View File

@@ -1,212 +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/>.
import React, { Fragment, useEffect, useState } from "react";
import {
Box,
Button,
CallHomeMenuIcon,
FormLayout,
HelpBox,
Loader,
PageLayout,
Switch,
} from "mds";
import { Link, useNavigate } from "react-router-dom";
import api from "../../../common/api";
import { ErrorResponseHandler } from "../../../common/types";
import { setErrorSnackMessage, setHelpName } from "../../../systemSlice";
import { useAppDispatch } from "../../../store";
import { ICallHomeResponse } from "./types";
import { registeredCluster } from "../../../config";
import CallHomeConfirmation from "./CallHomeConfirmation";
import RegisterCluster from "./RegisterCluster";
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";
import HelpMenu from "../HelpMenu";
const CallHome = () => {
const dispatch = useAppDispatch();
const navigate = useNavigate();
const [loading, setLoading] = useState<boolean>(true);
const [showConfirmation, setShowConfirmation] = useState<boolean>(false);
const [diagEnabled, setDiagEnabled] = useState<boolean>(false);
const [oDiagEnabled, setODiagEnabled] = useState<boolean>(false);
const [disableMode, setDisableMode] = useState<boolean>(false);
const clusterRegistered = registeredCluster();
useEffect(() => {
if (loading) {
api
.invoke("GET", `/api/v1/support/callhome`)
.then((res: ICallHomeResponse) => {
setLoading(false);
setDiagEnabled(!!res.diagnosticsStatus);
setODiagEnabled(!!res.diagnosticsStatus);
})
.catch((err: ErrorResponseHandler) => {
setLoading(false);
dispatch(setErrorSnackMessage(err));
});
}
}, [loading, dispatch]);
const callHomeClose = (refresh: boolean) => {
if (refresh) {
setLoading(true);
}
setShowConfirmation(false);
};
const confirmCallHomeAction = () => {
if (!clusterRegistered) {
navigate("/support/register");
return;
}
setDisableMode(false);
setShowConfirmation(true);
};
const disableCallHomeAction = () => {
setDisableMode(true);
setShowConfirmation(true);
};
let mainVariant: "regular" | "callAction" = "regular";
if (clusterRegistered && diagEnabled !== oDiagEnabled) {
mainVariant = "callAction";
}
useEffect(() => {
dispatch(setHelpName("call_home"));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<Fragment>
{showConfirmation && (
<CallHomeConfirmation
onClose={callHomeClose}
open={showConfirmation}
diagStatus={diagEnabled}
disable={disableMode}
/>
)}
<PageHeaderWrapper label="Call Home" actions={<HelpMenu />} />
<PageLayout>
{!clusterRegistered && <RegisterCluster compactMode />}
<FormLayout
helpBox={
<HelpBox
title={"Learn more about Call Home"}
iconComponent={<CallHomeMenuIcon />}
help={
<Fragment>
<Box
sx={{
display: "flex",
flexFlow: "column",
fontSize: "14px",
flex: "2",
marginTop: "10px",
}}
>
<Box>
Enabling Call Home sends cluster health & status to your
registered MinIO Subscription Network account every 24
hours.
<br />
<br />
This helps the MinIO support team to provide quick
incident responses along with suggestions for possible
improvements that can be made to your MinIO instances.
<br />
<br />
Your cluster must be{" "}
<Link to={"/support/register"}>registered</Link> in the
MinIO Subscription Network (SUBNET) before enabling this
feature.
</Box>
</Box>
</Fragment>
}
/>
}
>
{loading ? (
<span style={{ marginLeft: 5 }}>
<Loader style={{ width: 16, height: 16 }} />
</span>
) : (
<Fragment>
<Switch
value="enableDiag"
id="enableDiag"
name="enableDiag"
checked={diagEnabled}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setDiagEnabled(event.target.checked);
}}
label={"Daily Health Report"}
disabled={!clusterRegistered}
description={
"Daily Health Report enables you to proactively identify potential issues in your deployment before they escalate."
}
/>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
marginTop: "55px",
gap: "0px 10px",
}}
>
{oDiagEnabled && (
<Button
id={"callhome-action"}
variant={"secondary"}
data-test-id="call-home-toggle-button"
onClick={disableCallHomeAction}
disabled={loading || !clusterRegistered}
>
Disable Call Home
</Button>
)}
<Button
id={"callhome-action"}
type="button"
variant={mainVariant}
data-test-id="call-home-toggle-button"
onClick={confirmCallHomeAction}
disabled={loading || !clusterRegistered}
>
Save Configuration
</Button>
</Box>
</Fragment>
)}
</FormLayout>
</PageLayout>
</Fragment>
);
};
export default CallHome;

Some files were not shown because too many files have changed in this diff Show More