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

     1  package utilization
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"net/http"
     8  )
     9  
    10  const (
    11  	awsHostname     = "169.254.169.254"
    12  	awsEndpointPath = "/2016-09-02/dynamic/instance-identity/document"
    13  	awsEndpoint     = "http://" + awsHostname + awsEndpointPath
    14  )
    15  
    16  type aws struct {
    17  	InstanceID       string `json:"instanceId,omitempty"`
    18  	InstanceType     string `json:"instanceType,omitempty"`
    19  	AvailabilityZone string `json:"availabilityZone,omitempty"`
    20  }
    21  
    22  func gatherAWS(util *Data, client *http.Client) error {
    23  	aws, err := getAWS(client)
    24  	if err != nil {
    25  		// Only return the error here if it is unexpected to prevent
    26  		// warning customers who aren't running AWS about a timeout.
    27  		if _, ok := err.(unexpectedAWSErr); ok {
    28  			return err
    29  		}
    30  		return nil
    31  	}
    32  	util.Vendors.AWS = aws
    33  
    34  	return nil
    35  }
    36  
    37  type unexpectedAWSErr struct{ e error }
    38  
    39  func (e unexpectedAWSErr) Error() string {
    40  	return fmt.Sprintf("unexpected AWS error: %v", e.e)
    41  }
    42  
    43  func getAWS(client *http.Client) (*aws, error) {
    44  	response, err := client.Get(awsEndpoint)
    45  	if err != nil {
    46  		// No unexpectedAWSErr here: A timeout is usually going to
    47  		// happen.
    48  		return nil, err
    49  	}
    50  	defer response.Body.Close()
    51  
    52  	if response.StatusCode != 200 {
    53  		return nil, unexpectedAWSErr{e: fmt.Errorf("response code %d", response.StatusCode)}
    54  	}
    55  
    56  	data, err := ioutil.ReadAll(response.Body)
    57  	if err != nil {
    58  		return nil, unexpectedAWSErr{e: err}
    59  	}
    60  	a := &aws{}
    61  	if err := json.Unmarshal(data, a); err != nil {
    62  		return nil, unexpectedAWSErr{e: err}
    63  	}
    64  
    65  	if err := a.validate(); err != nil {
    66  		return nil, unexpectedAWSErr{e: err}
    67  	}
    68  
    69  	return a, nil
    70  }
    71  
    72  func (a *aws) validate() (err error) {
    73  	a.InstanceID, err = normalizeValue(a.InstanceID)
    74  	if err != nil {
    75  		return fmt.Errorf("invalid instance ID: %v", err)
    76  	}
    77  
    78  	a.InstanceType, err = normalizeValue(a.InstanceType)
    79  	if err != nil {
    80  		return fmt.Errorf("invalid instance type: %v", err)
    81  	}
    82  
    83  	a.AvailabilityZone, err = normalizeValue(a.AvailabilityZone)
    84  	if err != nil {
    85  		return fmt.Errorf("invalid availability zone: %v", err)
    86  	}
    87  
    88  	return
    89  }