github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/internal/config/subnet/subnet.go (about)

     1  // Copyright (c) 2015-2022 MinIO, Inc.
     2  //
     3  // This file is part of MinIO Object Storage stack
     4  //
     5  // This program is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Affero General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // This program is distributed in the hope that it will be useful
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU Affero General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Affero General Public License
    16  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package subnet
    19  
    20  import (
    21  	"bytes"
    22  	"encoding/json"
    23  	"errors"
    24  	"fmt"
    25  	"io"
    26  	"mime/multipart"
    27  	"net/http"
    28  	"time"
    29  
    30  	xhttp "github.com/minio/minio/internal/http"
    31  )
    32  
    33  const (
    34  	respBodyLimit = 1 << 20 // 1 MiB
    35  
    36  	// LoggerWebhookName - subnet logger webhook target
    37  	LoggerWebhookName = "subnet"
    38  )
    39  
    40  // Upload given file content (payload) to specified URL
    41  func (c Config) Upload(reqURL string, filename string, payload []byte) (string, error) {
    42  	if !c.Registered() {
    43  		return "", errors.New("Deployment is not registered with SUBNET. Please register the deployment via 'mc license register ALIAS'")
    44  	}
    45  
    46  	var body bytes.Buffer
    47  	writer := multipart.NewWriter(&body)
    48  	part, e := writer.CreateFormFile("file", filename)
    49  	if e != nil {
    50  		return "", e
    51  	}
    52  
    53  	if _, e = part.Write(payload); e != nil {
    54  		return "", e
    55  	}
    56  	writer.Close()
    57  
    58  	r, e := http.NewRequest(http.MethodPost, reqURL, &body)
    59  	if e != nil {
    60  		return "", e
    61  	}
    62  	r.Header.Add("Content-Type", writer.FormDataContentType())
    63  
    64  	return c.submitPost(r)
    65  }
    66  
    67  func (c Config) submitPost(r *http.Request) (string, error) {
    68  	configLock.RLock()
    69  	r.Header.Set(xhttp.SubnetAPIKey, c.APIKey)
    70  	configLock.RUnlock()
    71  	r.Header.Set(xhttp.MinioDeploymentID, xhttp.GlobalDeploymentID)
    72  
    73  	client := &http.Client{
    74  		Timeout:   10 * time.Second,
    75  		Transport: c.transport,
    76  	}
    77  
    78  	resp, err := client.Do(r)
    79  	if err != nil {
    80  		return "", err
    81  	}
    82  	defer xhttp.DrainBody(resp.Body)
    83  
    84  	respBytes, err := io.ReadAll(io.LimitReader(resp.Body, respBodyLimit))
    85  	if err != nil {
    86  		return "", err
    87  	}
    88  	respStr := string(respBytes)
    89  
    90  	if resp.StatusCode == http.StatusOK {
    91  		return respStr, nil
    92  	}
    93  
    94  	return respStr, fmt.Errorf("SUBNET request failed with code %d and error: %s", resp.StatusCode, respStr)
    95  }
    96  
    97  // Post submit 'payload' to specified URL
    98  func (c Config) Post(reqURL string, payload interface{}) (string, error) {
    99  	if !c.Registered() {
   100  		return "", errors.New("Deployment is not registered with SUBNET. Please register the deployment via 'mc license register ALIAS'")
   101  	}
   102  	body, err := json.Marshal(payload)
   103  	if err != nil {
   104  		return "", err
   105  	}
   106  	r, err := http.NewRequest(http.MethodPost, reqURL, bytes.NewReader(body))
   107  	if err != nil {
   108  		return "", err
   109  	}
   110  
   111  	r.Header.Set("Content-Type", "application/json")
   112  
   113  	return c.submitPost(r)
   114  }