VictoriaMetrics/lib/promscrape/discovery/hetzner/robot.go

97 lines
2.9 KiB
Go

package hetzner
import (
"encoding/json"
"fmt"
"net"
"strings"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promscrape/discoveryutils"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promutils"
)
type robotServersList struct {
Servers []RobotServerResponse
}
// RobotServerResponse represents hetzner robot server response.
type RobotServerResponse struct {
Server RobotServer `json:"server"`
}
// RobotServer represents the structure of hetzner robot server data.
type RobotServer struct {
ServerIP string `json:"server_ip"`
ServerIPV6 string `json:"server_ipv6_net"`
ServerNumber int `json:"server_number"`
ServerName string `json:"server_name"`
DC string `json:"dc"`
Status string `json:"status"`
Product string `json:"product"`
Canceled bool `json:"cancelled"`
Subnet []RobotSubnet `json:"subnet"`
}
// RobotSubnet represents the structure of hetzner robot subnet data.
type RobotSubnet struct {
IP string `json:"ip"`
Mask string `json:"mask"`
}
func getRobotServerLabels(cfg *apiConfig) ([]*promutils.Labels, error) {
servers, err := getRobotServers(cfg)
if err != nil {
return nil, err
}
var ms []*promutils.Labels
for _, server := range servers.Servers {
ms = server.appendTargetLabels(ms, cfg.port)
}
return ms, nil
}
// parseRobotServersList parses robotServersList from data.
func parseRobotServersList(data []byte) (*robotServersList, error) {
var servers robotServersList
err := json.Unmarshal(data, &servers.Servers)
if err != nil {
return nil, fmt.Errorf("cannot unmarshal robotServersList from %q: %w", data, err)
}
return &servers, nil
}
func getRobotServers(cfg *apiConfig) (*robotServersList, error) {
s, err := cfg.client.GetAPIResponse("/server")
if err != nil {
return nil, fmt.Errorf("cannot query hetzner robot api for servers: %w", err)
}
servers, err := parseRobotServersList(s)
if err != nil {
return nil, err
}
return servers, nil
}
func (server *RobotServerResponse) appendTargetLabels(ms []*promutils.Labels, port int) []*promutils.Labels {
addr := discoveryutils.JoinHostPort(server.Server.ServerIP, port)
m := promutils.NewLabels(16)
m.Add("__address__", addr)
m.Add("__meta_hetzner_server_id", fmt.Sprintf("%d", server.Server.ServerNumber))
m.Add("__meta_hetzner_server_name", server.Server.ServerName)
m.Add("__meta_hetzner_server_status", server.Server.Status)
m.Add("__meta_hetzner_public_ipv4", server.Server.ServerIP)
m.Add("__meta_hetzner_datacenter", strings.ToLower(server.Server.DC))
m.Add("__meta_hetzner_robot_product", server.Server.Product)
m.Add("__meta_hetzner_robot_cancelled", fmt.Sprintf("%t", server.Server.Canceled))
for _, subnet := range server.Server.Subnet {
ip := net.ParseIP(subnet.IP)
if ip.To4() == nil {
m.Add("__meta_hetzner_public_ipv6_network", fmt.Sprintf("%s/%s", subnet.IP, subnet.Mask))
break
}
}
ms = append(ms, m)
return ms
}