Skip to content

Commit

Permalink
add support for Hetzner cloud metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
def committed May 3, 2022
1 parent 3266fed commit 10b9282
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 18 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,15 @@ The [container_oom_kills_total](https://coroot.com/docs/metrics/node-agent#conta

If a node is a cloud instance, the agent identifies a cloud provider and collects additional information using the related metadata services.

Supported cloud providers: [AWS](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html), [GCP](https://cloud.google.com/compute/docs/metadata/overview), [Azure](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/instance-metadata-service?tabs=linux)
Supported cloud providers: [AWS](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html), [GCP](https://cloud.google.com/compute/docs/metadata/overview), [Azure](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/instance-metadata-service?tabs=linux), [Hetzner](https://docs.hetzner.cloud/#server-metadata)

Collected info:
* AccountID
* InstanceID
* Instance/machine type
* Region
* AvailabilityZone + AvailabilityZoneId (AWS only)
* AvailabilityZone
* AvailabilityZoneId (AWS only)
* LifeCycle: on-demand/spot (AWS and GCP only)
* Private & Public IP addresses

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ require (
golang.org/x/net v0.0.0-20210913180222-943fd674d43e
golang.org/x/sys v0.0.0-20210915083310-ed5796bab164
gopkg.in/alecthomas/kingpin.v2 v2.2.6
gopkg.in/yaml.v2 v2.4.0
inet.af/netaddr v0.0.0-20210903134321-85fa6c94624e
k8s.io/klog/v2 v2.20.0
)
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,7 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
21 changes: 5 additions & 16 deletions node/metadata/azure.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,29 +35,18 @@ type azureInstanceMetadata struct {
}

func getAzureMetadata() *CloudMetadata {
req, err := http.NewRequest(http.MethodGet, azureEndpoint, nil)
if err != nil {
klog.Errorln(err)
return nil
}
req.Header.Add("Metadata", "True")
q := req.URL.Query()
r, _ := http.NewRequest(http.MethodGet, azureEndpoint, nil)
r.Header.Add("Metadata", "True")
q := r.URL.Query()
q.Add("format", "json")
q.Add("api-version", "2021-05-01")
req.URL.RawQuery = q.Encode()
r.URL.RawQuery = q.Encode()

client := http.DefaultClient
client.Timeout = metadataServiceTimeout

resp, err := client.Do(req)
resp, err := httpGetWithTimeout(r)
if err != nil {
klog.Errorln(err)
return nil
}
if resp.StatusCode != 200 {
klog.Errorln("metadata service response:", resp.Status)
return nil
}
defer resp.Body.Close()

instanceMd := &azureInstanceMetadata{}
Expand Down
42 changes: 42 additions & 0 deletions node/metadata/hetzner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package metadata

import (
"gopkg.in/yaml.v2"
"k8s.io/klog/v2"
"net/http"
)

const hetznerInstanceMetadataURL = "http://169.254.169.254/hetzner/v1/metadata"

type hetznerInstanceMetadata struct {
AvailabilityZone string `yaml:"availability-zone"`
InstanceId string `yaml:"instance-id"`
PublicIPv4 string `yaml:"public-ipv4"`
LocalIPv4 string `yaml:"local-ipv4"`
Region string `yaml:"region"`
}

func getHetznerMetadata() *CloudMetadata {
r, _ := http.NewRequest(http.MethodGet, hetznerInstanceMetadataURL, nil)
resp, err := httpGetWithTimeout(r)
if err != nil {
klog.Errorln(err)
return nil
}
defer resp.Body.Close()
md := &hetznerInstanceMetadata{}
decoder := yaml.NewDecoder(resp.Body)
if err := decoder.Decode(md); err != nil {
klog.Errorln("failed to unmarshall response of Hetzner metadata service:", err)
return nil
}
res := &CloudMetadata{
Provider: CloudProviderHetzner,
InstanceId: md.InstanceId,
Region: md.Region,
AvailabilityZone: md.AvailabilityZone,
LocalIPv4: md.LocalIPv4,
PublicIPv4: md.PublicIPv4,
}
return res
}
24 changes: 24 additions & 0 deletions node/metadata/metadata.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package metadata

import (
"fmt"
"k8s.io/klog/v2"
"net/http"
"os"
"strings"
"time"
Expand All @@ -15,6 +17,7 @@ const (
CloudProviderAWS CloudProvider = "AWS"
CloudProviderGCP CloudProvider = "GCP"
CloudProviderAzure CloudProvider = "Azure"
CloudProviderHetzner CloudProvider = "Hetzner"
CloudProviderUnknown CloudProvider = ""
)

Expand Down Expand Up @@ -47,6 +50,11 @@ func getCloudProvider() CloudProvider {
return CloudProviderAzure
}
}
if vendor, err := os.ReadFile("/sys/class/dmi/id/sys_vendor"); err == nil {
if strings.TrimSpace(string(vendor)) == "Hetzner" {
return CloudProviderHetzner
}
}
return CloudProviderUnknown
}

Expand All @@ -60,6 +68,22 @@ func GetInstanceMetadata() *CloudMetadata {
return getGcpMetadata()
case CloudProviderAzure:
return getAzureMetadata()
case CloudProviderHetzner:
return getHetznerMetadata()
}
return nil
}

func httpGetWithTimeout(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 {
klog.Errorln()
return nil, fmt.Errorf("metadata service response: %s", resp.Status)
}
return resp, nil
}

0 comments on commit 10b9282

Please sign in to comment.