github.com/lulzWill/go-agent@v2.1.2+incompatible/internal/utilization/azure.go (about)

     1  package utilization
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"net/http"
     8  )
     9  
    10  const (
    11  	azureHostname     = "169.254.169.254"
    12  	azureEndpointPath = "/metadata/instance/compute?api-version=2017-03-01"
    13  	azureEndpoint     = "http://" + azureHostname + azureEndpointPath
    14  )
    15  
    16  type azure struct {
    17  	Location string `json:"location,omitempty"`
    18  	Name     string `json:"name,omitempty"`
    19  	VMID     string `json:"vmId,omitempty"`
    20  	VMSize   string `json:"vmSize,omitempty"`
    21  }
    22  
    23  func gatherAzure(util *Data, client *http.Client) error {
    24  	az, err := getAzure(client)
    25  	if err != nil {
    26  		// Only return the error here if it is unexpected to prevent
    27  		// warning customers who aren't running Azure about a timeout.
    28  		if _, ok := err.(unexpectedAzureErr); ok {
    29  			return err
    30  		}
    31  		return nil
    32  	}
    33  	util.Vendors.Azure = az
    34  
    35  	return nil
    36  }
    37  
    38  type unexpectedAzureErr struct{ e error }
    39  
    40  func (e unexpectedAzureErr) Error() string {
    41  	return fmt.Sprintf("unexpected Azure error: %v", e.e)
    42  }
    43  
    44  func getAzure(client *http.Client) (*azure, error) {
    45  	req, err := http.NewRequest("GET", azureEndpoint, nil)
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  	req.Header.Add("Metadata", "true")
    50  
    51  	response, err := client.Do(req)
    52  	if err != nil {
    53  		// No unexpectedAzureErr here: a timeout isusually going to
    54  		// happen.
    55  		return nil, err
    56  	}
    57  	defer response.Body.Close()
    58  
    59  	if response.StatusCode != 200 {
    60  		return nil, unexpectedAzureErr{e: fmt.Errorf("response code %d", response.StatusCode)}
    61  	}
    62  
    63  	data, err := ioutil.ReadAll(response.Body)
    64  	if err != nil {
    65  		return nil, unexpectedAzureErr{e: err}
    66  	}
    67  
    68  	az := &azure{}
    69  	if err := json.Unmarshal(data, az); err != nil {
    70  		return nil, unexpectedAzureErr{e: err}
    71  	}
    72  
    73  	if err := az.validate(); err != nil {
    74  		return nil, unexpectedAzureErr{e: err}
    75  	}
    76  
    77  	return az, nil
    78  }
    79  
    80  func (az *azure) validate() (err error) {
    81  	az.Location, err = normalizeValue(az.Location)
    82  	if err != nil {
    83  		return fmt.Errorf("Invalid location: %v", err)
    84  	}
    85  
    86  	az.Name, err = normalizeValue(az.Name)
    87  	if err != nil {
    88  		return fmt.Errorf("Invalid name: %v", err)
    89  	}
    90  
    91  	az.VMID, err = normalizeValue(az.VMID)
    92  	if err != nil {
    93  		return fmt.Errorf("Invalid VM ID: %v", err)
    94  	}
    95  
    96  	az.VMSize, err = normalizeValue(az.VMSize)
    97  	if err != nil {
    98  		return fmt.Errorf("Invalid VM size: %v", err)
    99  	}
   100  
   101  	return
   102  }