metadata.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package metadata
  2. import (
  3. "fmt"
  4. "net/http"
  5. "os"
  6. "strings"
  7. "time"
  8. "k8s.io/klog/v2"
  9. )
  10. const metadataServiceTimeout = 5 * time.Second
  11. type CloudProvider string
  12. const (
  13. CloudProviderAWS CloudProvider = "AWS"
  14. CloudProviderGCP CloudProvider = "GCP"
  15. CloudProviderAzure CloudProvider = "Azure"
  16. CloudProviderHetzner CloudProvider = "Hetzner"
  17. CloudProviderDigitalOcean CloudProvider = "DigitalOcean"
  18. CloudProviderUnknown CloudProvider = ""
  19. )
  20. type CloudMetadata struct {
  21. Provider CloudProvider
  22. AccountId string
  23. InstanceId string
  24. InstanceType string
  25. LifeCycle string
  26. Region string
  27. AvailabilityZone string
  28. AvailabilityZoneId string
  29. LocalIPv4 string
  30. PublicIPv4 string
  31. }
  32. func getCloudProvider() CloudProvider {
  33. if d, err := os.ReadFile("/sys/hypervisor/uuid"); err == nil { // AWS Xen instances
  34. if strings.HasPrefix(strings.ToLower(string(d)), "ec2") {
  35. return CloudProviderAWS
  36. }
  37. }
  38. if vendor, err := os.ReadFile("/sys/class/dmi/id/board_vendor"); err == nil {
  39. switch strings.TrimSpace(string(vendor)) {
  40. case "Amazon EC2":
  41. return CloudProviderAWS
  42. case "Google":
  43. return CloudProviderGCP
  44. case "Microsoft Corporation":
  45. return CloudProviderAzure
  46. case "DigitalOcean":
  47. return CloudProviderDigitalOcean
  48. }
  49. }
  50. if vendor, err := os.ReadFile("/sys/class/dmi/id/sys_vendor"); err == nil {
  51. if strings.TrimSpace(string(vendor)) == "Hetzner" {
  52. return CloudProviderHetzner
  53. }
  54. }
  55. return CloudProviderUnknown
  56. }
  57. func GetInstanceMetadata() *CloudMetadata {
  58. provider := getCloudProvider()
  59. klog.Infoln("cloud provider:", provider)
  60. switch provider {
  61. case CloudProviderAWS:
  62. return getAwsMetadata()
  63. case CloudProviderGCP:
  64. return getGcpMetadata()
  65. case CloudProviderAzure:
  66. return getAzureMetadata()
  67. case CloudProviderHetzner:
  68. return getHetznerMetadata()
  69. case CloudProviderDigitalOcean:
  70. return getDigitalOceanMetadata()
  71. }
  72. return nil
  73. }
  74. func httpCallWithTimeout(r *http.Request) (*http.Response, error) {
  75. client := http.DefaultClient
  76. client.Timeout = metadataServiceTimeout
  77. resp, err := client.Do(r)
  78. if err != nil {
  79. return nil, err
  80. }
  81. if resp.StatusCode != 200 {
  82. return nil, fmt.Errorf("metadata service response: %s", resp.Status)
  83. }
  84. return resp, nil
  85. }