metadata.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. package metadata
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "io/ioutil"
  7. "net"
  8. "net/http"
  9. )
  10. const BaseURL = "https://metadata.packet.net"
  11. func GetMetadata() (*CurrentDevice, error) {
  12. res, err := http.Get(BaseURL + "/metadata")
  13. if err != nil {
  14. return nil, err
  15. }
  16. b, err := ioutil.ReadAll(res.Body)
  17. res.Body.Close()
  18. if err != nil {
  19. return nil, err
  20. }
  21. var result struct {
  22. Error string `json:"error"`
  23. *CurrentDevice
  24. }
  25. if err := json.Unmarshal(b, &result); err != nil {
  26. if res.StatusCode >= 400 {
  27. return nil, errors.New(res.Status)
  28. }
  29. return nil, err
  30. }
  31. if result.Error != "" {
  32. return nil, errors.New(result.Error)
  33. }
  34. return result.CurrentDevice, nil
  35. }
  36. func GetUserData() ([]byte, error) {
  37. res, err := http.Get(BaseURL + "/userdata")
  38. if err != nil {
  39. return nil, err
  40. }
  41. b, err := ioutil.ReadAll(res.Body)
  42. res.Body.Close()
  43. return b, err
  44. }
  45. type AddressFamily int
  46. const (
  47. IPv4 = AddressFamily(4)
  48. IPv6 = AddressFamily(6)
  49. )
  50. type AddressInfo struct {
  51. ID string `json:"id"`
  52. Family AddressFamily `json:"address_family"`
  53. Public bool `json:"public"`
  54. Management bool `json:"management"`
  55. Address net.IP `json:"address"`
  56. NetworkMask net.IP `json:"netmask"`
  57. Gateway net.IP `json:"gateway"`
  58. NetworkBits int `json:"cidr"`
  59. // These are available, but not really needed:
  60. // Network net.IP `json:"network"`
  61. }
  62. type BondingMode int
  63. const (
  64. BondingBalanceRR = BondingMode(0)
  65. BondingActiveBackup = BondingMode(1)
  66. BondingBalanceXOR = BondingMode(2)
  67. BondingBroadcast = BondingMode(3)
  68. BondingLACP = BondingMode(4)
  69. BondingBalanceTLB = BondingMode(5)
  70. BondingBalanceALB = BondingMode(6)
  71. )
  72. var bondingModeStrings = map[BondingMode]string{
  73. BondingBalanceRR: "balance-rr",
  74. BondingActiveBackup: "active-backup",
  75. BondingBalanceXOR: "balance-xor",
  76. BondingBroadcast: "broadcast",
  77. BondingLACP: "802.3ad",
  78. BondingBalanceTLB: "balance-tlb",
  79. BondingBalanceALB: "balance-alb",
  80. }
  81. func (m BondingMode) String() string {
  82. if str, ok := bondingModeStrings[m]; ok {
  83. return str
  84. }
  85. return fmt.Sprintf("%d", m)
  86. }
  87. type CurrentDevice struct {
  88. ID string `json:"id"`
  89. Hostname string `json:"hostname"`
  90. IQN string `json:"iqn"`
  91. Plan string `json:"plan"`
  92. Facility string `json:"facility"`
  93. Tags []string `json:"tags"`
  94. SSHKeys []string `json:"ssh_keys"`
  95. OS OperatingSystem `json:"operating_system"`
  96. Network NetworkInfo `json:"network"`
  97. Volumes []VolumeInfo `json:"volume"`
  98. // This is available, but is actually inaccurate, currently:
  99. // APIBaseURL string `json:"api_url"`
  100. }
  101. type InterfaceInfo struct {
  102. Name string `json:"name"`
  103. MAC string `json:"mac"`
  104. }
  105. func (i *InterfaceInfo) ParseMAC() (net.HardwareAddr, error) {
  106. return net.ParseMAC(i.MAC)
  107. }
  108. type NetworkInfo struct {
  109. Interfaces []InterfaceInfo `json:"interfaces"`
  110. Addresses []AddressInfo `json:"addresses"`
  111. Bonding struct {
  112. Mode BondingMode `json:"mode"`
  113. } `json:"bonding"`
  114. }
  115. func (n *NetworkInfo) BondingMode() BondingMode {
  116. return n.Bonding.Mode
  117. }
  118. type OperatingSystem struct {
  119. Slug string `json:"slug"`
  120. Distro string `json:"distro"`
  121. Version string `json:"version"`
  122. }
  123. type VolumeInfo struct {
  124. Name string `json:"name"`
  125. IQN string `json:"iqn"`
  126. IPs []net.IP `json:"ips"`
  127. Capacity struct {
  128. Size int `json:"size,string"`
  129. Unit string `json:"unit"`
  130. } `json:"capacity"`
  131. }