github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/pkg/cloud/azure/metadata.go (about)

     1  package azure
     2  
     3  import (
     4  	"crypto/md5" //nolint:gosec
     5  	"encoding/json"
     6  	"fmt"
     7  	"io"
     8  	"net/http"
     9  	"net/url"
    10  	"time"
    11  
    12  	"github.com/treeverse/lakefs/pkg/cloud"
    13  	"github.com/treeverse/lakefs/pkg/logging"
    14  )
    15  
    16  const azureMetadataIP = "169.254.169.254"
    17  const metadataRequestTimeout = 5 * time.Second
    18  
    19  type MetadataProvider struct {
    20  	logger logging.Logger
    21  }
    22  
    23  func NewMetadataProvider(logger logging.Logger) *MetadataProvider {
    24  	return &MetadataProvider{logger: logger}
    25  }
    26  
    27  type instanceMetadataResponse struct {
    28  	Compute struct {
    29  		SubscriptionID string `json:"subscriptionId"`
    30  	} `json:"compute"`
    31  }
    32  
    33  func (m *MetadataProvider) GetMetadata() map[string]string {
    34  	client := http.Client{Timeout: metadataRequestTimeout}
    35  	req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://%s/metadata/instance", azureMetadataIP), nil)
    36  	if err != nil {
    37  		m.logger.WithError(err).Warn("Failed to create request for Azure instance metadata")
    38  		return nil
    39  	}
    40  	req.Header.Add("Metadata", "True")
    41  	q := url.Values{"format": {"json"}, "api-version": {"2019-03-11"}}
    42  	req.URL.RawQuery = q.Encode()
    43  	resp, err := client.Do(req)
    44  	if err != nil {
    45  		m.logger.WithError(err).Warn("Failed to get Azure subscription ID from instance metadata", err)
    46  		return nil
    47  	}
    48  	defer func() {
    49  		_ = resp.Body.Close()
    50  	}()
    51  	responseBody, err := io.ReadAll(resp.Body)
    52  	if err != nil {
    53  		m.logger.WithError(err).Warn("Failed to get Azure subscription ID from instance metadata", err)
    54  		return nil
    55  	}
    56  	responseObj := &instanceMetadataResponse{}
    57  	err = json.Unmarshal(responseBody, responseObj)
    58  	if err != nil {
    59  		m.logger.WithError(err).Warn("Failed to get Azure subscription ID from instance metadata", err)
    60  		return nil
    61  	}
    62  	if responseObj.Compute.SubscriptionID == "" {
    63  		m.logger.Info("Got empty subscription id from azure")
    64  		return nil
    65  	}
    66  	return map[string]string{
    67  		cloud.IDKey:     fmt.Sprintf("%x", md5.Sum([]byte(responseObj.Compute.SubscriptionID))), //nolint:gosec
    68  		cloud.IDTypeKey: "azure_subscription_id",
    69  	}
    70  }