package metadata import ( "fmt" "net/http" "os" "strings" "time" "k8s.io/klog/v2" ) const metadataServiceTimeout = 5 * time.Second type CloudProvider string const ( CloudProviderAWS CloudProvider = "AWS" CloudProviderGCP CloudProvider = "GCP" CloudProviderAzure CloudProvider = "Azure" CloudProviderHetzner CloudProvider = "Hetzner" CloudProviderDigitalOcean CloudProvider = "DigitalOcean" CloudProviderUnknown CloudProvider = "" ) type CloudMetadata struct { Provider CloudProvider AccountId string InstanceId string InstanceType string LifeCycle string Region string AvailabilityZone string AvailabilityZoneId string LocalIPv4 string PublicIPv4 string } func getCloudProvider() CloudProvider { if d, err := os.ReadFile("/sys/hypervisor/uuid"); err == nil { // AWS Xen instances if strings.HasPrefix(strings.ToLower(string(d)), "ec2") { return CloudProviderAWS } } if vendor, err := os.ReadFile("/sys/class/dmi/id/board_vendor"); err == nil { switch strings.TrimSpace(string(vendor)) { case "Amazon EC2": return CloudProviderAWS case "Google": return CloudProviderGCP case "Microsoft Corporation": return CloudProviderAzure case "DigitalOcean": return CloudProviderDigitalOcean } } if vendor, err := os.ReadFile("/sys/class/dmi/id/sys_vendor"); err == nil { if strings.TrimSpace(string(vendor)) == "Hetzner" { return CloudProviderHetzner } } return CloudProviderUnknown } func GetInstanceMetadata() *CloudMetadata { provider := getCloudProvider() klog.Infoln("cloud provider:", provider) switch provider { case CloudProviderAWS: return getAwsMetadata() case CloudProviderGCP: return getGcpMetadata() case CloudProviderAzure: return getAzureMetadata() case CloudProviderHetzner: return getHetznerMetadata() case CloudProviderDigitalOcean: return getDigitalOceanMetadata() } return nil } func httpCallWithTimeout(r *http.Request) (*http.Response, error) { client := http.DefaultClient client.Timeout = metadataServiceTimeout resp, err := client.Do(r) if err != nil { return nil, err } if resp.StatusCode != 200 { return nil, fmt.Errorf("metadata service response: %s", resp.Status) } return resp, nil }