You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
prometheus/discovery/ovhcloud/dedicated_server.go

164 lines
5.4 KiB

// Copyright 2021 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package ovhcloud
import (
"context"
"fmt"
"net/netip"
"net/url"
"path"
"strconv"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/ovh/go-ovh/ovh"
"github.com/prometheus/common/model"
"github.com/prometheus/prometheus/discovery/refresh"
"github.com/prometheus/prometheus/discovery/targetgroup"
)
const (
dedicatedServerAPIPath = "/dedicated/server"
dedicatedServerLabelPrefix = metaLabelPrefix + "dedicated_server_"
)
// dedicatedServer struct from API. Also contains IP addresses that are fetched
// independently.
type dedicatedServer struct {
State string `json:"state"`
ips []netip.Addr
CommercialRange string `json:"commercialRange"`
LinkSpeed int `json:"linkSpeed"`
Rack string `json:"rack"`
NoIntervention bool `json:"noIntervention"`
Os string `json:"os"`
SupportLevel string `json:"supportLevel"`
ServerID int64 `json:"serverId"`
Reverse string `json:"reverse"`
Datacenter string `json:"datacenter"`
Name string `json:"name"`
}
type dedicatedServerDiscovery struct {
*refresh.Discovery
config *SDConfig
logger log.Logger
}
func newDedicatedServerDiscovery(conf *SDConfig, logger log.Logger) *dedicatedServerDiscovery {
return &dedicatedServerDiscovery{config: conf, logger: logger}
}
func getDedicatedServerList(client *ovh.Client) ([]string, error) {
var dedicatedListName []string
err := client.Get(dedicatedServerAPIPath, &dedicatedListName)
if err != nil {
return nil, err
}
return dedicatedListName, nil
}
func getDedicatedServerDetails(client *ovh.Client, serverName string) (*dedicatedServer, error) {
var dedicatedServerDetails dedicatedServer
err := client.Get(path.Join(dedicatedServerAPIPath, url.QueryEscape(serverName)), &dedicatedServerDetails)
if err != nil {
return nil, err
}
var ips []string
err = client.Get(path.Join(dedicatedServerAPIPath, url.QueryEscape(serverName), "ips"), &ips)
if err != nil {
return nil, err
}
parsedIPs, err := parseIPList(ips)
if err != nil {
return nil, err
}
dedicatedServerDetails.ips = parsedIPs
return &dedicatedServerDetails, nil
}
func (d *dedicatedServerDiscovery) getService() string {
return "dedicated_server"
}
func (d *dedicatedServerDiscovery) getSource() string {
return fmt.Sprintf("%s_%s", d.config.Name(), d.getService())
}
func (d *dedicatedServerDiscovery) refresh(context.Context) ([]*targetgroup.Group, error) {
client, err := createClient(d.config)
if err != nil {
return nil, err
}
var dedicatedServerDetailedList []dedicatedServer
dedicatedServerList, err := getDedicatedServerList(client)
if err != nil {
return nil, err
}
for _, dedicatedServerName := range dedicatedServerList {
dedicatedServer, err := getDedicatedServerDetails(client, dedicatedServerName)
if err != nil {
err := level.Warn(d.logger).Log("msg", fmt.Sprintf("%s: Could not get details of %s", d.getSource(), dedicatedServerName), "err", err.Error())
if err != nil {
return nil, err
}
continue
}
dedicatedServerDetailedList = append(dedicatedServerDetailedList, *dedicatedServer)
}
var targets []model.LabelSet
for _, server := range dedicatedServerDetailedList {
var ipv4, ipv6 string
for _, ip := range server.ips {
if ip.Is4() {
ipv4 = ip.String()
}
if ip.Is6() {
ipv6 = ip.String()
}
}
defaultIP := ipv4
if defaultIP == "" {
defaultIP = ipv6
}
labels := model.LabelSet{
model.AddressLabel: model.LabelValue(defaultIP),
model.InstanceLabel: model.LabelValue(server.Name),
dedicatedServerLabelPrefix + "state": model.LabelValue(server.State),
dedicatedServerLabelPrefix + "commercial_range": model.LabelValue(server.CommercialRange),
dedicatedServerLabelPrefix + "link_speed": model.LabelValue(strconv.Itoa(server.LinkSpeed)),
dedicatedServerLabelPrefix + "rack": model.LabelValue(server.Rack),
dedicatedServerLabelPrefix + "no_intervention": model.LabelValue(strconv.FormatBool(server.NoIntervention)),
dedicatedServerLabelPrefix + "os": model.LabelValue(server.Os),
dedicatedServerLabelPrefix + "support_level": model.LabelValue(server.SupportLevel),
dedicatedServerLabelPrefix + "server_id": model.LabelValue(strconv.FormatInt(server.ServerID, 10)),
dedicatedServerLabelPrefix + "reverse": model.LabelValue(server.Reverse),
dedicatedServerLabelPrefix + "datacenter": model.LabelValue(server.Datacenter),
dedicatedServerLabelPrefix + "name": model.LabelValue(server.Name),
dedicatedServerLabelPrefix + "ipv4": model.LabelValue(ipv4),
dedicatedServerLabelPrefix + "ipv6": model.LabelValue(ipv6),
}
targets = append(targets, labels)
}
return []*targetgroup.Group{{Source: d.getSource(), Targets: targets}}, nil
}