diff --git a/api/admin_health_info.go b/api/admin_health_info.go
index a9467549f..d467f65ee 100644
--- a/api/admin_health_info.go
+++ b/api/admin_health_info.go
@@ -17,22 +17,22 @@
package api
import (
- "bytes"
"context"
b64 "encoding/base64"
"encoding/json"
"errors"
"fmt"
"net/http"
- "strings"
+ "net/url"
+ "os"
"time"
+ "github.com/minio/console/pkg/logger"
"github.com/minio/console/pkg/utils"
- "github.com/klauspost/compress/gzip"
- xhttp "github.com/minio/console/pkg/http"
subnet "github.com/minio/console/pkg/subnet"
"github.com/minio/madmin-go/v3"
+ mc "github.com/minio/mc/cmd"
"github.com/minio/websocket"
)
@@ -63,7 +63,7 @@ func startHealthInfo(ctx context.Context, conn WSConn, client MinioAdmin, deadli
return err
}
- compressedDiag, err := tarGZ(healthInfo, version)
+ compressedDiag, err := mc.TarGZHealthInfo(healthInfo, version)
if err != nil {
return err
}
@@ -75,11 +75,11 @@ func startHealthInfo(ctx context.Context, conn WSConn, client MinioAdmin, deadli
}
ctx = context.WithValue(ctx, utils.ContextClientIP, conn.remoteAddress())
- subnetResp, err := sendHealthInfoToSubnet(ctx, healthInfo, client)
+ err = sendHealthInfoToSubnet(ctx, healthInfo, client)
report := messageReport{
Encoded: encodedDiag,
ServerHealthInfo: healthInfo,
- SubnetResponse: subnetResp,
+ SubnetResponse: mc.SubnetBaseURL() + "/health",
}
if err != nil {
report.SubnetResponse = fmt.Sprintf("Error: %s", err.Error())
@@ -94,31 +94,6 @@ func startHealthInfo(ctx context.Context, conn WSConn, client MinioAdmin, deadli
return conn.writeMessage(websocket.TextMessage, message)
}
-// compress and tar MinIO diagnostics output
-func tarGZ(healthInfo interface{}, version string) ([]byte, error) {
- buffer := bytes.NewBuffer(nil)
- gzWriter := gzip.NewWriter(buffer)
-
- enc := json.NewEncoder(gzWriter)
-
- header := struct {
- Version string `json:"version"`
- }{Version: version}
-
- if err := enc.Encode(header); err != nil {
- return nil, err
- }
-
- if err := enc.Encode(healthInfo); err != nil {
- return nil, err
- }
- err := gzWriter.Close()
- if err != nil {
- return nil, err
- }
- return buffer.Bytes(), nil
-}
-
// getHealthInfoOptionsFromReq gets duration for startHealthInfo request
// path come as : `/health-info?deadline=2h`
func getHealthInfoOptionsFromReq(req *http.Request) (*time.Duration, error) {
@@ -129,16 +104,27 @@ func getHealthInfoOptionsFromReq(req *http.Request) (*time.Duration, error) {
return &deadlineDuration, nil
}
-func sendHealthInfoToSubnet(ctx context.Context, healthInfo interface{}, client MinioAdmin) (string, error) {
- filename := fmt.Sprintf("health_%d.json", time.Now().Unix())
+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
+}
- clientIP := utils.ClientIPFromContext(ctx)
-
- subnetUploadURL := subnet.UploadURL("health", filename)
- subnetHTTPClient := &xhttp.Client{Client: GetConsoleHTTPClient("", clientIP)}
+func sendHealthInfoToSubnet(ctx context.Context, healthInfo interface{}, client MinioAdmin) error {
+ filename := fmt.Sprintf("health_%d.json.gz", time.Now().Unix())
subnetTokenConfig, e := GetSubnetKeyFromMinIOConfig(ctx, client)
if e != nil {
- return "", e
+ return e
+ }
+ e = updateMcGlobals(*subnetTokenConfig)
+ if e != nil {
+ return e
}
var apiKey string
if len(subnetTokenConfig.APIKey) != 0 {
@@ -146,32 +132,41 @@ func sendHealthInfoToSubnet(ctx context.Context, healthInfo interface{}, client
} else {
apiKey, e = subnet.GetSubnetAPIKeyUsingLicense(subnetTokenConfig.License)
if e != nil {
- return "", e
+ return e
}
}
- headers := subnet.UploadAuthHeaders(apiKey)
- uploadInfo, formDataType, e := subnet.ProcessUploadInfo(healthInfo, "health", filename)
+ compressedHealthInfo, e := mc.TarGZHealthInfo(healthInfo, madmin.HealthInfoVersion)
if e != nil {
- return "", e
+ 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
}
- resp, e := subnet.UploadFileToSubnet(uploadInfo, subnetHTTPClient, subnetUploadURL, headers, formDataType)
- if e != nil {
- return "", e
- }
type SubnetResponse struct {
- ClusterURL string `json:"cluster_url,omitempty"`
+ 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
- }
- if len(subnetResp.ClusterURL) != 0 {
- subnetClusterURL := strings.ReplaceAll(subnetResp.ClusterURL, "%2f", "/")
- return subnetClusterURL, nil
+ return e
}
- return "", ErrSubnetUploadFail
+ return nil
}
diff --git a/api/configure_console.go b/api/configure_console.go
index e84c026ac..f44dfaa01 100644
--- a/api/configure_console.go
+++ b/api/configure_console.go
@@ -506,7 +506,7 @@ func replaceBaseInIndex(indexPageBytes []byte, basePath string) []byte {
func replaceLicense(indexPageBytes []byte) []byte {
indexPageStr := string(indexPageBytes)
newPlan := fmt.Sprintf("", InstanceLicensePlan.String())
- indexPageStr = strings.Replace(indexPageStr, "", newPlan, 1)
+ indexPageStr = strings.Replace(indexPageStr, "", newPlan, 1)
indexPageBytes = []byte(indexPageStr)
return indexPageBytes
}
diff --git a/api/errors.go b/api/errors.go
index bc067bdd0..d1e0341bf 100644
--- a/api/errors.go
+++ b/api/errors.go
@@ -72,7 +72,6 @@ var (
ErrEncryptionConfigNotFound = errors.New("encryption configuration not found")
ErrPolicyNotFound = errors.New("policy does not exist")
ErrLoginNotAllowed = errors.New("login not allowed")
- ErrSubnetUploadFail = errors.New("SUBNET upload failed")
ErrHealthReportFail = errors.New("failure to generate Health report")
)
diff --git a/go.mod b/go.mod
index c12220cb0..632ec91f4 100644
--- a/go.mod
+++ b/go.mod
@@ -21,8 +21,8 @@ require (
github.com/minio/cli v1.24.2
github.com/minio/highwayhash v1.0.2
github.com/minio/kes v0.23.0
- github.com/minio/madmin-go/v3 v3.0.50-0.20240307075442-63b4fc3ac1fd
- github.com/minio/mc v0.0.0-20240320210729-9043bbf545d2
+ github.com/minio/madmin-go/v3 v3.0.50
+ github.com/minio/mc v0.0.0-20240330152952-9f8147bf0e03
github.com/minio/minio-go/v7 v7.0.69
github.com/minio/selfupdate v0.6.0
github.com/minio/websocket v1.6.0
diff --git a/go.sum b/go.sum
index 981dac4c3..3eedebb2d 100644
--- a/go.sum
+++ b/go.sum
@@ -184,10 +184,10 @@ github.com/minio/kes v0.23.0 h1:T0zHtyDoI3JdKrVvzdM4xwVryYYyh5pKwNUVBoqxsNs=
github.com/minio/kes v0.23.0/go.mod h1:vvXVGcgu9mYLkbVWlEvFFl6bYR196RQlOU2Q+rHApl8=
github.com/minio/kes-go v0.2.1 h1:KnqS+p6xoSFJZbQhmJaz/PbxeA6nQyRqT/ywrn5lU2o=
github.com/minio/kes-go v0.2.1/go.mod h1:76xf7l41Wrh+IifisABXK2S8uZWYgWV1IGBKC3GdOJk=
-github.com/minio/madmin-go/v3 v3.0.50-0.20240307075442-63b4fc3ac1fd h1:oZycRrLgzEg4+lGZ5Tkua3BKvK7rOtDlmoOR3gq58l4=
-github.com/minio/madmin-go/v3 v3.0.50-0.20240307075442-63b4fc3ac1fd/go.mod h1:ZDF7kf5fhmxLhbGTqyq5efs4ao0v4eWf7nOuef/ljJs=
-github.com/minio/mc v0.0.0-20240320210729-9043bbf545d2 h1:zF4kiN6HJp4B5IFp+riDA8roY0r+UJV0RvaaVitchH4=
-github.com/minio/mc v0.0.0-20240320210729-9043bbf545d2/go.mod h1:YgeY0RTYvbm/H6Gzwb+rpRsQ/XREi3NwITZUcTNATOQ=
+github.com/minio/madmin-go/v3 v3.0.50 h1:+RQMetVFvPQmAOEDN/xmLhwk9+xOzu3rqwnlZEskgvg=
+github.com/minio/madmin-go/v3 v3.0.50/go.mod h1:ZDF7kf5fhmxLhbGTqyq5efs4ao0v4eWf7nOuef/ljJs=
+github.com/minio/mc v0.0.0-20240330152952-9f8147bf0e03 h1:xF1hntqvs/CVEHGBETSrIMTW3iSU3k2j/YCFXGDWoBs=
+github.com/minio/mc v0.0.0-20240330152952-9f8147bf0e03/go.mod h1:RMCe706GTL9EOO6pxzFXd9Vp+3w2L1uctPiycmLDr9U=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
github.com/minio/minio-go/v7 v7.0.69 h1:l8AnsQFyY1xiwa/DaQskY4NXSLA2yrGsW5iD9nRPVS0=
diff --git a/pkg/subnet/utils.go b/pkg/subnet/utils.go
index 1111521cf..a7e6001fb 100644
--- a/pkg/subnet/utils.go
+++ b/pkg/subnet/utils.go
@@ -18,14 +18,11 @@ package subnet
import (
"bytes"
- "compress/gzip"
"crypto/tls"
"encoding/base64"
"encoding/json"
- "errors"
"fmt"
"io"
- "mime/multipart"
"net"
"net/http"
"time"
@@ -79,65 +76,6 @@ func UploadAuthHeaders(apiKey string) map[string]string {
return map[string]string{"x-subnet-api-key": apiKey}
}
-func ProcessUploadInfo(info interface{}, uploadType string, filename string) ([]byte, string, error) {
- if uploadType == "health" {
- return processHealthReport(info, filename)
- }
- return nil, "", errors.New("invalid SUBNET upload type")
-}
-
-func UploadFileToSubnet(info []byte, client *xhttp.Client, reqURL string, headers map[string]string, formDataType string) (string, error) {
- req, e := subnetUploadReq(info, reqURL, formDataType)
- if e != nil {
- return "", e
- }
- resp, e := subnetReqDo(client, req, headers)
- return resp, e
-}
-
-func processHealthReport(info interface{}, filename string) ([]byte, string, error) {
- var body bytes.Buffer
- writer := multipart.NewWriter(&body)
- zipWriter := gzip.NewWriter(&body)
- version := "3"
- enc := json.NewEncoder(zipWriter)
-
- header := struct {
- Version string `json:"version"`
- }{Version: version}
-
- if e := enc.Encode(header); e != nil {
- return nil, "", e
- }
-
- if e := enc.Encode(info); e != nil {
- return nil, "", e
- }
- zipWriter.Close()
- temp := body
- part, e := writer.CreateFormFile("file", filename)
- if e != nil {
- return nil, "", e
- }
- if _, e = io.Copy(part, &temp); e != nil {
- return nil, "", e
- }
-
- writer.Close()
- return body.Bytes(), writer.FormDataContentType(), nil
-}
-
-func subnetUploadReq(body []byte, url string, formDataType string) (*http.Request, error) {
- uploadDataBody := bytes.NewReader(body)
- r, e := http.NewRequest(http.MethodPost, url, uploadDataBody)
- if e != nil {
- return nil, e
- }
- r.Header.Add("Content-Type", formDataType)
-
- return r, nil
-}
-
func GenerateRegToken(clusterRegInfo mc.ClusterRegistrationInfo) (string, error) {
token, e := json.Marshal(clusterRegInfo)
if e != nil {
diff --git a/web-app/public/index.html b/web-app/public/index.html
index 806d86d3f..76a4bb79f 100644
--- a/web-app/public/index.html
+++ b/web-app/public/index.html
@@ -15,7 +15,7 @@
name="theme-color"
/>
-
+