mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-01 14:47:38 +00:00
189 lines
6.2 KiB
Go
189 lines
6.2 KiB
Go
|
package hetzner
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
|
||
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promscrape/discoveryutils"
|
||
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promutils"
|
||
|
)
|
||
|
|
||
|
// HcloudServerList represents a list of servers from Hetzner Cloud API.
|
||
|
type HcloudServerList struct {
|
||
|
Servers []HcloudServer `json:"servers"`
|
||
|
}
|
||
|
|
||
|
// HcloudServer represents the structure of server data.
|
||
|
type HcloudServer struct {
|
||
|
ID int `json:"id"`
|
||
|
Name string `json:"name"`
|
||
|
Status string `json:"status"`
|
||
|
PublicNet PublicNet `json:"public_net,omitempty"`
|
||
|
PrivateNet []PrivateNet `json:"private_net,omitempty"`
|
||
|
ServerType ServerType `json:"server_type"`
|
||
|
Datacenter Datacenter `json:"datacenter"`
|
||
|
Image Image `json:"image"`
|
||
|
Labels map[string]string `json:"labels"`
|
||
|
}
|
||
|
|
||
|
type Datacenter struct {
|
||
|
Name string `json:"name"`
|
||
|
Location DatacenterLocation `json:"location"`
|
||
|
}
|
||
|
|
||
|
// DatacenterLocation represents the datacenter information.
|
||
|
type DatacenterLocation struct {
|
||
|
Name string `json:"name"`
|
||
|
NetworkZone string `json:"network_zone"`
|
||
|
}
|
||
|
|
||
|
// Image represents the image information.
|
||
|
type Image struct {
|
||
|
Name string `json:"name"`
|
||
|
Description string `json:"description"`
|
||
|
OsFlavor string `json:"os_flavor"`
|
||
|
OsVersion string `json:"os_version"`
|
||
|
}
|
||
|
|
||
|
// PublicNet represents the public network information.
|
||
|
type PublicNet struct {
|
||
|
IPv4 IPv4 `json:"ipv4"`
|
||
|
IPv6 IPv6 `json:"ipv6"`
|
||
|
}
|
||
|
|
||
|
// PrivateNet represents the private network information.
|
||
|
type PrivateNet struct {
|
||
|
ID int `json:"network"`
|
||
|
IP string `json:"ip"`
|
||
|
}
|
||
|
|
||
|
// IPv4 represents the IPv4 information.
|
||
|
type IPv4 struct {
|
||
|
IP string `json:"ip"`
|
||
|
}
|
||
|
|
||
|
// IPv6 represents the IPv6 information.
|
||
|
type IPv6 struct {
|
||
|
IP string `json:"ip"`
|
||
|
}
|
||
|
|
||
|
// ServerType represents the server type information.
|
||
|
type ServerType struct {
|
||
|
Name string `json:"name"`
|
||
|
Cores int `json:"cores"`
|
||
|
CpuType string `json:"cpu_type"`
|
||
|
Memory float32 `json:"memory"`
|
||
|
Disk int `json:"disk"`
|
||
|
}
|
||
|
|
||
|
// HcloudNetwork represents the hetzner cloud network information.
|
||
|
type HcloudNetwork struct {
|
||
|
Name string `json:"name"`
|
||
|
ID int `json:"id"`
|
||
|
}
|
||
|
|
||
|
type HcloudNetworksList struct {
|
||
|
Networks []HcloudNetwork `json:"networks"`
|
||
|
}
|
||
|
|
||
|
// getHcloudServerLabels returns labels for hcloud servers obtained from the given cfg
|
||
|
func getHcloudServerLabels(cfg *apiConfig) ([]*promutils.Labels, error) {
|
||
|
networks, err := getHcloudNetworks(cfg)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
servers, err := getServers(cfg)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
var ms []*promutils.Labels
|
||
|
for _, server := range servers.Servers {
|
||
|
ms = server.appendTargetLabels(ms, cfg.port, networks)
|
||
|
}
|
||
|
return ms, nil
|
||
|
}
|
||
|
|
||
|
// getHcloudNetworks returns hcloud networks obtained from the given cfg
|
||
|
func getHcloudNetworks(cfg *apiConfig) (*HcloudNetworksList, error) {
|
||
|
n, err := cfg.client.GetAPIResponse("/networks")
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("cannot query hcloud api for networks: %w", err)
|
||
|
}
|
||
|
networks, err := parseHcloudNetworksList(n)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("cannot unmarshal HcloudServerList from %q: %w", n, err)
|
||
|
}
|
||
|
return networks, nil
|
||
|
}
|
||
|
|
||
|
// getServers returns hcloud servers obtained from the given cfg
|
||
|
func getServers(cfg *apiConfig) (*HcloudServerList, error) {
|
||
|
s, err := cfg.client.GetAPIResponse("/servers")
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("cannot query hcloud api for servers: %w", err)
|
||
|
}
|
||
|
servers, err := parseHcloudServerList(s)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return servers, nil
|
||
|
}
|
||
|
|
||
|
// parseHcloudNetworks parses HcloudNetworksList from data.
|
||
|
func parseHcloudNetworksList(data []byte) (*HcloudNetworksList, error) {
|
||
|
var networks HcloudNetworksList
|
||
|
err := json.Unmarshal(data, &networks)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("cannot unmarshal HcloudNetworksList from %q: %w", data, err)
|
||
|
}
|
||
|
return &networks, nil
|
||
|
}
|
||
|
|
||
|
// parseHcloudServerList parses HcloudServerList from data.
|
||
|
func parseHcloudServerList(data []byte) (*HcloudServerList, error) {
|
||
|
var servers HcloudServerList
|
||
|
err := json.Unmarshal(data, &servers)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("cannot unmarshal HcloudServerList from %q: %w", data, err)
|
||
|
}
|
||
|
return &servers, nil
|
||
|
}
|
||
|
|
||
|
func (server *HcloudServer) appendTargetLabels(ms []*promutils.Labels, port int, networks *HcloudNetworksList) []*promutils.Labels {
|
||
|
addr := discoveryutils.JoinHostPort(server.PublicNet.IPv4.IP, port)
|
||
|
m := promutils.NewLabels(24)
|
||
|
m.Add("__address__", addr)
|
||
|
m.Add("__meta_hetzner_server_id", fmt.Sprintf("%d", server.ID))
|
||
|
m.Add("__meta_hetzner_server_name", server.Name)
|
||
|
m.Add("__meta_hetzner_server_status", server.Status)
|
||
|
m.Add("__meta_hetzner_public_ipv4", server.PublicNet.IPv4.IP)
|
||
|
m.Add("__meta_hetzner_public_ipv6_network", server.PublicNet.IPv6.IP)
|
||
|
m.Add("__meta_hetzner_datacenter", server.Datacenter.Name)
|
||
|
m.Add("__meta_hetzner_hcloud_image_name", server.Image.Name)
|
||
|
m.Add("__meta_hetzner_hcloud_image_description", server.Image.Description)
|
||
|
m.Add("__meta_hetzner_hcloud_image_os_flavor", server.Image.OsFlavor)
|
||
|
m.Add("__meta_hetzner_hcloud_image_os_version", server.Image.OsVersion)
|
||
|
m.Add("__meta_hetzner_hcloud_datacenter_location", server.Datacenter.Location.Name)
|
||
|
m.Add("__meta_hetzner_hcloud_datacenter_location_network_zone", server.Datacenter.Location.NetworkZone)
|
||
|
m.Add("__meta_hetzner_hcloud_server_type", server.ServerType.Name)
|
||
|
m.Add("__meta_hetzner_hcloud_cpu_cores", fmt.Sprintf("%d", server.ServerType.Cores))
|
||
|
m.Add("__meta_hetzner_hcloud_cpu_type", server.ServerType.CpuType)
|
||
|
m.Add("__meta_hetzner_hcloud_memory_size_gb", fmt.Sprintf("%d", int(server.ServerType.Memory)))
|
||
|
m.Add("__meta_hetzner_hcloud_disk_size_gb", fmt.Sprintf("%d", server.ServerType.Disk))
|
||
|
|
||
|
for _, privateNet := range server.PrivateNet {
|
||
|
for _, network := range networks.Networks {
|
||
|
if privateNet.ID == network.ID {
|
||
|
m.Add(discoveryutils.SanitizeLabelName("__meta_hetzner_hcloud_private_ipv4_"+network.Name), privateNet.IP)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
for labelKey, labelValue := range server.Labels {
|
||
|
m.Add(discoveryutils.SanitizeLabelName("__meta_hetzner_hcloud_label_"+labelKey), labelValue)
|
||
|
m.Add(discoveryutils.SanitizeLabelName("__meta_hetzner_hcloud_labelpresent_"+labelKey), fmt.Sprintf("%t", true))
|
||
|
|
||
|
}
|
||
|
ms = append(ms, m)
|
||
|
return ms
|
||
|
}
|