Add service discovery for IONOS Cloud (#10514)

* Add service discovery for IONOS Cloud

Signed-off-by: Felix Ehrenpfort <felix@ehrenpfort.de>
pull/10724/head
Felix Ehrenpfort 3 years ago committed by GitHub
parent e22b54e253
commit ce3bc818a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -40,6 +40,7 @@ import (
"github.com/prometheus/prometheus/discovery/file"
"github.com/prometheus/prometheus/discovery/hetzner"
"github.com/prometheus/prometheus/discovery/http"
"github.com/prometheus/prometheus/discovery/ionos"
"github.com/prometheus/prometheus/discovery/kubernetes"
"github.com/prometheus/prometheus/discovery/linode"
"github.com/prometheus/prometheus/discovery/marathon"
@ -996,6 +997,29 @@ var expectedConf = &Config{
},
},
},
{
JobName: "ionos",
HonorTimestamps: true,
ScrapeInterval: model.Duration(15 * time.Second),
ScrapeTimeout: DefaultGlobalConfig.ScrapeTimeout,
MetricsPath: DefaultScrapeConfig.MetricsPath,
Scheme: DefaultScrapeConfig.Scheme,
HTTPClientConfig: config.DefaultHTTPClientConfig,
ServiceDiscoveryConfigs: discovery.Configs{
&ionos.SDConfig{
DatacenterID: "8feda53f-15f0-447f-badf-ebe32dad2fc0",
HTTPClientConfig: config.HTTPClientConfig{
Authorization: &config.Authorization{Type: "Bearer", Credentials: "abcdef"},
FollowRedirects: true,
EnableHTTP2: true,
},
Port: 80,
RefreshInterval: model.Duration(60 * time.Second),
},
},
},
},
AlertingConfig: AlertingConfig{
AlertmanagerConfigs: []*AlertmanagerConfig{
@ -1093,7 +1117,7 @@ func TestElideSecrets(t *testing.T) {
yamlConfig := string(config)
matches := secretRe.FindAllStringIndex(yamlConfig, -1)
require.Equal(t, 16, len(matches), "wrong number of secret matches found")
require.Equal(t, 17, len(matches), "wrong number of secret matches found")
require.NotContains(t, yamlConfig, "mysecret",
"yaml marshal reveals authentication credentials.")
}
@ -1532,6 +1556,10 @@ var expectedErrors = []struct {
filename: "uyuni_no_server.bad.yml",
errMsg: "Uyuni SD configuration requires server host",
},
{
filename: "ionos_datacenter.bad.yml",
errMsg: "datacenter id can't be empty",
},
}
func TestBadConfigs(t *testing.T) {

@ -367,6 +367,12 @@ scrape_configs:
username: gopher
password: hole
- job_name: ionos
ionos_sd_configs:
- datacenter_id: 8feda53f-15f0-447f-badf-ebe32dad2fc0
authorization:
credentials: abcdef
alerting:
alertmanagers:
- scheme: https

@ -0,0 +1,3 @@
scrape_configs:
- ionos_sd_configs:
- datacenter_id: ""

@ -26,6 +26,7 @@ import (
_ "github.com/prometheus/prometheus/discovery/gce" // register gce
_ "github.com/prometheus/prometheus/discovery/hetzner" // register hetzner
_ "github.com/prometheus/prometheus/discovery/http" // register http
_ "github.com/prometheus/prometheus/discovery/ionos" // register ionos
_ "github.com/prometheus/prometheus/discovery/kubernetes" // register kubernetes
_ "github.com/prometheus/prometheus/discovery/linode" // register linode
_ "github.com/prometheus/prometheus/discovery/marathon" // register marathon

@ -0,0 +1,111 @@
// 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 ionos
import (
"time"
"github.com/go-kit/log"
"github.com/pkg/errors"
"github.com/prometheus/common/config"
"github.com/prometheus/common/model"
"github.com/prometheus/prometheus/discovery"
"github.com/prometheus/prometheus/discovery/refresh"
)
const (
// metaLabelPrefix is the meta prefix used for all meta labels in this
// discovery.
metaLabelPrefix = model.MetaLabelPrefix + "ionos_"
metaLabelSeparator = ","
)
func init() {
discovery.RegisterConfig(&SDConfig{})
}
// Discovery periodically performs IONOS Cloud target discovery. It implements
// the Discoverer interface.
type Discovery struct{}
// NewDiscovery returns a new refresh.Discovery for IONOS Cloud.
func NewDiscovery(conf *SDConfig, logger log.Logger) (*refresh.Discovery, error) {
if conf.ionosEndpoint == "" {
conf.ionosEndpoint = "https://api.ionos.com"
}
d, err := newServerDiscovery(conf, logger)
if err != nil {
return nil, err
}
return refresh.NewDiscovery(
logger,
"ionos",
time.Duration(conf.RefreshInterval),
d.refresh,
), nil
}
// DefaultSDConfig is the default IONOS Cloud service discovery configuration.
var DefaultSDConfig = SDConfig{
HTTPClientConfig: config.DefaultHTTPClientConfig,
RefreshInterval: model.Duration(60 * time.Second),
Port: 80,
}
// SDConfig configuration to use for IONOS Cloud Discovery.
type SDConfig struct {
// DatacenterID: IONOS Cloud data center ID used to discover targets.
DatacenterID string `yaml:"datacenter_id"`
HTTPClientConfig config.HTTPClientConfig `yaml:",inline"`
RefreshInterval model.Duration `yaml:"refresh_interval"`
Port int `yaml:"port"`
ionosEndpoint string // For tests only.
}
// Name returns the name of the IONOS Cloud service discovery.
func (c SDConfig) Name() string {
return "ionos"
}
// NewDiscoverer returns a new discovery.Discoverer for IONOS Cloud.
func (c SDConfig) NewDiscoverer(options discovery.DiscovererOptions) (discovery.Discoverer, error) {
return NewDiscovery(&c, options.Logger)
}
// UnmarshalYAML implements the yaml.Unmarshaler interface.
func (c *SDConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
*c = DefaultSDConfig
type plain SDConfig
err := unmarshal((*plain)(c))
if err != nil {
return err
}
if c.DatacenterID == "" {
return errors.New("datacenter id can't be empty")
}
return c.HTTPClientConfig.Validate()
}
// SetDirectory joins any relative file paths with dir.
func (c *SDConfig) SetDirectory(dir string) {
c.HTTPClientConfig.SetDirectory(dir)
}

@ -0,0 +1,166 @@
// 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 ionos
import (
"context"
"fmt"
"net"
"net/http"
"strconv"
"strings"
"time"
"github.com/go-kit/log"
ionoscloud "github.com/ionos-cloud/sdk-go/v6"
"github.com/prometheus/common/config"
"github.com/prometheus/common/model"
"github.com/prometheus/common/version"
"github.com/prometheus/prometheus/discovery/refresh"
"github.com/prometheus/prometheus/discovery/targetgroup"
"github.com/prometheus/prometheus/util/strutil"
)
const (
serverLabelPrefix = metaLabelPrefix + "server_"
serverAvailabilityZoneLabel = serverLabelPrefix + "availability_zone"
serverBootCDROMIDLabel = serverLabelPrefix + "boot_cdrom_id"
serverBootImageIDLabel = serverLabelPrefix + "boot_image_id"
serverBootVolumeIDLabel = serverLabelPrefix + "boot_volume_id"
serverCPUFamilyLabel = serverLabelPrefix + "cpu_family"
serverIDLabel = serverLabelPrefix + "id"
serverIPLabel = serverLabelPrefix + "ip"
serverLifecycleLabel = serverLabelPrefix + "lifecycle"
serverNameLabel = serverLabelPrefix + "name"
serverNICIPLabelPrefix = serverLabelPrefix + "nic_ip_"
serverServersIDLabel = serverLabelPrefix + "servers_id"
serverStateLabel = serverLabelPrefix + "state"
serverTypeLabel = serverLabelPrefix + "type"
nicDefaultName = "unnamed"
)
type serverDiscovery struct {
*refresh.Discovery
client *ionoscloud.APIClient
port int
datacenterID string
}
func newServerDiscovery(conf *SDConfig, logger log.Logger) (*serverDiscovery, error) {
d := &serverDiscovery{
port: conf.Port,
datacenterID: conf.DatacenterID,
}
rt, err := config.NewRoundTripperFromConfig(conf.HTTPClientConfig, "ionos_sd")
if err != nil {
return nil, err
}
// Username, password and token are set via http client config.
cfg := ionoscloud.NewConfiguration("", "", "", conf.ionosEndpoint)
cfg.HTTPClient = &http.Client{
Transport: rt,
Timeout: time.Duration(conf.RefreshInterval),
}
cfg.UserAgent = fmt.Sprintf("Prometheus/%s", version.Version)
d.client = ionoscloud.NewAPIClient(cfg)
return d, nil
}
func (d *serverDiscovery) refresh(ctx context.Context) ([]*targetgroup.Group, error) {
api := d.client.ServersApi
servers, _, err := api.DatacentersServersGet(ctx, d.datacenterID).
Depth(3).
Execute()
if err != nil {
return nil, err
}
var targets []model.LabelSet
for _, server := range *servers.Items {
var ips []string
ipsByNICName := make(map[string][]string)
if server.Entities != nil && server.Entities.Nics != nil {
for _, nic := range *server.Entities.Nics.Items {
nicName := nicDefaultName
if name := nic.Properties.Name; name != nil {
nicName = *name
}
nicIPs := *nic.Properties.Ips
ips = append(nicIPs, ips...)
ipsByNICName[nicName] = append(nicIPs, ipsByNICName[nicName]...)
}
}
// If a server has no IP addresses, it's being dropped from the targets.
if len(ips) == 0 {
continue
}
addr := net.JoinHostPort(ips[0], strconv.FormatUint(uint64(d.port), 10))
labels := model.LabelSet{
model.AddressLabel: model.LabelValue(addr),
serverAvailabilityZoneLabel: model.LabelValue(*server.Properties.AvailabilityZone),
serverCPUFamilyLabel: model.LabelValue(*server.Properties.CpuFamily),
serverServersIDLabel: model.LabelValue(*servers.Id),
serverIDLabel: model.LabelValue(*server.Id),
serverIPLabel: model.LabelValue(join(ips, metaLabelSeparator)),
serverLifecycleLabel: model.LabelValue(*server.Metadata.State),
serverNameLabel: model.LabelValue(*server.Properties.Name),
serverStateLabel: model.LabelValue(*server.Properties.VmState),
serverTypeLabel: model.LabelValue(*server.Properties.Type),
}
for nicName, nicIPs := range ipsByNICName {
name := serverNICIPLabelPrefix + strutil.SanitizeLabelName(nicName)
labels[model.LabelName(name)] = model.LabelValue(join(nicIPs, metaLabelSeparator))
}
if server.Properties.BootCdrom != nil {
labels[serverBootCDROMIDLabel] = model.LabelValue(*server.Properties.BootCdrom.Id)
}
if server.Properties.BootVolume != nil {
labels[serverBootVolumeIDLabel] = model.LabelValue(*server.Properties.BootVolume.Id)
}
if server.Entities != nil && server.Entities.Volumes != nil {
volumes := *server.Entities.Volumes.Items
if len(volumes) > 0 {
image := volumes[0].Properties.Image
if image != nil {
labels[serverBootImageIDLabel] = model.LabelValue(*image)
}
}
}
targets = append(targets, labels)
}
return []*targetgroup.Group{{Source: "ionos", Targets: targets}}, nil
}
// join returns strings.Join with additional separators at beginning and end.
func join(elems []string, sep string) string {
return sep + strings.Join(elems, sep) + sep
}

@ -0,0 +1,115 @@
// 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 ionos
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"os"
"testing"
ionoscloud "github.com/ionos-cloud/sdk-go/v6"
"github.com/prometheus/common/config"
"github.com/prometheus/common/model"
"github.com/stretchr/testify/require"
)
var (
ionosTestBearerToken = config.Secret("jwt")
ionosTestDatacenterID = "8feda53f-15f0-447f-badf-ebe32dad2fc0"
)
func TestIONOSServerRefresh(t *testing.T) {
mock := httptest.NewServer(http.HandlerFunc(mockIONOSServers))
defer mock.Close()
cfg := DefaultSDConfig
cfg.DatacenterID = ionosTestDatacenterID
cfg.HTTPClientConfig.BearerToken = ionosTestBearerToken
cfg.ionosEndpoint = mock.URL
d, err := newServerDiscovery(&cfg, nil)
require.NoError(t, err)
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, 2, len(tg.Targets))
for i, lbls := range []model.LabelSet{
{
"__address__": "85.215.243.177:80",
"__meta_ionos_server_availability_zone": "ZONE_2",
"__meta_ionos_server_boot_cdrom_id": "0e4d57f9-cd78-11e9-b88c-525400f64d8d",
"__meta_ionos_server_cpu_family": "INTEL_SKYLAKE",
"__meta_ionos_server_id": "b501942c-4e08-43e6-8ec1-00e59c64e0e4",
"__meta_ionos_server_ip": ",85.215.243.177,185.56.150.9,85.215.238.118,",
"__meta_ionos_server_nic_ip_metrics": ",85.215.243.177,",
"__meta_ionos_server_nic_ip_unnamed": ",185.56.150.9,85.215.238.118,",
"__meta_ionos_server_lifecycle": "AVAILABLE",
"__meta_ionos_server_name": "prometheus-2",
"__meta_ionos_server_servers_id": "8feda53f-15f0-447f-badf-ebe32dad2fc0/servers",
"__meta_ionos_server_state": "RUNNING",
"__meta_ionos_server_type": "ENTERPRISE",
},
{
"__address__": "85.215.248.84:80",
"__meta_ionos_server_availability_zone": "ZONE_1",
"__meta_ionos_server_boot_cdrom_id": "0e4d57f9-cd78-11e9-b88c-525400f64d8d",
"__meta_ionos_server_cpu_family": "INTEL_SKYLAKE",
"__meta_ionos_server_id": "523415e6-ff8c-4dc0-86d3-09c256039b30",
"__meta_ionos_server_ip": ",85.215.248.84,",
"__meta_ionos_server_nic_ip_unnamed": ",85.215.248.84,",
"__meta_ionos_server_lifecycle": "AVAILABLE",
"__meta_ionos_server_name": "prometheus-1",
"__meta_ionos_server_servers_id": "8feda53f-15f0-447f-badf-ebe32dad2fc0/servers",
"__meta_ionos_server_state": "RUNNING",
"__meta_ionos_server_type": "ENTERPRISE",
},
} {
t.Run(fmt.Sprintf("item %d", i), func(t *testing.T) {
require.Equal(t, lbls, tg.Targets[i])
})
}
}
func mockIONOSServers(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Authorization") != fmt.Sprintf("Bearer %s", ionosTestBearerToken) {
http.Error(w, "bad token", http.StatusUnauthorized)
return
}
if r.URL.Path != fmt.Sprintf("%s/datacenters/%s/servers", ionoscloud.DefaultIonosBasePath, ionosTestDatacenterID) {
http.Error(w, fmt.Sprintf("bad url: %s", r.URL.Path), http.StatusNotFound)
return
}
w.Header().Set("Content-Type", "application/json")
server, err := os.ReadFile("testdata/servers.json")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
_, err = w.Write(server)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}

@ -0,0 +1,615 @@
{
"id": "8feda53f-15f0-447f-badf-ebe32dad2fc0/servers",
"type": "collection",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers",
"items": [
{
"id": "d6bf44ee-f7e8-4e19-8716-96fdd18cc697",
"type": "server",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/d6bf44ee-f7e8-4e19-8716-96fdd18cc697",
"metadata": {
"etag": "3bd2cf1f190fdba8502ba8c0cc79433e",
"createdDate": "2019-09-02T11:51:53Z",
"createdBy": "System",
"createdByUserId": "[UNKNOWN]",
"lastModifiedDate": "2019-09-02T11:51:53Z",
"lastModifiedBy": "System",
"lastModifiedByUserId": "[UNKNOWN]",
"state": "AVAILABLE"
},
"properties": {
"name": "prometheus-3",
"cores": 2,
"ram": 4096,
"availabilityZone": "AUTO",
"vmState": "RUNNING",
"bootCdrom": {
"id": "0e4d57f9-cd78-11e9-b88c-525400f64d8d",
"type": "image",
"href": "https://api.ionos.com/cloudapi/v6/images/0e4d57f9-cd78-11e9-b88c-525400f64d8d",
"metadata": {
"etag": "ca643281fd2a5b68002bc00ac0ecd920",
"createdDate": "2019-09-02T11:51:53Z",
"createdBy": "System",
"createdByUserId": "[UNKNOWN]",
"lastModifiedDate": "2019-09-02T11:51:53Z",
"lastModifiedBy": "System",
"lastModifiedByUserId": "[UNKNOWN]",
"state": "AVAILABLE"
},
"properties": {
"name": "debian-10.0.0-amd64-netinst.iso",
"description": null,
"location": "de/txl",
"size": 0.33,
"cpuHotPlug": true,
"cpuHotUnplug": false,
"ramHotPlug": true,
"ramHotUnplug": false,
"nicHotPlug": true,
"nicHotUnplug": true,
"discVirtioHotPlug": true,
"discVirtioHotUnplug": true,
"discScsiHotPlug": false,
"discScsiHotUnplug": false,
"licenceType": "LINUX",
"imageType": "CDROM",
"imageAliases": [
"debian:latest_iso",
"debian:10_iso"
],
"cloudInit": "NONE",
"public": true
}
},
"bootVolume": null,
"cpuFamily": "INTEL_SKYLAKE",
"type": "ENTERPRISE"
},
"entities": {
"cdroms": {
"id": "d6bf44ee-f7e8-4e19-8716-96fdd18cc697/cdroms",
"type": "collection",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/d6bf44ee-f7e8-4e19-8716-96fdd18cc697/cdroms",
"items": [
{
"id": "0e4d57f9-cd78-11e9-b88c-525400f64d8d",
"type": "image",
"href": "https://api.ionos.com/cloudapi/v6/images/0e4d57f9-cd78-11e9-b88c-525400f64d8d",
"metadata": {
"etag": "ca643281fd2a5b68002bc00ac0ecd920",
"createdDate": "2019-09-02T11:51:53Z",
"createdBy": "System",
"createdByUserId": "[UNKNOWN]",
"lastModifiedDate": "2019-09-02T11:51:53Z",
"lastModifiedBy": "System",
"lastModifiedByUserId": "[UNKNOWN]",
"state": "AVAILABLE"
},
"properties": {
"name": "debian-10.0.0-amd64-netinst.iso",
"description": null,
"location": "de/txl",
"size": 0.33,
"cpuHotPlug": true,
"cpuHotUnplug": false,
"ramHotPlug": true,
"ramHotUnplug": false,
"nicHotPlug": true,
"nicHotUnplug": true,
"discVirtioHotPlug": true,
"discVirtioHotUnplug": true,
"discScsiHotPlug": false,
"discScsiHotUnplug": false,
"licenceType": "LINUX",
"imageType": "CDROM",
"imageAliases": [
"debian:10_iso",
"debian:latest_iso"
],
"cloudInit": "NONE",
"public": true
}
}
]
},
"volumes": {
"id": "d6bf44ee-f7e8-4e19-8716-96fdd18cc697/volumes",
"type": "collection",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/d6bf44ee-f7e8-4e19-8716-96fdd18cc697/volumes",
"items": []
},
"nics": {
"id": "d6bf44ee-f7e8-4e19-8716-96fdd18cc697/nics",
"type": "collection",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/d6bf44ee-f7e8-4e19-8716-96fdd18cc697/nics",
"items": []
}
}
},
{
"id": "b501942c-4e08-43e6-8ec1-00e59c64e0e4",
"type": "server",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/b501942c-4e08-43e6-8ec1-00e59c64e0e4",
"metadata": {
"etag": "fe405a5f2e041d506086ee0c2159b678",
"createdDate": "2019-09-02T11:51:53Z",
"createdBy": "System",
"createdByUserId": "[UNKNOWN]",
"lastModifiedDate": "2019-09-02T11:51:53Z",
"lastModifiedBy": "System",
"lastModifiedByUserId": "[UNKNOWN]",
"state": "AVAILABLE"
},
"properties": {
"name": "prometheus-2",
"cores": 1,
"ram": 1024,
"availabilityZone": "ZONE_2",
"vmState": "RUNNING",
"bootCdrom": {
"id": "0e4d57f9-cd78-11e9-b88c-525400f64d8d",
"type": "image",
"href": "https://api.ionos.com/cloudapi/v6/images/0e4d57f9-cd78-11e9-b88c-525400f64d8d",
"metadata": {
"etag": "ca643281fd2a5b68002bc00ac0ecd920",
"createdDate": "2019-09-02T11:51:53Z",
"createdBy": "System",
"createdByUserId": "[UNKNOWN]",
"lastModifiedDate": "2019-09-02T11:51:53Z",
"lastModifiedBy": "System",
"lastModifiedByUserId": "[UNKNOWN]",
"state": "AVAILABLE"
},
"properties": {
"name": "debian-10.0.0-amd64-netinst.iso",
"description": null,
"location": "de/txl",
"size": 0.33,
"cpuHotPlug": true,
"cpuHotUnplug": false,
"ramHotPlug": true,
"ramHotUnplug": false,
"nicHotPlug": true,
"nicHotUnplug": true,
"discVirtioHotPlug": true,
"discVirtioHotUnplug": true,
"discScsiHotPlug": false,
"discScsiHotUnplug": false,
"licenceType": "LINUX",
"imageType": "CDROM",
"imageAliases": [
"debian:latest_iso",
"debian:10_iso"
],
"cloudInit": "NONE",
"public": true
}
},
"bootVolume": null,
"cpuFamily": "INTEL_SKYLAKE",
"type": "ENTERPRISE"
},
"entities": {
"cdroms": {
"id": "b501942c-4e08-43e6-8ec1-00e59c64e0e4/cdroms",
"type": "collection",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/b501942c-4e08-43e6-8ec1-00e59c64e0e4/cdroms",
"items": [
{
"id": "0e4d57f9-cd78-11e9-b88c-525400f64d8d",
"type": "image",
"href": "https://api.ionos.com/cloudapi/v6/images/0e4d57f9-cd78-11e9-b88c-525400f64d8d",
"metadata": {
"etag": "ca643281fd2a5b68002bc00ac0ecd920",
"createdDate": "2019-09-02T11:51:53Z",
"createdBy": "System",
"createdByUserId": "[UNKNOWN]",
"lastModifiedDate": "2019-09-02T11:51:53Z",
"lastModifiedBy": "System",
"lastModifiedByUserId": "[UNKNOWN]",
"state": "AVAILABLE"
},
"properties": {
"name": "debian-10.0.0-amd64-netinst.iso",
"description": null,
"location": "de/txl",
"size": 0.33,
"cpuHotPlug": true,
"cpuHotUnplug": false,
"ramHotPlug": true,
"ramHotUnplug": false,
"nicHotPlug": true,
"nicHotUnplug": true,
"discVirtioHotPlug": true,
"discVirtioHotUnplug": true,
"discScsiHotPlug": false,
"discScsiHotUnplug": false,
"licenceType": "LINUX",
"imageType": "CDROM",
"imageAliases": [
"debian:10_iso",
"debian:latest_iso"
],
"cloudInit": "NONE",
"public": true
}
}
]
},
"volumes": {
"id": "b501942c-4e08-43e6-8ec1-00e59c64e0e4/volumes",
"type": "collection",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/b501942c-4e08-43e6-8ec1-00e59c64e0e4/volumes",
"items": [
{
"id": "97a58f00-e2a5-4ebb-8b9a-f694837b0548",
"type": "volume",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/volumes/97a58f00-e2a5-4ebb-8b9a-f694837b0548",
"metadata": {
"etag": "27491713a77c5453c6ae7d0f98a1beec",
"createdDate": "2019-09-02T11:51:53Z",
"createdBy": "System",
"createdByUserId": "[UNKNOWN]",
"lastModifiedDate": "2019-09-02T11:51:53Z",
"lastModifiedBy": "System",
"lastModifiedByUserId": "[UNKNOWN]",
"state": "AVAILABLE"
},
"properties": {
"name": "prometheus-data-1",
"type": "HDD",
"size": 10,
"availabilityZone": "AUTO",
"image": null,
"imagePassword": null,
"sshKeys": null,
"bus": "VIRTIO",
"licenceType": "UNKNOWN",
"cpuHotPlug": false,
"ramHotPlug": false,
"nicHotPlug": false,
"nicHotUnplug": false,
"discVirtioHotPlug": false,
"discVirtioHotUnplug": false,
"deviceNumber": 1,
"userData": null,
"pciSlot": 6,
"bootServer": "b501942c-4e08-43e6-8ec1-00e59c64e0e4"
}
}
]
},
"nics": {
"id": "b501942c-4e08-43e6-8ec1-00e59c64e0e4/nics",
"type": "collection",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/b501942c-4e08-43e6-8ec1-00e59c64e0e4/nics",
"items": [
{
"id": "206e9a88-097c-4c87-8544-1f5fe0b6b0f1",
"type": "nic",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/b501942c-4e08-43e6-8ec1-00e59c64e0e4/nics/206e9a88-097c-4c87-8544-1f5fe0b6b0f1",
"metadata": {
"etag": "be2b6fff29e7e09c1a4a5ca150876eaa",
"createdDate": "2019-09-02T11:51:53Z",
"createdBy": "System",
"createdByUserId": "[UNKNOWN]",
"lastModifiedDate": "2019-09-02T11:51:53Z",
"lastModifiedBy": "System",
"lastModifiedByUserId": "[UNKNOWN]",
"state": "AVAILABLE"
},
"properties": {
"name": null,
"mac": "02:01:4b:1c:cf:57",
"ips": [
"85.215.238.118"
],
"dhcp": true,
"lan": 1,
"firewallActive": false,
"firewallType": "INGRESS",
"deviceNumber": 1,
"pciSlot": 5
},
"entities": {
"firewallrules": {
"id": "206e9a88-097c-4c87-8544-1f5fe0b6b0f1/firewallrules",
"type": "collection",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/b501942c-4e08-43e6-8ec1-00e59c64e0e4/nics/206e9a88-097c-4c87-8544-1f5fe0b6b0f1/firewallrules"
},
"flowlogs": {
"id": "206e9a88-097c-4c87-8544-1f5fe0b6b0f1/flowlogs",
"type": "collection",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/b501942c-4e08-43e6-8ec1-00e59c64e0e4/nics/206e9a88-097c-4c87-8544-1f5fe0b6b0f1/flowlogs"
}
}
},
{
"id": "8a568a32-da62-437d-8b73-f580d1a1588f",
"type": "nic",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/b501942c-4e08-43e6-8ec1-00e59c64e0e4/nics/8a568a32-da62-437d-8b73-f580d1a1588f",
"metadata": {
"etag": "2dca0340a0610b1dfdb2e66f6aae3ed3",
"createdDate": "2022-05-05T13:12:31Z",
"createdBy": "felix.ehrenpfort@codecentric.cloud",
"createdByUserId": "cfcb4526-fbe0-461e-9149-ffb00a83fbec",
"lastModifiedDate": "2022-05-05T13:12:31Z",
"lastModifiedBy": "felix.ehrenpfort@codecentric.cloud",
"lastModifiedByUserId": "cfcb4526-fbe0-461e-9149-ffb00a83fbec",
"state": "AVAILABLE"
},
"properties": {
"name": null,
"mac": "02:01:56:f6:47:a8",
"ips": [
"185.56.150.9"
],
"dhcp": true,
"lan": 1,
"firewallActive": false,
"firewallType": "INGRESS",
"deviceNumber": 3,
"pciSlot": 8
},
"entities": {
"firewallrules": {
"id": "8a568a32-da62-437d-8b73-f580d1a1588f/firewallrules",
"type": "collection",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/b501942c-4e08-43e6-8ec1-00e59c64e0e4/nics/8a568a32-da62-437d-8b73-f580d1a1588f/firewallrules"
},
"flowlogs": {
"id": "8a568a32-da62-437d-8b73-f580d1a1588f/flowlogs",
"type": "collection",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/b501942c-4e08-43e6-8ec1-00e59c64e0e4/nics/8a568a32-da62-437d-8b73-f580d1a1588f/flowlogs"
}
}
},
{
"id": "17ecc866-4a08-4ada-858f-7b726a5f5070",
"type": "nic",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/b501942c-4e08-43e6-8ec1-00e59c64e0e4/nics/17ecc866-4a08-4ada-858f-7b726a5f5070",
"metadata": {
"etag": "f6a82276c6fdb460811d3789e54e0054",
"createdDate": "2022-05-05T11:45:36Z",
"createdBy": "felix.ehrenpfort@codecentric.cloud",
"createdByUserId": "cfcb4526-fbe0-461e-9149-ffb00a83fbec",
"lastModifiedDate": "2022-05-05T11:45:36Z",
"lastModifiedBy": "felix.ehrenpfort@codecentric.cloud",
"lastModifiedByUserId": "cfcb4526-fbe0-461e-9149-ffb00a83fbec",
"state": "AVAILABLE"
},
"properties": {
"name": "metrics",
"mac": "02:01:93:80:fa:a4",
"ips": [
"85.215.243.177"
],
"dhcp": true,
"lan": 1,
"firewallActive": false,
"firewallType": "INGRESS",
"deviceNumber": 2,
"pciSlot": 7
},
"entities": {
"firewallrules": {
"id": "17ecc866-4a08-4ada-858f-7b726a5f5070/firewallrules",
"type": "collection",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/b501942c-4e08-43e6-8ec1-00e59c64e0e4/nics/17ecc866-4a08-4ada-858f-7b726a5f5070/firewallrules"
},
"flowlogs": {
"id": "17ecc866-4a08-4ada-858f-7b726a5f5070/flowlogs",
"type": "collection",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/b501942c-4e08-43e6-8ec1-00e59c64e0e4/nics/17ecc866-4a08-4ada-858f-7b726a5f5070/flowlogs"
}
}
}
]
}
}
},
{
"id": "523415e6-ff8c-4dc0-86d3-09c256039b30",
"type": "server",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/523415e6-ff8c-4dc0-86d3-09c256039b30",
"metadata": {
"etag": "fe405a5f2e041d506086ee0c2159b678",
"createdDate": "2019-09-02T11:51:53Z",
"createdBy": "System",
"createdByUserId": "[UNKNOWN]",
"lastModifiedDate": "2019-09-02T11:51:53Z",
"lastModifiedBy": "System",
"lastModifiedByUserId": "[UNKNOWN]",
"state": "AVAILABLE"
},
"properties": {
"name": "prometheus-1",
"cores": 1,
"ram": 1024,
"availabilityZone": "ZONE_1",
"vmState": "RUNNING",
"bootCdrom": {
"id": "0e4d57f9-cd78-11e9-b88c-525400f64d8d",
"type": "image",
"href": "https://api.ionos.com/cloudapi/v6/images/0e4d57f9-cd78-11e9-b88c-525400f64d8d",
"metadata": {
"etag": "ca643281fd2a5b68002bc00ac0ecd920",
"createdDate": "2019-09-02T11:51:53Z",
"createdBy": "System",
"createdByUserId": "[UNKNOWN]",
"lastModifiedDate": "2019-09-02T11:51:53Z",
"lastModifiedBy": "System",
"lastModifiedByUserId": "[UNKNOWN]",
"state": "AVAILABLE"
},
"properties": {
"name": "debian-10.0.0-amd64-netinst.iso",
"description": null,
"location": "de/txl",
"size": 0.33,
"cpuHotPlug": true,
"cpuHotUnplug": false,
"ramHotPlug": true,
"ramHotUnplug": false,
"nicHotPlug": true,
"nicHotUnplug": true,
"discVirtioHotPlug": true,
"discVirtioHotUnplug": true,
"discScsiHotPlug": false,
"discScsiHotUnplug": false,
"licenceType": "LINUX",
"imageType": "CDROM",
"imageAliases": [
"debian:latest_iso",
"debian:10_iso"
],
"cloudInit": "NONE",
"public": true
}
},
"bootVolume": null,
"cpuFamily": "INTEL_SKYLAKE",
"type": "ENTERPRISE"
},
"entities": {
"cdroms": {
"id": "523415e6-ff8c-4dc0-86d3-09c256039b30/cdroms",
"type": "collection",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/523415e6-ff8c-4dc0-86d3-09c256039b30/cdroms",
"items": [
{
"id": "0e4d57f9-cd78-11e9-b88c-525400f64d8d",
"type": "image",
"href": "https://api.ionos.com/cloudapi/v6/images/0e4d57f9-cd78-11e9-b88c-525400f64d8d",
"metadata": {
"etag": "ca643281fd2a5b68002bc00ac0ecd920",
"createdDate": "2019-09-02T11:51:53Z",
"createdBy": "System",
"createdByUserId": "[UNKNOWN]",
"lastModifiedDate": "2019-09-02T11:51:53Z",
"lastModifiedBy": "System",
"lastModifiedByUserId": "[UNKNOWN]",
"state": "AVAILABLE"
},
"properties": {
"name": "debian-10.0.0-amd64-netinst.iso",
"description": null,
"location": "de/txl",
"size": 0.33,
"cpuHotPlug": true,
"cpuHotUnplug": false,
"ramHotPlug": true,
"ramHotUnplug": false,
"nicHotPlug": true,
"nicHotUnplug": true,
"discVirtioHotPlug": true,
"discVirtioHotUnplug": true,
"discScsiHotPlug": false,
"discScsiHotUnplug": false,
"licenceType": "LINUX",
"imageType": "CDROM",
"imageAliases": [
"debian:10_iso",
"debian:latest_iso"
],
"cloudInit": "NONE",
"public": true
}
}
]
},
"volumes": {
"id": "523415e6-ff8c-4dc0-86d3-09c256039b30/volumes",
"type": "collection",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/523415e6-ff8c-4dc0-86d3-09c256039b30/volumes",
"items": [
{
"id": "5dc21326-7e33-4dc7-84ac-63b02aad4624",
"type": "volume",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/volumes/5dc21326-7e33-4dc7-84ac-63b02aad4624",
"metadata": {
"etag": "27491713a77c5453c6ae7d0f98a1beec",
"createdDate": "2019-09-02T11:51:53Z",
"createdBy": "System",
"createdByUserId": "[UNKNOWN]",
"lastModifiedDate": "2019-09-02T11:51:53Z",
"lastModifiedBy": "System",
"lastModifiedByUserId": "[UNKNOWN]",
"state": "AVAILABLE"
},
"properties": {
"name": "prometheus-data-2",
"type": "HDD",
"size": 10,
"availabilityZone": "AUTO",
"image": null,
"imagePassword": null,
"sshKeys": null,
"bus": "VIRTIO",
"licenceType": "UNKNOWN",
"cpuHotPlug": false,
"ramHotPlug": false,
"nicHotPlug": false,
"nicHotUnplug": false,
"discVirtioHotPlug": false,
"discVirtioHotUnplug": false,
"deviceNumber": 1,
"userData": null,
"pciSlot": 6,
"bootServer": "523415e6-ff8c-4dc0-86d3-09c256039b30"
}
}
]
},
"nics": {
"id": "523415e6-ff8c-4dc0-86d3-09c256039b30/nics",
"type": "collection",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/523415e6-ff8c-4dc0-86d3-09c256039b30/nics",
"items": [
{
"id": "684033a2-317f-4977-8a01-68263d59336c",
"type": "nic",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/523415e6-ff8c-4dc0-86d3-09c256039b30/nics/684033a2-317f-4977-8a01-68263d59336c",
"metadata": {
"etag": "fe405a5f2e041d506086ee0c2159b678",
"createdDate": "2019-09-02T11:51:53Z",
"createdBy": "System",
"createdByUserId": "[UNKNOWN]",
"lastModifiedDate": "2019-09-02T11:51:53Z",
"lastModifiedBy": "System",
"lastModifiedByUserId": "[UNKNOWN]",
"state": "AVAILABLE"
},
"properties": {
"name": null,
"mac": "02:01:17:12:27:1b",
"ips": [
"85.215.248.84"
],
"dhcp": true,
"lan": 1,
"firewallActive": false,
"firewallType": "INGRESS",
"deviceNumber": 1,
"pciSlot": 5
},
"entities": {
"firewallrules": {
"id": "684033a2-317f-4977-8a01-68263d59336c/firewallrules",
"type": "collection",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/523415e6-ff8c-4dc0-86d3-09c256039b30/nics/684033a2-317f-4977-8a01-68263d59336c/firewallrules"
},
"flowlogs": {
"id": "684033a2-317f-4977-8a01-68263d59336c/flowlogs",
"type": "collection",
"href": "https://api.ionos.com/cloudapi/v6/datacenters/8feda53f-15f0-447f-badf-ebe32dad2fc0/servers/523415e6-ff8c-4dc0-86d3-09c256039b30/nics/684033a2-317f-4977-8a01-68263d59336c/flowlogs"
}
}
}
]
}
}
}
]
}

@ -256,6 +256,11 @@ hetzner_sd_configs:
http_sd_configs:
[ - <http_sd_config> ... ]
# List of IONOS service discovery configurations.
ionos_sd_configs:
[ - <ionos_sd_config> ... ]
# List of Kubernetes service discovery configurations.
kubernetes_sd_configs:
[ - <kubernetes_sd_config> ... ]
@ -1539,6 +1544,86 @@ tls_config:
[ <tls_config> ]
```
### `<ionos_sd_config>`
IONOS SD configurations allows retrieving scrape targets from
[IONOS Cloud](https://cloud.ionos.com/) API. This service discovery uses the
first NICs IP address by default, but that can be changed with relabeling. The
following meta labels are available on all targets during
[relabeling](#relabel_config):
* `__meta_ionos_server_availability_zone`: the availability zone of the server
* `__meta_ionos_server_boot_cdrom_id`: the ID of the CD-ROM the server is booted
from
* `__meta_ionos_server_boot_image_id`: the ID of the boot image or snapshot the
server is booted from
* `__meta_ionos_server_boot_volume_id`: the ID of the boot volume
* `__meta_ionos_server_cpu_family`: the CPU family of the server
to
* `__meta_ionos_server_id`: the ID of the server
* `__meta_ionos_server_ip`: comma seperated list of all IPs assigned to the
server
* `__meta_ionos_server_lifecycle`: the lifecycle state of the server resource
* `__meta_ionos_server_name`: the name of the server
* `__meta_ionos_server_nic_ip_<nic_name>`: comma seperated list of IPs, grouped
by the name of each NIC attached to the server
* `__meta_ionos_server_servers_id`: the ID of the servers the server belongs to
* `__meta_ionos_server_state`: the execution state of the server
* `__meta_ionos_server_type`: the type of the server
```yaml
# The unique ID of the data center.
datacenter_id: <string>
# 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, required when using IONOS
# Cloud username and password as authentication method.
basic_auth:
[ username: <string> ]
[ password: <secret> ]
[ password_file: <string> ]
# Optional `Authorization` header configuration, required when using IONOS
# Cloud token as authentication method.
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 servers are refreshed.
[ refresh_interval: <duration> | default = 60s ]
```
### `<kubernetes_sd_config>`
Kubernetes SD configurations allow retrieving scrape targets from
@ -2680,6 +2765,10 @@ hetzner_sd_configs:
http_sd_configs:
[ - <http_sd_config> ... ]
# List of IONOS service discovery configurations.
ionos_sd_configs:
[ - <ionos_sd_config> ... ]
# List of Kubernetes service discovery configurations.
kubernetes_sd_configs:
[ - <kubernetes_sd_config> ... ]

@ -0,0 +1,30 @@
# A example scrape configuration for running Prometheus with IONOS Cloud.
scrape_configs:
- job_name: "node"
ionos_sd_configs:
- basic_auth:
# Replace with your username.
username: username
# Replace with your password.
password: password
# You can find your data center unique ID here: https://dcd.ionos.com/latest/
datacenter_id: 11111111-1111-1111-1111-111111111111
port: 9100
relabel_configs:
# Only scrape servers that are available via API.
- source_labels: [__meta_ionos_server_lifecycle]
action: keep
regex: "AVAILABLE"
# Only scrape servers that are in a running state.
- source_labels: [__meta_ionos_server_state]
action: keep
regex: "RUNNING"
# Replace instance label with server name.
- source_labels: [__meta_ionos_server_name]
target_label: instance
# Add server availability zone as label.
- source_labels: [__meta_ionos_availability_zone]
target_label: ionos_zone

@ -35,6 +35,7 @@ require (
github.com/hashicorp/go-hclog v0.12.2 // indirect
github.com/hashicorp/go-immutable-radix v1.2.0 // indirect
github.com/hetznercloud/hcloud-go v1.33.1
github.com/ionos-cloud/sdk-go/v6 v6.0.5851
github.com/json-iterator/go v1.1.12
github.com/kolo/xmlrpc v0.0.0-20201022064351-38db28db192b
github.com/linode/linodego v1.4.1

@ -765,6 +765,8 @@ github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/intel/goresctrl v0.2.0/go.mod h1:+CZdzouYFn5EsxgqAQTEzMfwKwuc0fVdMrT9FCCAVRQ=
github.com/ionos-cloud/sdk-go/v6 v6.0.5851 h1:Xjdta3uR5SDLXXl0oahgVIJ+AQNFCyOCuAwxPAXFUCM=
github.com/ionos-cloud/sdk-go/v6 v6.0.5851/go.mod h1:UE3V/2DjnqD5doOqtjYqzJRMpI1RiwrvuuSEPX1pdnk=
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
github.com/j-keck/arping v1.0.2/go.mod h1:aJbELhR92bSk7tp79AWM/ftfc90EfEi2bQJrbBFOsPw=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=

@ -6,6 +6,7 @@
- github.com/prometheus/prometheus/discovery/eureka
- github.com/prometheus/prometheus/discovery/gce
- github.com/prometheus/prometheus/discovery/hetzner
- github.com/prometheus/prometheus/discovery/ionos
- github.com/prometheus/prometheus/discovery/kubernetes
- github.com/prometheus/prometheus/discovery/linode
- github.com/prometheus/prometheus/discovery/marathon

@ -40,6 +40,9 @@ import (
// Register hetzner plugin.
_ "github.com/prometheus/prometheus/discovery/hetzner"
// Register ionos plugin.
_ "github.com/prometheus/prometheus/discovery/ionos"
// Register kubernetes plugin.
_ "github.com/prometheus/prometheus/discovery/kubernetes"

Loading…
Cancel
Save