azure.go 2.2 KB

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