mirror of https://github.com/prometheus/prometheus
Browse Source
Co-authored-by: Patrik <patrik@ptrk.io> Co-authored-by: Julien Pivotto <roidelapluie@inuits.eu> Signed-off-by: Rémy Léone <rleone@scaleway.com>pull/8583/head
Rémy Léone
4 years ago
committed by
GitHub
11 changed files with 742 additions and 1 deletions
@ -0,0 +1,4 @@
|
||||
scrape_configs: |
||||
- scaleway_sd_configs: |
||||
- role: invalid |
||||
|
@ -0,0 +1,192 @@
|
||||
// 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 scaleway |
||||
|
||||
import ( |
||||
"context" |
||||
"fmt" |
||||
"net" |
||||
"net/http" |
||||
"strconv" |
||||
"strings" |
||||
"time" |
||||
|
||||
"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/scaleway/scaleway-sdk-go/api/baremetal/v1" |
||||
"github.com/scaleway/scaleway-sdk-go/scw" |
||||
) |
||||
|
||||
type baremetalDiscovery struct { |
||||
*refresh.Discovery |
||||
client *scw.Client |
||||
port int |
||||
zone string |
||||
project string |
||||
accessKey string |
||||
secretKey string |
||||
nameFilter string |
||||
tagsFilter []string |
||||
} |
||||
|
||||
const ( |
||||
baremetalLabelPrefix = metaLabelPrefix + "baremetal_" |
||||
|
||||
baremetalIDLabel = baremetalLabelPrefix + "id" |
||||
baremetalPublicIPv4Label = baremetalLabelPrefix + "public_ipv4" |
||||
baremetalPublicIPv6Label = baremetalLabelPrefix + "public_ipv6" |
||||
baremetalNameLabel = baremetalLabelPrefix + "name" |
||||
baremetalOSNameLabel = baremetalLabelPrefix + "os_name" |
||||
baremetalOSVersionLabel = baremetalLabelPrefix + "os_version" |
||||
baremetalProjectLabel = baremetalLabelPrefix + "project_id" |
||||
baremetalStatusLabel = baremetalLabelPrefix + "status" |
||||
baremetalTagsLabel = baremetalLabelPrefix + "tags" |
||||
baremetalTypeLabel = baremetalLabelPrefix + "type" |
||||
baremetalZoneLabel = baremetalLabelPrefix + "zone" |
||||
) |
||||
|
||||
func newBaremetalDiscovery(conf *SDConfig) (*baremetalDiscovery, error) { |
||||
d := &baremetalDiscovery{ |
||||
port: conf.Port, |
||||
zone: conf.Zone, |
||||
project: conf.Project, |
||||
accessKey: conf.AccessKey, |
||||
secretKey: string(conf.SecretKey), |
||||
nameFilter: conf.NameFilter, |
||||
tagsFilter: conf.TagsFilter, |
||||
} |
||||
|
||||
rt, err := config.NewRoundTripperFromConfig(conf.HTTPClientConfig, "scaleway_sd", false, false) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
profile, err := loadProfile(conf) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
d.client, err = scw.NewClient( |
||||
scw.WithHTTPClient(&http.Client{ |
||||
Transport: rt, |
||||
Timeout: time.Duration(conf.RefreshInterval), |
||||
}), |
||||
scw.WithUserAgent(fmt.Sprintf("Prometheus/%s", version.Version)), |
||||
scw.WithProfile(profile), |
||||
) |
||||
if err != nil { |
||||
return nil, fmt.Errorf("error setting up scaleway client: %w", err) |
||||
} |
||||
|
||||
return d, nil |
||||
} |
||||
|
||||
func (d *baremetalDiscovery) refresh(ctx context.Context) ([]*targetgroup.Group, error) { |
||||
api := baremetal.NewAPI(d.client) |
||||
|
||||
req := &baremetal.ListServersRequest{} |
||||
|
||||
if d.nameFilter != "" { |
||||
req.Name = scw.StringPtr(d.nameFilter) |
||||
} |
||||
|
||||
if d.tagsFilter != nil { |
||||
req.Tags = d.tagsFilter |
||||
} |
||||
|
||||
servers, err := api.ListServers(req, scw.WithAllPages(), scw.WithContext(ctx)) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
offers, err := api.ListOffers(&baremetal.ListOffersRequest{}, scw.WithAllPages()) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
osFullList, err := api.ListOS(&baremetal.ListOSRequest{}, scw.WithAllPages()) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
var targets []model.LabelSet |
||||
for _, server := range servers.Servers { |
||||
labels := model.LabelSet{ |
||||
baremetalIDLabel: model.LabelValue(server.ID), |
||||
baremetalNameLabel: model.LabelValue(server.Name), |
||||
baremetalZoneLabel: model.LabelValue(server.Zone.String()), |
||||
baremetalStatusLabel: model.LabelValue(server.Status), |
||||
baremetalProjectLabel: model.LabelValue(server.ProjectID), |
||||
} |
||||
|
||||
for _, offer := range offers.Offers { |
||||
if server.OfferID == offer.ID { |
||||
labels[baremetalTypeLabel] = model.LabelValue(offer.Name) |
||||
break |
||||
} |
||||
} |
||||
|
||||
if server.Install != nil { |
||||
for _, os := range osFullList.Os { |
||||
if server.Install.OsID == os.ID { |
||||
labels[baremetalOSNameLabel] = model.LabelValue(os.Name) |
||||
labels[baremetalOSVersionLabel] = model.LabelValue(os.Version) |
||||
break |
||||
} |
||||
} |
||||
} |
||||
|
||||
if len(server.Tags) > 0 { |
||||
// We surround the separated list with the separator as well. This way regular expressions
|
||||
// in relabeling rules don't have to consider tag positions.
|
||||
tags := separator + strings.Join(server.Tags, separator) + separator |
||||
labels[baremetalTagsLabel] = model.LabelValue(tags) |
||||
} |
||||
|
||||
for _, ip := range server.IPs { |
||||
switch v := ip.Version.String(); v { |
||||
case "IPv4": |
||||
if _, ok := labels[baremetalPublicIPv4Label]; ok { |
||||
// If the server has multiple IPv4, we only take the first one.
|
||||
// This should not happen.
|
||||
continue |
||||
} |
||||
labels[baremetalPublicIPv4Label] = model.LabelValue(ip.Address.String()) |
||||
|
||||
// We always default the __address__ to IPv4.
|
||||
addr := net.JoinHostPort(ip.Address.String(), strconv.FormatUint(uint64(d.port), 10)) |
||||
labels[model.AddressLabel] = model.LabelValue(addr) |
||||
case "IPv6": |
||||
if _, ok := labels[baremetalPublicIPv6Label]; ok { |
||||
// If the server has multiple IPv6, we only take the first one.
|
||||
// This should not happen.
|
||||
continue |
||||
} |
||||
labels[baremetalPublicIPv6Label] = model.LabelValue(ip.Address.String()) |
||||
if _, ok := labels[model.AddressLabel]; !ok { |
||||
// This server does not have an IPv4 or we have not parsed it
|
||||
// yet.
|
||||
addr := net.JoinHostPort(ip.Address.String(), strconv.FormatUint(uint64(d.port), 10)) |
||||
labels[model.AddressLabel] = model.LabelValue(addr) |
||||
} |
||||
default: |
||||
return nil, fmt.Errorf("unknown IP version: %s", v) |
||||
} |
||||
} |
||||
targets = append(targets, labels) |
||||
} |
||||
return []*targetgroup.Group{{Source: "scaleway", Targets: targets}}, nil |
||||
} |
@ -0,0 +1,155 @@
|
||||
// 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 scaleway |
||||
|
||||
import ( |
||||
"context" |
||||
"fmt" |
||||
"net" |
||||
"net/http" |
||||
"strconv" |
||||
"strings" |
||||
"time" |
||||
|
||||
"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/scaleway/scaleway-sdk-go/api/instance/v1" |
||||
"github.com/scaleway/scaleway-sdk-go/scw" |
||||
) |
||||
|
||||
const ( |
||||
instanceLabelPrefix = metaLabelPrefix + "instance_" |
||||
|
||||
instanceIDLabel = instanceLabelPrefix + "id" |
||||
instancePrivateIPv4 = instanceLabelPrefix + "private_ipv4" |
||||
instancePublicIPv4 = instanceLabelPrefix + "public_ipv4" |
||||
instancePublicIPv6 = instanceLabelPrefix + "public_ipv6" |
||||
instanceImageNameLabel = instanceLabelPrefix + "image_name" |
||||
instanceNameLabel = instanceLabelPrefix + "name" |
||||
instanceProjectLabel = instanceLabelPrefix + "project_id" |
||||
instanceStateLabel = instanceLabelPrefix + "status" |
||||
instanceTagsLabel = instanceLabelPrefix + "tags" |
||||
instanceTypeLabel = instanceLabelPrefix + "type" |
||||
instanceZoneLabel = instanceLabelPrefix + "zone" |
||||
) |
||||
|
||||
type instanceDiscovery struct { |
||||
*refresh.Discovery |
||||
client *scw.Client |
||||
port int |
||||
zone string |
||||
project string |
||||
accessKey string |
||||
secretKey string |
||||
nameFilter string |
||||
tagsFilter []string |
||||
} |
||||
|
||||
func newInstanceDiscovery(conf *SDConfig) (*instanceDiscovery, error) { |
||||
d := &instanceDiscovery{ |
||||
port: conf.Port, |
||||
zone: conf.Zone, |
||||
project: conf.Project, |
||||
accessKey: conf.AccessKey, |
||||
secretKey: string(conf.SecretKey), |
||||
nameFilter: conf.NameFilter, |
||||
tagsFilter: conf.TagsFilter, |
||||
} |
||||
|
||||
rt, err := config.NewRoundTripperFromConfig(conf.HTTPClientConfig, "scaleway_sd", false, false) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
profile, err := loadProfile(conf) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
d.client, err = scw.NewClient( |
||||
scw.WithHTTPClient(&http.Client{ |
||||
Transport: rt, |
||||
Timeout: time.Duration(conf.RefreshInterval), |
||||
}), |
||||
scw.WithUserAgent(fmt.Sprintf("Prometheus/%s", version.Version)), |
||||
scw.WithProfile(profile), |
||||
) |
||||
if err != nil { |
||||
return nil, fmt.Errorf("error setting up scaleway client: %w", err) |
||||
} |
||||
|
||||
return d, nil |
||||
} |
||||
|
||||
func (d *instanceDiscovery) refresh(ctx context.Context) ([]*targetgroup.Group, error) { |
||||
api := instance.NewAPI(d.client) |
||||
|
||||
req := &instance.ListServersRequest{} |
||||
|
||||
if d.nameFilter != "" { |
||||
req.Name = scw.StringPtr(d.nameFilter) |
||||
} |
||||
|
||||
if d.tagsFilter != nil { |
||||
req.Tags = d.tagsFilter |
||||
} |
||||
|
||||
servers, err := api.ListServers(req, scw.WithAllPages(), scw.WithContext(ctx)) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
var targets []model.LabelSet |
||||
for _, server := range servers.Servers { |
||||
labels := model.LabelSet{ |
||||
instanceIDLabel: model.LabelValue(server.ID), |
||||
instanceImageNameLabel: model.LabelValue(server.Image.Name), |
||||
instanceNameLabel: model.LabelValue(server.Name), |
||||
instanceProjectLabel: model.LabelValue(server.Project), |
||||
instanceStateLabel: model.LabelValue(server.State), |
||||
instanceTypeLabel: model.LabelValue(server.CommercialType), |
||||
instanceZoneLabel: model.LabelValue(server.Zone.String()), |
||||
} |
||||
|
||||
if len(server.Tags) > 0 { |
||||
// We surround the separated list with the separator as well. This way regular expressions
|
||||
// in relabeling rules don't have to consider tag positions.
|
||||
tags := separator + strings.Join(server.Tags, separator) + separator |
||||
labels[instanceTagsLabel] = model.LabelValue(tags) |
||||
} |
||||
|
||||
if server.IPv6 != nil { |
||||
labels[instancePublicIPv6] = model.LabelValue(server.IPv6.Address.String()) |
||||
} |
||||
|
||||
if server.PublicIP != nil { |
||||
labels[instancePublicIPv4] = model.LabelValue(server.PublicIP.Address.String()) |
||||
} |
||||
|
||||
if server.PrivateIP != nil { |
||||
labels[instancePrivateIPv4] = model.LabelValue(*server.PrivateIP) |
||||
|
||||
addr := net.JoinHostPort(*server.PrivateIP, strconv.FormatUint(uint64(d.port), 10)) |
||||
labels[model.AddressLabel] = model.LabelValue(addr) |
||||
|
||||
targets = append(targets, labels) |
||||
} |
||||
|
||||
} |
||||
|
||||
return []*targetgroup.Group{{Source: "scaleway", Targets: targets}}, nil |
||||
} |
@ -0,0 +1,200 @@
|
||||
// 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 scaleway |
||||
|
||||
import ( |
||||
"context" |
||||
"time" |
||||
|
||||
"github.com/go-kit/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" |
||||
"github.com/prometheus/prometheus/discovery/targetgroup" |
||||
"github.com/scaleway/scaleway-sdk-go/scw" |
||||
) |
||||
|
||||
// metaLabelPrefix is the meta prefix used for all meta labels.
|
||||
// in this discovery.
|
||||
const ( |
||||
metaLabelPrefix = model.MetaLabelPrefix + "scaleway_" |
||||
separator = "," |
||||
) |
||||
|
||||
// role is the role of the target within the Scaleway Ecosystem.
|
||||
type role string |
||||
|
||||
// The valid options for role.
|
||||
const ( |
||||
// Scaleway Elements Baremetal
|
||||
// https://www.scaleway.com/en/bare-metal-servers/
|
||||
roleBaremetal role = "baremetal" |
||||
|
||||
// Scaleway Elements Instance
|
||||
// https://www.scaleway.com/en/virtual-instances/
|
||||
roleInstance role = "instance" |
||||
) |
||||
|
||||
// UnmarshalYAML implements the yaml.Unmarshaler interface.
|
||||
func (c *role) UnmarshalYAML(unmarshal func(interface{}) error) error { |
||||
if err := unmarshal((*string)(c)); err != nil { |
||||
return err |
||||
} |
||||
switch *c { |
||||
case roleInstance, roleBaremetal: |
||||
return nil |
||||
default: |
||||
return errors.Errorf("unknown role %q", *c) |
||||
} |
||||
} |
||||
|
||||
// DefaultSDConfig is the default Scaleway Service Discovery configuration.
|
||||
var DefaultSDConfig = SDConfig{ |
||||
Port: 80, |
||||
RefreshInterval: model.Duration(60 * time.Second), |
||||
HTTPClientConfig: config.DefaultHTTPClientConfig, |
||||
Zone: scw.ZoneFrPar1.String(), |
||||
APIURL: "https://api.scaleway.com", |
||||
} |
||||
|
||||
type SDConfig struct { |
||||
// Project: The Scaleway Project ID used to filter discovery on.
|
||||
Project string `yaml:"project_id"` |
||||
|
||||
// APIURL: URL of the Scaleway API to use.
|
||||
APIURL string `yaml:"api_url,omitempty"` |
||||
// Zone: The zone of the scrape targets.
|
||||
// If you need to configure multiple zones use multiple scaleway_sd_configs
|
||||
Zone string `yaml:"zone"` |
||||
// AccessKey used to authenticate on Scaleway APIs.
|
||||
AccessKey string `yaml:"access_key"` |
||||
// SecretKey used to authenticate on Scaleway APIs.
|
||||
SecretKey config.Secret `yaml:"secret_key"` |
||||
// NameFilter to filter on during the ListServers.
|
||||
NameFilter string `yaml:"name_filter,omitempty"` |
||||
// TagsFilter to filter on during the ListServers.
|
||||
TagsFilter []string `yaml:"tags_filter,omitempty"` |
||||
|
||||
HTTPClientConfig config.HTTPClientConfig `yaml:",inline"` |
||||
|
||||
RefreshInterval model.Duration `yaml:"refresh_interval"` |
||||
Port int `yaml:"port"` |
||||
// Role can be either instance or baremetal
|
||||
Role role `yaml:"role"` |
||||
} |
||||
|
||||
func (c SDConfig) Name() string { |
||||
return "scaleway" |
||||
} |
||||
|
||||
// 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.Role == "" { |
||||
return errors.New("role missing (one of: instance, baremetal)") |
||||
} |
||||
|
||||
if c.Project == "" { |
||||
return errors.New("project_id is mandatory") |
||||
} |
||||
|
||||
if c.SecretKey == "" { |
||||
return errors.New("secret_key is mandatory") |
||||
} |
||||
|
||||
if c.AccessKey == "" { |
||||
return errors.New("access_key is mandatory") |
||||
} |
||||
|
||||
profile, err := loadProfile(c) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
_, err = scw.NewClient( |
||||
scw.WithProfile(profile), |
||||
) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
|
||||
return c.HTTPClientConfig.Validate() |
||||
} |
||||
|
||||
func (c SDConfig) NewDiscoverer(options discovery.DiscovererOptions) (discovery.Discoverer, error) { |
||||
return NewDiscovery(&c, options.Logger) |
||||
} |
||||
|
||||
// SetDirectory joins any relative file paths with dir.
|
||||
func (c *SDConfig) SetDirectory(dir string) { |
||||
c.HTTPClientConfig.SetDirectory(dir) |
||||
} |
||||
|
||||
func init() { |
||||
discovery.RegisterConfig(&SDConfig{}) |
||||
} |
||||
|
||||
// Discovery periodically performs Scaleway requests. It implements
|
||||
// the Discoverer interface.
|
||||
type Discovery struct { |
||||
} |
||||
|
||||
func NewDiscovery(conf *SDConfig, logger log.Logger) (*refresh.Discovery, error) { |
||||
r, err := newRefresher(conf) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
return refresh.NewDiscovery( |
||||
logger, |
||||
"scaleway", |
||||
time.Duration(conf.RefreshInterval), |
||||
r.refresh, |
||||
), nil |
||||
} |
||||
|
||||
type refresher interface { |
||||
refresh(context.Context) ([]*targetgroup.Group, error) |
||||
} |
||||
|
||||
func newRefresher(conf *SDConfig) (refresher, error) { |
||||
switch conf.Role { |
||||
case roleBaremetal: |
||||
return newBaremetalDiscovery(conf) |
||||
case roleInstance: |
||||
return newInstanceDiscovery(conf) |
||||
} |
||||
return nil, errors.New("unknown Scaleway discovery role") |
||||
} |
||||
|
||||
func loadProfile(sdConfig *SDConfig) (*scw.Profile, error) { |
||||
// Profile coming from Prometheus Configuration file
|
||||
prometheusConfigProfile := &scw.Profile{ |
||||
DefaultZone: scw.StringPtr(sdConfig.Zone), |
||||
APIURL: scw.StringPtr(sdConfig.APIURL), |
||||
SecretKey: scw.StringPtr(string(sdConfig.SecretKey)), |
||||
AccessKey: scw.StringPtr(sdConfig.AccessKey), |
||||
DefaultProjectID: scw.StringPtr(sdConfig.Project), |
||||
SendTelemetry: scw.BoolPtr(false), |
||||
} |
||||
|
||||
return prometheusConfigProfile, nil |
||||
} |
@ -0,0 +1,41 @@
|
||||
# A example scrape configuration for running Prometheus with Scaleway. |
||||
scrape_configs: |
||||
- job_name: 'prometheus' |
||||
scaleway_sd_configs: |
||||
- role: instance |
||||
# You can find you project ID here: https://console.scaleway.com/project/settings |
||||
project_id: 11111111-1111-1111-1111-111111111111 |
||||
# Replace with Scaleway Credentials: https://console.scaleway.com/project/credentials |
||||
access_key: SCWXXXXXXXXXXXXXXXXX |
||||
secret_key: 11111111-1111-1111-1111-111111111111 |
||||
relabel_configs: |
||||
# Only scrape targets that have a tag 'prometheus'. |
||||
- source_labels: [__meta_scaleway_instance_tags] |
||||
regex: '.*,prometheus,.*' |
||||
action: keep |
||||
# Use the public IPv6 address and port 9100 to scrape the target. |
||||
- source_labels: [__meta_scaleway_instance_public_ipv6] |
||||
target_label: __address__ |
||||
replacement: '[$1]:9090' |
||||
# Add the zone as label |
||||
- source_labels: [__meta_scaleway_instance_zone] |
||||
target_label: scw_zone |
||||
|
||||
- job_name: 'node' |
||||
scaleway_sd_configs: |
||||
- role: baremetal |
||||
# You can find you project ID here: https://console.scaleway.com/project/settings |
||||
project_id: 11111111-1111-1111-1111-111111111111 |
||||
zone: fr-par-2 |
||||
# Replace with Scaleway Credentials: https://console.scaleway.com/project/credentials |
||||
access_key: SCWXXXXXXXXXXXXXXXXX |
||||
secret_key: 11111111-1111-1111-1111-111111111111 |
||||
relabel_configs: |
||||
# Filter out servers that are not physically in the datacenter. |
||||
- source_labels: [__meta_scaleway_baremetal_status] |
||||
regex: '(delivering|out_of_stock)' |
||||
action: drop |
||||
# Use the public IPv6 address and port 9100 to scrape the target. |
||||
- source_labels: [__meta_scaleway_baremetal_public_ipv6] |
||||
target_label: __address__ |
||||
replacement: '[$1]:9100' |
Loading…
Reference in new issue