vultr integration

Signed-off-by: David Dymko <dymkod@gmail.com>
This commit is contained in:
David Dymko 2022-05-24 12:03:49 -04:00 committed by Julien Pivotto
parent d11c418102
commit 3ef153b00c
11 changed files with 662 additions and 3 deletions

View file

@ -51,6 +51,7 @@ import (
"github.com/prometheus/prometheus/discovery/targetgroup" "github.com/prometheus/prometheus/discovery/targetgroup"
"github.com/prometheus/prometheus/discovery/triton" "github.com/prometheus/prometheus/discovery/triton"
"github.com/prometheus/prometheus/discovery/uyuni" "github.com/prometheus/prometheus/discovery/uyuni"
"github.com/prometheus/prometheus/discovery/vultr"
"github.com/prometheus/prometheus/discovery/xds" "github.com/prometheus/prometheus/discovery/xds"
"github.com/prometheus/prometheus/discovery/zookeeper" "github.com/prometheus/prometheus/discovery/zookeeper"
"github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/labels"
@ -1020,6 +1021,32 @@ var expectedConf = &Config{
}, },
}, },
}, },
{
JobName: "vultr",
HonorTimestamps: true,
ScrapeInterval: model.Duration(15 * time.Second),
ScrapeTimeout: DefaultGlobalConfig.ScrapeTimeout,
MetricsPath: DefaultScrapeConfig.MetricsPath,
Scheme: DefaultScrapeConfig.Scheme,
HTTPClientConfig: config.DefaultHTTPClientConfig,
ServiceDiscoveryConfigs: discovery.Configs{
&vultr.SDConfig{
HTTPClientConfig: config.HTTPClientConfig{
Authorization: &config.Authorization{
Type: "Bearer",
Credentials: "abcdef",
},
FollowRedirects: true,
EnableHTTP2: true,
},
Port: 80,
RefreshInterval: model.Duration(60 * time.Second),
},
},
},
}, },
AlertingConfig: AlertingConfig{ AlertingConfig: AlertingConfig{
AlertmanagerConfigs: []*AlertmanagerConfig{ AlertmanagerConfigs: []*AlertmanagerConfig{
@ -1117,7 +1144,7 @@ func TestElideSecrets(t *testing.T) {
yamlConfig := string(config) yamlConfig := string(config)
matches := secretRe.FindAllStringIndex(yamlConfig, -1) matches := secretRe.FindAllStringIndex(yamlConfig, -1)
require.Equal(t, 17, len(matches), "wrong number of secret matches found") require.Equal(t, 18, len(matches), "wrong number of secret matches found")
require.NotContains(t, yamlConfig, "mysecret", require.NotContains(t, yamlConfig, "mysecret",
"yaml marshal reveals authentication credentials.") "yaml marshal reveals authentication credentials.")
} }

View file

@ -373,6 +373,11 @@ scrape_configs:
authorization: authorization:
credentials: abcdef credentials: abcdef
- job_name: vultr
vultr_sd_configs:
- authorization:
credentials: abcdef
alerting: alerting:
alertmanagers: alertmanagers:
- scheme: https - scheme: https

View file

@ -36,6 +36,7 @@ import (
_ "github.com/prometheus/prometheus/discovery/scaleway" // register scaleway _ "github.com/prometheus/prometheus/discovery/scaleway" // register scaleway
_ "github.com/prometheus/prometheus/discovery/triton" // register triton _ "github.com/prometheus/prometheus/discovery/triton" // register triton
_ "github.com/prometheus/prometheus/discovery/uyuni" // register uyuni _ "github.com/prometheus/prometheus/discovery/uyuni" // register uyuni
_ "github.com/prometheus/prometheus/discovery/vultr" // register vultr
_ "github.com/prometheus/prometheus/discovery/xds" // register xds _ "github.com/prometheus/prometheus/discovery/xds" // register xds
_ "github.com/prometheus/prometheus/discovery/zookeeper" // register zookeeper _ "github.com/prometheus/prometheus/discovery/zookeeper" // register zookeeper
) )

View file

@ -0,0 +1,170 @@
// Copyright 2022 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 vultr
import (
"fmt"
"net/http"
"net/http/httptest"
"testing"
)
// SDMock is the interface for the Vultr mock
type SDMock struct {
t *testing.T
Server *httptest.Server
Mux *http.ServeMux
}
// NewSDMock returns a new SDMock.
func NewSDMock(t *testing.T) *SDMock {
return &SDMock{
t: t,
}
}
// Endpoint returns the URI to the mock server
func (m *SDMock) Endpoint() string {
return m.Server.URL + "/"
}
// Setup creates the mock server
func (m *SDMock) Setup() {
m.Mux = http.NewServeMux()
m.Server = httptest.NewServer(m.Mux)
}
// ShutdownServer creates the mock server
func (m *SDMock) ShutdownServer() {
m.Server.Close()
}
const APIKey = "ABCBTDG35OTGH2UKCC3S6CNMDUPCN3ZWSGFQ"
// HandleInstanceList mocks vultr instances list.
func (m *SDMock) HandleInstanceList() {
m.Mux.HandleFunc("/v2/instances", func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Authorization") != fmt.Sprintf("Bearer %s", APIKey) {
w.WriteHeader(http.StatusForbidden)
return
}
w.Header().Add("content-type", "application/json; charset=utf-8")
w.WriteHeader(http.StatusOK)
fmt.Fprint(w, `
{
"instances": [
{
"id": "dbdbd38c-9884-4c92-95fe-899e50dee717",
"os": "Marketplace",
"ram": 4096,
"disk": 128,
"main_ip": "149.28.234.27",
"vcpu_count": 2,
"region": "ewr",
"plan": "vhf-2c-4gb",
"date_created": "2022-03-10T02:25:30+00:00",
"status": "active",
"allowed_bandwidth": 3000,
"netmask_v4": "255.255.254.0",
"gateway_v4": "149.28.234.1",
"power_status": "running",
"server_status": "ok",
"v6_network": "",
"v6_main_ip": "",
"v6_network_size": 0,
"label": "np-2-eae38a19b0f3",
"internal_ip": "10.1.96.5",
"kvm": "https://my.vultr.com/subs/vps/novnc/api.php?data=djJ8Q2k2NlVpNUlZNE5kM3NZMWdBNzFKUkVadDBDU3ItTEJ8-yNWBdMn1AWPqX-EnpTVbA1qBeP0txBZbahSOh3UtHIL2p0fZKEdFJwFNjWtvBKC9BGvJkoJdWBoo7hF-6RzavdUKPD3KIU5xD_T6keV8X-PPukPgXMuSUaAqurAuJvwAWXcTcodBjaIH961xgbvfkFyqVl0ZgHf3ErZQE-EmpZ0Jc3uF1DO2McJ4UL8KUvHLwa-ZDUZ_AtWJjQWsjNkxjvOiA",
"hostname": "np-2-eae38a19b0f3",
"os_id": 426,
"app_id": 0,
"image_id": "vke-worker",
"firewall_group_id": "",
"features": ["backups"],
"tags": ["tag1", "tag2", "tag3"]
},
{
"id": "fccb117c-62f7-4b17-995d-a8e56dd30b33",
"os": "Marketplace",
"ram": 4096,
"disk": 128,
"main_ip": "45.63.1.222",
"vcpu_count": 2,
"region": "ewr",
"plan": "vhf-2c-4gb",
"date_created": "2022-03-10T02:25:32+00:00",
"status": "active",
"allowed_bandwidth": 3000,
"netmask_v4": "255.255.254.0",
"gateway_v4": "45.63.0.1",
"power_status": "running",
"server_status": "ok",
"v6_network": "",
"v6_main_ip": "",
"v6_network_size": 0,
"label": "np-2-fd0714b5fe42",
"internal_ip": "10.1.96.6",
"kvm": "https://my.vultr.com/subs/vps/novnc/api.php?data=djJ8R0tzbmI0VWVfSDR6VE51Q0FGUTBCamwyTFNzZDNkVTF8Zwm93t6L2BLTYSNmM0g0Ppf43r71aIbqLiJCx6_1NuCugUqIKz8POshH91vi6XXDorpb3hYTk8RrJWQbaFMak7XbbfMObzsrFxKAQUVGfbjTBIHCKftxNIXeQOp1fEIDa3p-vkfSxEpx6ZX8nChGYYSVuOjS1twV6oI_IKtHXKdFJiVFz0Unay_K3HuXW_H2wrYSjmAChloR-eA1jSmBXLccJQ",
"hostname": "np-2-fd0714b5fe42",
"os_id": 426,
"app_id": 0,
"image_id": "vke-worker",
"firewall_group_id": "",
"features": [],
"tags": []
},
{
"id": "c4e58767-f61b-4c5e-9bce-43761cc04868",
"os": "Marketplace",
"ram": 4096,
"disk": 128,
"main_ip": "149.28.237.151",
"vcpu_count": 2,
"region": "ewr",
"plan": "vhf-2c-4gb",
"date_created": "2022-03-10T02:25:33+00:00",
"status": "active",
"allowed_bandwidth": 3000,
"netmask_v4": "255.255.254.0",
"gateway_v4": "149.28.236.1",
"power_status": "running",
"server_status": "ok",
"v6_network": "",
"v6_main_ip": "",
"v6_network_size": 0,
"label": "np-2-d04e7829fa43",
"internal_ip": "10.1.96.7",
"kvm": "https://my.vultr.com/subs/vps/novnc/api.php?data=djJ8NFEzbFZmV2hOUWNrc2R4bndnckhFQTJ3ME1yWmxVeW98P-p-KeyNtP73wzVvuWZSOrV5PvQDiBmYyB3cp99btIy5nczmvX8DOGSChbEldk3idKNdFLQMIieWnpR5xU5K-dMYlL6n6oYv2u-rh8zxS6-8hQsSbL2OsoywNPoLpQ3xPkT9Rb-yPrZX4fDLbt8yPVKDHqHO0GB-TxVPemueovfkkUZMXSraAXgHtl1YgK2uLMQf1WBFVzgwnQ7MYcfMGGYFQw",
"hostname": "np-2-d04e7829fa43",
"os_id": 426,
"app_id": 0,
"image_id": "vke-worker",
"firewall_group_id": "",
"features": [],
"tags": []
}
],
"meta": {
"total": 3,
"links": {
"next": "",
"prev": ""
}
}
}
`)
})
}

212
discovery/vultr/vultr.go Normal file
View file

@ -0,0 +1,212 @@
// Copyright 2022 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 vultr
import (
"context"
"fmt"
"net"
"net/http"
"strconv"
"strings"
"time"
"github.com/go-kit/log"
"github.com/prometheus/common/config"
"github.com/prometheus/common/model"
"github.com/prometheus/common/version"
"github.com/vultr/govultr/v2"
"github.com/prometheus/prometheus/discovery"
"github.com/prometheus/prometheus/discovery/refresh"
"github.com/prometheus/prometheus/discovery/targetgroup"
)
const (
vultrInstanceLabel = model.MetaLabelPrefix + "vultr_instance_"
vultrInstanceLabelID = vultrInstanceLabel + "id"
vultrInstanceLabelLabel = vultrInstanceLabel + "label"
vultrInstanceLabelOS = vultrInstanceLabel + "os"
vultrInstanceLabelOSID = vultrInstanceLabel + "os_id"
vultrInstanceLabelRegion = vultrInstanceLabel + "region"
vultrInstanceLabelPlan = vultrInstanceLabel + "plan"
vultrInstanceLabelMainIP = vultrInstanceLabel + "main_ip"
vultrInstanceLabelMainIPV6 = vultrInstanceLabel + "main_ipv6"
vultrInstanceLabelInternalIP = vultrInstanceLabel + "internal_ip"
vultrInstanceLabelFeatures = vultrInstanceLabel + "features"
vultrInstanceLabelTags = vultrInstanceLabel + "tags"
vultrInstanceLabelHostname = vultrInstanceLabel + "hostname"
vultrInstanceLabelServerStatus = vultrInstanceLabel + "server_status"
vultrInstanceLabelVCPU = vultrInstanceLabel + "vcpu_count"
vultrInstanceLabelMemory = vultrInstanceLabel + "ram_bytes"
vultrInstanceLabelBandwidth = vultrInstanceLabel + "allowed_bandwidth_gb"
vultrInstanceLabelDisk = vultrInstanceLabel + "disk_gb"
separator = ","
)
// DefaultSDConfig is the default Vultr SD configuration.
var DefaultSDConfig = SDConfig{
Port: 80,
RefreshInterval: model.Duration(60 * time.Second),
HTTPClientConfig: config.DefaultHTTPClientConfig,
}
func init() {
discovery.RegisterConfig(&SDConfig{})
}
type SDConfig struct {
HTTPClientConfig config.HTTPClientConfig `yaml:",inline"`
RefreshInterval model.Duration `yaml:"refresh_interval"`
Port int `yaml:"port"`
}
// Name returns the name of the Config.
func (*SDConfig) Name() string { return "vultr" }
// NewDiscoverer returns a Discoverer for the Config.
func (c *SDConfig) NewDiscoverer(opts discovery.DiscovererOptions) (discovery.Discoverer, error) {
return NewDiscovery(c, opts.Logger)
}
// SetDirectory joins any relative file paths with dir.
func (c *SDConfig) SetDirectory(dir string) {
c.HTTPClientConfig.SetDirectory(dir)
}
// UnmarshalYAML implements the yaml.Unmarshaler interface.
func (c *SDConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
*c = DefaultSDConfig
type plain SDConfig
if err := unmarshal((*plain)(c)); err != nil {
return err
}
return c.HTTPClientConfig.Validate()
}
// Discovery periodically performs Vultr requests. It implements
// the Discoverer interface.
type Discovery struct {
*refresh.Discovery
client *govultr.Client
port int
}
// NewDiscovery returns a new Discovery which periodically refreshes its targets.
func NewDiscovery(conf *SDConfig, logger log.Logger) (*Discovery, error) {
d := &Discovery{
port: conf.Port,
}
rt, err := config.NewRoundTripperFromConfig(conf.HTTPClientConfig, "vultr_sd")
if err != nil {
return nil, err
}
d.client = govultr.NewClient(&http.Client{
Transport: rt,
Timeout: time.Duration(conf.RefreshInterval),
})
d.client.SetUserAgent(fmt.Sprintf("Prometheus/%s", version.Version))
if err != nil {
return nil, fmt.Errorf("error setting up vultr agent: %w", err)
}
d.Discovery = refresh.NewDiscovery(
logger,
"vultr",
time.Duration(conf.RefreshInterval),
d.refresh,
)
return d, nil
}
func (d *Discovery) refresh(ctx context.Context) ([]*targetgroup.Group, error) {
tg := &targetgroup.Group{
Source: "Vultr",
}
instances, err := d.listInstances(ctx)
if err != nil {
return nil, err
}
for _, instance := range instances {
labels := model.LabelSet{
vultrInstanceLabelID: model.LabelValue(instance.ID),
vultrInstanceLabelLabel: model.LabelValue(instance.Label),
vultrInstanceLabelOS: model.LabelValue(instance.Os),
vultrInstanceLabelOSID: model.LabelValue(strconv.Itoa(instance.OsID)),
vultrInstanceLabelRegion: model.LabelValue(instance.Region),
vultrInstanceLabelPlan: model.LabelValue(instance.Plan),
vultrInstanceLabelVCPU: model.LabelValue(strconv.Itoa(instance.VCPUCount)),
vultrInstanceLabelMemory: model.LabelValue(strconv.Itoa(instance.RAM)),
vultrInstanceLabelBandwidth: model.LabelValue(strconv.Itoa(instance.AllowedBandwidth)),
vultrInstanceLabelDisk: model.LabelValue(strconv.Itoa(instance.Disk)),
vultrInstanceLabelMainIP: model.LabelValue(instance.MainIP),
vultrInstanceLabelMainIPV6: model.LabelValue(instance.V6MainIP),
vultrInstanceLabelInternalIP: model.LabelValue(instance.InternalIP),
vultrInstanceLabelHostname: model.LabelValue(instance.Hostname),
vultrInstanceLabelServerStatus: model.LabelValue(instance.ServerStatus),
}
addr := net.JoinHostPort(instance.MainIP, strconv.FormatUint(uint64(d.port), 10))
labels[model.AddressLabel] = model.LabelValue(addr)
// We surround the separated list with the separator as well. This way regular expressions
// in relabeling rules don't have to consider feature positions.
if len(instance.Features) > 0 {
features := separator + strings.Join(instance.Features, separator) + separator
labels[vultrInstanceLabelFeatures] = model.LabelValue(features)
}
if len(instance.Tags) > 0 {
tags := separator + strings.Join(instance.Tags, separator) + separator
labels[vultrInstanceLabelTags] = model.LabelValue(tags)
}
tg.Targets = append(tg.Targets, labels)
}
return []*targetgroup.Group{tg}, nil
}
func (d *Discovery) listInstances(ctx context.Context) ([]govultr.Instance, error) {
var instances []govultr.Instance
listOptions := &govultr.ListOptions{
PerPage: 100,
}
for {
pagedInstances, meta, err := d.client.Instance.List(ctx, listOptions)
if err != nil {
return nil, err
}
instances = append(instances, pagedInstances...)
if meta.Links.Next == "" {
break
} else {
listOptions.Cursor = meta.Links.Next
continue
}
}
return instances, nil
}

View file

@ -0,0 +1,128 @@
// Copyright 2022 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 vultr
import (
"context"
"fmt"
"net/url"
"testing"
"github.com/go-kit/log"
"github.com/prometheus/common/model"
"github.com/stretchr/testify/require"
)
type VultrSDTestSuite struct {
Mock *SDMock
}
func (s *VultrSDTestSuite) TearDownSuite() {
s.Mock.ShutdownServer()
}
func (s *VultrSDTestSuite) SetupTest(t *testing.T) {
s.Mock = NewSDMock(t)
s.Mock.Setup()
s.Mock.HandleInstanceList()
}
func TestVultrSDRefresh(t *testing.T) {
sdMock := &VultrSDTestSuite{}
sdMock.SetupTest(t)
t.Cleanup(sdMock.TearDownSuite)
cfg := DefaultSDConfig
cfg.HTTPClientConfig.BearerToken = APIKey
d, err := NewDiscovery(&cfg, log.NewNopLogger())
require.NoError(t, err)
endpoint, err := url.Parse(sdMock.Mock.Endpoint())
require.NoError(t, err)
d.client.BaseURL = endpoint
ctx := context.Background()
tgs, err := d.refresh(ctx)
require.NoError(t, err)
require.Equal(t, 1, len(tgs))
tg := tgs[0]
require.NotNil(t, tg)
require.NotNil(t, tg.Targets)
require.Equal(t, 3, len(tg.Targets))
for i, k := range []model.LabelSet{
{
"__address__": model.LabelValue("149.28.234.27:80"),
"__meta_vultr_instance_id": model.LabelValue("dbdbd38c-9884-4c92-95fe-899e50dee717"),
"__meta_vultr_instance_label": model.LabelValue("np-2-eae38a19b0f3"),
"__meta_vultr_instance_os": model.LabelValue("Marketplace"),
"__meta_vultr_instance_os_id": model.LabelValue("426"),
"__meta_vultr_instance_region": model.LabelValue("ewr"),
"__meta_vultr_instance_plan": model.LabelValue("vhf-2c-4gb"),
"__meta_vultr_instance_main_ip": model.LabelValue("149.28.234.27"),
"__meta_vultr_instance_internal_ip": model.LabelValue("10.1.96.5"),
"__meta_vultr_instance_main_ipv6": model.LabelValue(""),
"__meta_vultr_instance_features": model.LabelValue(",backups,"),
"__meta_vultr_instance_tags": model.LabelValue(",tag1,tag2,tag3,"),
"__meta_vultr_instance_hostname": model.LabelValue("np-2-eae38a19b0f3"),
"__meta_vultr_instance_server_status": model.LabelValue("ok"),
"__meta_vultr_instance_vcpu_count": model.LabelValue("2"),
"__meta_vultr_instance_ram_bytes": model.LabelValue("4096"),
"__meta_vultr_instance_disk_gb": model.LabelValue("128"),
"__meta_vultr_instance_allowed_bandwidth_gb": model.LabelValue("3000"),
},
{
"__address__": model.LabelValue("45.63.1.222:80"),
"__meta_vultr_instance_id": model.LabelValue("fccb117c-62f7-4b17-995d-a8e56dd30b33"),
"__meta_vultr_instance_label": model.LabelValue("np-2-fd0714b5fe42"),
"__meta_vultr_instance_os": model.LabelValue("Marketplace"),
"__meta_vultr_instance_os_id": model.LabelValue("426"),
"__meta_vultr_instance_region": model.LabelValue("ewr"),
"__meta_vultr_instance_plan": model.LabelValue("vhf-2c-4gb"),
"__meta_vultr_instance_main_ip": model.LabelValue("45.63.1.222"),
"__meta_vultr_instance_internal_ip": model.LabelValue("10.1.96.6"),
"__meta_vultr_instance_main_ipv6": model.LabelValue(""),
"__meta_vultr_instance_hostname": model.LabelValue("np-2-fd0714b5fe42"),
"__meta_vultr_instance_server_status": model.LabelValue("ok"),
"__meta_vultr_instance_vcpu_count": model.LabelValue("2"),
"__meta_vultr_instance_ram_bytes": model.LabelValue("4096"),
"__meta_vultr_instance_disk_gb": model.LabelValue("128"),
"__meta_vultr_instance_allowed_bandwidth_gb": model.LabelValue("3000"),
},
{
"__address__": model.LabelValue("149.28.237.151:80"),
"__meta_vultr_instance_id": model.LabelValue("c4e58767-f61b-4c5e-9bce-43761cc04868"),
"__meta_vultr_instance_label": model.LabelValue("np-2-d04e7829fa43"),
"__meta_vultr_instance_os": model.LabelValue("Marketplace"),
"__meta_vultr_instance_os_id": model.LabelValue("426"),
"__meta_vultr_instance_region": model.LabelValue("ewr"),
"__meta_vultr_instance_plan": model.LabelValue("vhf-2c-4gb"),
"__meta_vultr_instance_main_ip": model.LabelValue("149.28.237.151"),
"__meta_vultr_instance_internal_ip": model.LabelValue("10.1.96.7"),
"__meta_vultr_instance_main_ipv6": model.LabelValue(""),
"__meta_vultr_instance_hostname": model.LabelValue("np-2-d04e7829fa43"),
"__meta_vultr_instance_server_status": model.LabelValue("ok"),
"__meta_vultr_instance_vcpu_count": model.LabelValue("2"),
"__meta_vultr_instance_ram_bytes": model.LabelValue("4096"),
"__meta_vultr_instance_disk_gb": model.LabelValue("128"),
"__meta_vultr_instance_allowed_bandwidth_gb": model.LabelValue("3000"),
},
} {
t.Run(fmt.Sprintf("item %d", i), func(t *testing.T) {
require.Equal(t, k, tg.Targets[i])
})
}
}

View file

@ -2538,6 +2538,83 @@ tls_config:
See [the Prometheus uyuni-sd configuration file](/documentation/examples/prometheus-uyuni.yml) See [the Prometheus uyuni-sd configuration file](/documentation/examples/prometheus-uyuni.yml)
for a practical example on how to set up Uyuni Prometheus configuration. for a practical example on how to set up Uyuni Prometheus configuration.
### `<vultr_sd_config>`
Vultr SD configurations allow retrieving scrape targets from [Vultr](https://www.vultr.com/).
This service discovery uses the main IPv4 address by default, which that be
changed with relabelling, as demonstrated in [the Prometheus vultr-sd
configuration file](/documentation/examples/prometheus-vultr.yml).
The following meta labels are available on targets during [relabeling](#relabel_config):
* `__meta_vultr_instance_id` : A unique ID for the vultr Instance.
* `__meta_vultr_instance_label` : The user-supplied label for this instance.
* `__meta_vultr_instance_os` : The Operating System name.
* `__meta_vultr_instance_os_id` : The Operating System id used by this instance.
* `__meta_vultr_instance_region` : The Region id where the Instance is located.
* `__meta_vultr_instance_plan` : A unique ID for the Plan.
* `__meta_vultr_instance_main_ip` : The main IPv4 address.
* `__meta_vultr_instance_internal_ip` : The private IP address.
* `__meta_vultr_instance_main_ipv6` : The main IPv6 address.
* `__meta_vultr_instance_features` : List of features that are available to the instance.
* `__meta_vultr_instance_tags` : List of tags associated with the instance.
* `__meta_vultr_instance_hostname` : The hostname for this instance.
* `__meta_vultr_instance_server_status` : The server health status.
* `__meta_vultr_instance_vcpu_count` : Number of vCPUs.
* `__meta_vultr_instance_ram_bytes` : The amount of RAM in MB.
* `__meta_vultr_instance_disk_gb` : The size of the disk in GB.
* `__meta_vultr_instance_allowed_bandwidth_gb` : Monthly bandwidth quota in GB.
```yaml
# Authentication information used to authenticate to the API server.
# Note that `basic_auth` and `authorization` options are
# mutually exclusive.
# password and password_file are mutually exclusive.
# Optional HTTP basic authentication information, not currently supported by Vultr.
basic_auth:
[ username: <string> ]
[ password: <secret> ]
[ password_file: <string> ]
# Optional `Authorization` header configuration.
authorization:
# Sets the authentication type.
[ type: <string> | default: Bearer ]
# Sets the credentials. It is mutually exclusive with
# `credentials_file`.
[ credentials: <secret> ]
# Sets the credentials to the credentials read from the configured file.
# It is mutually exclusive with `credentials`.
[ credentials_file: <filename> ]
# Optional OAuth 2.0 configuration.
# Cannot be used at the same time as basic_auth or authorization.
oauth2:
[ <oauth2> ]
# Optional proxy URL.
[ proxy_url: <string> ]
# Configure whether HTTP requests follow HTTP 3xx redirects.
[ follow_redirects: <boolean> | default = true ]
# Whether to enable HTTP2.
[ enable_http2: <bool> | default: true ]
# TLS configuration.
tls_config:
[ <tls_config> ]
# The port to scrape metrics from.
[ port: <int> | default = 80 ]
# The time after which the instances are refreshed.
[ refresh_interval: <duration> | default = 60s ]
```
### `<static_config>` ### `<static_config>`
A `static_config` allows specifying a list of targets and a common label set A `static_config` allows specifying a list of targets and a common label set
@ -2813,6 +2890,10 @@ triton_sd_configs:
uyuni_sd_configs: uyuni_sd_configs:
[ - <uyuni_sd_config> ... ] [ - <uyuni_sd_config> ... ]
# List of Vultr service discovery configurations.
vultr_sd_configs:
[ - <vultr_sd_config> ... ]
# List of labeled statically configured Alertmanagers. # List of labeled statically configured Alertmanagers.
static_configs: static_configs:
[ - <static_config> ... ] [ - <static_config> ... ]

View file

@ -0,0 +1,24 @@
# An example scrape configuration for running Prometheus with
# Vultr.
scrape_configs:
# Make Prometheus scrape itself for metrics.
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
# Discover Node Exporter instances to scrape.
- job_name: "node"
vultr_sd_configs:
- authorization:
credentials: "<replace with a Personal Access Token>"
relabel_configs:
# Only scrape targets that have a tag 'monitoring'.
- source_labels: [__meta_vultr_instance_tags]
regex: ".*,monitoring,.*"
action: keep
# Use the public IPv6 address and port 9100 to scrape the target.
- source_labels: [__meta_vultr_instance_main_ipv6]
target_label: __address__
replacement: "[$1]:9100"

4
go.mod
View file

@ -48,6 +48,7 @@ require (
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.9 github.com/scaleway/scaleway-sdk-go v1.0.0-beta.9
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749
github.com/stretchr/testify v1.7.1 github.com/stretchr/testify v1.7.1
github.com/vultr/govultr/v2 v2.17.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0
go.opentelemetry.io/otel v1.7.0 go.opentelemetry.io/otel v1.7.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0
@ -128,10 +129,11 @@ require (
github.com/google/uuid v1.2.0 // indirect github.com/google/uuid v1.2.0 // indirect
github.com/googleapis/gax-go/v2 v2.3.0 // indirect github.com/googleapis/gax-go/v2 v2.3.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.2 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.2 // indirect
github.com/hashicorp/go-cleanhttp v0.5.1 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-hclog v0.12.2 // indirect github.com/hashicorp/go-hclog v0.12.2 // indirect
github.com/hashicorp/go-immutable-radix v1.2.0 // indirect github.com/hashicorp/go-immutable-radix v1.2.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.1 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/serf v0.9.6 // indirect github.com/hashicorp/serf v0.9.6 // indirect

8
go.sum
View file

@ -464,8 +464,10 @@ github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOj
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v0.12.2 h1:F1fdYblUEsxKiailtkhCCG2g4bipEgaHiDc8vffNpD4= github.com/hashicorp/go-hclog v0.12.2 h1:F1fdYblUEsxKiailtkhCCG2g4bipEgaHiDc8vffNpD4=
github.com/hashicorp/go-hclog v0.12.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.12.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
@ -479,6 +481,8 @@ github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1aJLQ4LJJbTQ=
github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
@ -820,6 +824,8 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/vultr/govultr/v2 v2.17.0 h1:BHa6MQvQn4YNOw+ecfrbISOf4+3cvgofEQHKBSXt6t0=
github.com/vultr/govultr/v2 v2.17.0/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=

View file

@ -70,6 +70,9 @@ import (
// Register uyuni plugin. // Register uyuni plugin.
_ "github.com/prometheus/prometheus/discovery/uyuni" _ "github.com/prometheus/prometheus/discovery/uyuni"
// Register vultr plugin.
_ "github.com/prometheus/prometheus/discovery/vultr"
// Register xds plugin. // Register xds plugin.
_ "github.com/prometheus/prometheus/discovery/xds" _ "github.com/prometheus/prometheus/discovery/xds"