From 4456dcc26e583c2c5c028ad61c8f9f58c75ef27b Mon Sep 17 00:00:00 2001 From: Bram Vogelaar Date: Sat, 25 Jun 2022 22:47:42 +0200 Subject: [PATCH] feat(nomad): add nomad service discovery Signed-off-by: Bram Vogelaar --- config/config_test.go | 27 +++ config/testdata/conf.good.yml | 4 + discovery/install/install.go | 1 + discovery/nomad/nomad.go | 208 ++++++++++++++++++++ discovery/nomad/nomad_test.go | 172 ++++++++++++++++ docs/configuration/configuration.md | 75 +++++++ documentation/examples/prometheus-nomad.yml | 23 +++ go.mod | 3 + go.sum | 14 +- plugins.yml | 1 + plugins/plugins.go | 3 + 11 files changed, 529 insertions(+), 2 deletions(-) create mode 100644 discovery/nomad/nomad.go create mode 100644 discovery/nomad/nomad_test.go create mode 100644 documentation/examples/prometheus-nomad.yml diff --git a/config/config_test.go b/config/config_test.go index dc8ab742b..54b4e2b11 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -45,6 +45,7 @@ import ( "github.com/prometheus/prometheus/discovery/linode" "github.com/prometheus/prometheus/discovery/marathon" "github.com/prometheus/prometheus/discovery/moby" + "github.com/prometheus/prometheus/discovery/nomad" "github.com/prometheus/prometheus/discovery/openstack" "github.com/prometheus/prometheus/discovery/puppetdb" "github.com/prometheus/prometheus/discovery/scaleway" @@ -513,6 +514,32 @@ var expectedConf = &Config{ }, }, }, + { + JobName: "service-nomad", + + HonorTimestamps: true, + ScrapeInterval: model.Duration(15 * time.Second), + ScrapeTimeout: DefaultGlobalConfig.ScrapeTimeout, + + MetricsPath: DefaultScrapeConfig.MetricsPath, + Scheme: DefaultScrapeConfig.Scheme, + HTTPClientConfig: config.DefaultHTTPClientConfig, + + ServiceDiscoveryConfigs: discovery.Configs{ + &nomad.SDConfig{ + AllowStale: true, + Namespace: "default", + RefreshInterval: model.Duration(60 * time.Second), + Region: "global", + Server: "http://localhost:4646", + TagSeparator: ",", + HTTPClientConfig: config.HTTPClientConfig{ + FollowRedirects: true, + EnableHTTP2: true, + }, + }, + }, + }, { JobName: "service-ec2", diff --git a/config/testdata/conf.good.yml b/config/testdata/conf.good.yml index e217a82ea..a894907c5 100644 --- a/config/testdata/conf.good.yml +++ b/config/testdata/conf.good.yml @@ -214,6 +214,10 @@ scrape_configs: cert_file: valid_cert_file key_file: valid_key_file + - job_name: service-nomad + nomad_sd_configs: + - server: 'http://localhost:4646' + - job_name: service-ec2 ec2_sd_configs: - region: us-east-1 diff --git a/discovery/install/install.go b/discovery/install/install.go index d8a5a82cb..36e13948d 100644 --- a/discovery/install/install.go +++ b/discovery/install/install.go @@ -31,6 +31,7 @@ import ( _ "github.com/prometheus/prometheus/discovery/linode" // register linode _ "github.com/prometheus/prometheus/discovery/marathon" // register marathon _ "github.com/prometheus/prometheus/discovery/moby" // register moby + _ "github.com/prometheus/prometheus/discovery/nomad" // register nomad _ "github.com/prometheus/prometheus/discovery/openstack" // register openstack _ "github.com/prometheus/prometheus/discovery/puppetdb" // register puppetdb _ "github.com/prometheus/prometheus/discovery/scaleway" // register scaleway diff --git a/discovery/nomad/nomad.go b/discovery/nomad/nomad.go new file mode 100644 index 000000000..c29c67f7d --- /dev/null +++ b/discovery/nomad/nomad.go @@ -0,0 +1,208 @@ +// 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 nomad + +import ( + "context" + "errors" + "fmt" + "net" + "strconv" + "strings" + "time" + + "github.com/go-kit/log" + nomad "github.com/hashicorp/nomad/api" + "github.com/prometheus/client_golang/prometheus" + "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" +) + +const ( + // nomadLabel is the name for the label containing a target. + nomadLabel = model.MetaLabelPrefix + "nomad_" + // serviceLabel is the name of the label containing the service name. + nomadAddress = nomadLabel + "address" + nomadService = nomadLabel + "service" + nomadNamespace = nomadLabel + "namespace" + nomadNodeID = nomadLabel + "node_id" + nomadDatacenter = nomadLabel + "dc" + nomadServiceAddress = nomadService + "_address" + nomadServicePort = nomadService + "_port" + nomadServiceID = nomadService + "_id" + nomadTags = nomadLabel + "tags" +) + +// DefaultSDConfig is the default nomad SD configuration. +var ( + DefaultSDConfig = SDConfig{ + AllowStale: true, + HTTPClientConfig: config.DefaultHTTPClientConfig, + Namespace: "default", + RefreshInterval: model.Duration(60 * time.Second), + Region: "global", + Server: "http://localhost:4646", + TagSeparator: ",", + } + + failuresCount = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "prometheus_sd_nomad_failures_total", + Help: "Number of nomad service discovery refresh failures.", + }) +) + +func init() { + discovery.RegisterConfig(&SDConfig{}) + prometheus.MustRegister(failuresCount) +} + +// SDConfig is the configuration for nomad based service discovery. +type SDConfig struct { + AllowStale bool `yaml:"allow_stale"` + HTTPClientConfig config.HTTPClientConfig `yaml:",inline"` + Namespace string `yaml:"namespace"` + RefreshInterval model.Duration `yaml:"refresh_interval"` + Region string `yaml:"region"` + Server string `yaml:"server"` + TagSeparator string `yaml:"tag_separator,omitempty"` +} + +// Name returns the name of the Config. +func (*SDConfig) Name() string { return "nomad" } + +// 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 + err := unmarshal((*plain)(c)) + if err != nil { + return err + } + if strings.TrimSpace(c.Server) == "" { + return errors.New("nomad SD configuration requires a server address") + } + return c.HTTPClientConfig.Validate() +} + +// Discovery periodically performs nomad requests. It implements +// the Discoverer interface. +type Discovery struct { + *refresh.Discovery + allowStale bool + client *nomad.Client + namespace string + refreshInterval time.Duration + region string + server string + tagSeparator string +} + +// NewDiscovery returns a new Discovery which periodically refreshes its targets. +func NewDiscovery(conf *SDConfig, logger log.Logger) (*Discovery, error) { + d := &Discovery{ + allowStale: conf.AllowStale, + namespace: conf.Namespace, + refreshInterval: time.Duration(conf.RefreshInterval), + region: conf.Region, + server: conf.Server, + tagSeparator: conf.TagSeparator, + } + + HTTPClient, err := config.NewClientFromConfig(conf.HTTPClientConfig, "nomad_sd") + if err != nil { + return nil, err + } + + config := nomad.Config{ + Address: conf.Server, + HttpClient: HTTPClient, + Namespace: conf.Namespace, + Region: conf.Region, + } + + client, err := nomad.NewClient(&config) + if err != nil { + return nil, err + } + d.client = client + + d.Discovery = refresh.NewDiscovery( + logger, + "nomad", + time.Duration(conf.RefreshInterval), + d.refresh, + ) + return d, nil +} + +func (d *Discovery) refresh(ctx context.Context) ([]*targetgroup.Group, error) { + opts := &nomad.QueryOptions{ + AllowStale: d.allowStale, + } + stubs, _, err := d.client.Services().List(opts) + if err != nil { + return nil, err + } + + tg := &targetgroup.Group{ + Source: "Nomad", + } + + for _, stub := range stubs { + for _, service := range stub.Services { + instances, _, err := d.client.Services().Get(service.ServiceName, opts) + if err != nil { + return nil, fmt.Errorf("failed to fetch services: %w", err) + } + + for _, instance := range instances { + labels := model.LabelSet{ + nomadAddress: model.LabelValue(instance.Address), + nomadDatacenter: model.LabelValue(instance.Datacenter), + nomadNodeID: model.LabelValue(instance.NodeID), + nomadNamespace: model.LabelValue(instance.Namespace), + nomadServiceAddress: model.LabelValue(instance.Address), + nomadServiceID: model.LabelValue(instance.ID), + nomadServicePort: model.LabelValue(strconv.Itoa(instance.Port)), + nomadService: model.LabelValue(instance.ServiceName), + } + addr := net.JoinHostPort(instance.Address, strconv.FormatInt(int64(instance.Port), 10)) + labels[model.AddressLabel] = model.LabelValue(addr) + + if len(instance.Tags) > 0 { + tags := d.tagSeparator + strings.Join(instance.Tags, d.tagSeparator) + d.tagSeparator + labels[nomadTags] = model.LabelValue(tags) + } + + tg.Targets = append(tg.Targets, labels) + } + } + } + return []*targetgroup.Group{tg}, nil +} diff --git a/discovery/nomad/nomad_test.go b/discovery/nomad/nomad_test.go new file mode 100644 index 000000000..ab23f1fe4 --- /dev/null +++ b/discovery/nomad/nomad_test.go @@ -0,0 +1,172 @@ +// Copyright 2015 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 nomad + +import ( + "context" + "fmt" + "net/http" + "net/http/httptest" + "net/url" + "testing" + + "github.com/go-kit/log" + "github.com/prometheus/common/model" + "github.com/stretchr/testify/require" +) + +type NomadSDTestSuite struct { + Mock *SDMock +} + +// SDMock is the interface for the nomad 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() +} + +func (s *NomadSDTestSuite) TearDownSuite() { + s.Mock.ShutdownServer() +} + +func (s *NomadSDTestSuite) SetupTest(t *testing.T) { + s.Mock = NewSDMock(t) + s.Mock.Setup() + + s.Mock.HandleServicesList() + s.Mock.HandleServiceHashiCupsGet() +} + +func (m *SDMock) HandleServicesList() { + m.Mux.HandleFunc("/v1/services", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("content-type", "application/json; charset=utf-8") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, ` + [ + { + "Namespace": "default", + "Services": [ + { + "ServiceName": "hashicups", + "Tags": [ + "metrics" + ] + } + ] + } + ]`, + ) + }) +} + +func (m *SDMock) HandleServiceHashiCupsGet() { + m.Mux.HandleFunc("/v1/service/hashicups", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("content-type", "application/json; charset=utf-8") + w.WriteHeader(http.StatusOK) + + fmt.Fprint(w, ` + [ + { + "ID": "_nomad-task-6a1d5f0a-7362-3f5d-9baf-5ed438918e50-group-hashicups-hashicups-hashicups_ui", + "ServiceName": "hashicups", + "Namespace": "default", + "NodeID": "d92fdc3c-9c2b-298a-e8f4-c33f3a449f09", + "Datacenter": "dc1", + "JobID": "dashboard", + "AllocID": "6a1d5f0a-7362-3f5d-9baf-5ed438918e50", + "Tags": [ + "metrics" + ], + "Address": "127.0.0.1", + "Port": 30456, + "CreateIndex": 226, + "ModifyIndex": 226 + } + ]`, + ) + }) +} + +func TestConfiguredService(t *testing.T) { + conf := &SDConfig{ + Server: "http://localhost:4646", + } + _, err := NewDiscovery(conf, nil) + if err != nil { + t.Errorf("Unexpected error when initializing discovery %v", err) + } +} + +func TestNomadSDRefresh(t *testing.T) { + sdmock := &NomadSDTestSuite{} + sdmock.SetupTest(t) + t.Cleanup(sdmock.TearDownSuite) + + endpoint, err := url.Parse(sdmock.Mock.Endpoint()) + require.NoError(t, err) + + cfg := DefaultSDConfig + cfg.Server = endpoint.String() + d, err := NewDiscovery(&cfg, log.NewNopLogger()) + require.NoError(t, err) + + tgs, err := d.refresh(context.Background()) + 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, 1, len(tg.Targets)) + + lbls := model.LabelSet{ + "__address__": model.LabelValue("127.0.0.1:30456"), + "__meta_nomad_address": model.LabelValue("127.0.0.1"), + "__meta_nomad_dc": model.LabelValue("dc1"), + "__meta_nomad_namespace": model.LabelValue("default"), + "__meta_nomad_node_id": model.LabelValue("d92fdc3c-9c2b-298a-e8f4-c33f3a449f09"), + "__meta_nomad_service": model.LabelValue("hashicups"), + "__meta_nomad_service_address": model.LabelValue("127.0.0.1"), + "__meta_nomad_service_id": model.LabelValue("_nomad-task-6a1d5f0a-7362-3f5d-9baf-5ed438918e50-group-hashicups-hashicups-hashicups_ui"), + "__meta_nomad_service_port": model.LabelValue("30456"), + "__meta_nomad_tags": model.LabelValue(",metrics,"), + } + require.Equal(t, lbls, tg.Targets[0]) +} diff --git a/docs/configuration/configuration.md b/docs/configuration/configuration.md index b1e3bb47d..d36db3359 100644 --- a/docs/configuration/configuration.md +++ b/docs/configuration/configuration.md @@ -285,6 +285,10 @@ marathon_sd_configs: nerve_sd_configs: [ - ... ] +# List of Nomad service discovery configurations. +nomad_sd_configs: + [ - ... ] + # List of OpenStack service discovery configurations. openstack_sd_configs: [ - ... ] @@ -2174,6 +2178,73 @@ paths: - [ timeout: | default = 10s ] ``` +### `` + +Nomad SD configurations allow retrieving scrape targets from [Nomad's](https://www.nomadproject.io/) +Service API. + +The following meta labels are available on targets during [relabeling](#relabel_config): + +* `__meta_nomad_address`: the service address of the target +* `__meta_nomad_dc`: the datacenter name for the target +* `__meta_nomad_namespace`: the namespace of the target +* `__meta_nomad_node`: the node name defined for the target +* `__meta_nomad_service`: the name of the service the target belongs to +* `__meta_nomad_service_address`: the service address of the target +* `__meta_nomad_service_id`: the service ID of the target +* `__meta_nomad_service_port`: the service port of the target +* `__meta_nomad_tags`: the list of tags of the target joined by the tag separator + +```yaml +# The information to access the Nomad API. It is to be defined +# as the Nomad documentation requires. +[ allow_stale: | default = true ] +[ datacenter: ] +[ namespace: | default = default ] +[ refresh_interval: | default = 60s ] +[ region: | default = global ] +[ server: ] +[ tag_separator: | default = ,] + +# Authentication information used to authenticate to the nomad server. +# Note that `basic_auth`, `authorization` and `oauth2` options are +# mutually exclusive. +# `password` and `password_file` are mutually exclusive. + +# Optional HTTP basic authentication information. +basic_auth: + [ username: ] + [ password: ] + [ password_file: ] + +# Optional `Authorization` header configuration. +authorization: + # Sets the authentication type. + [ type: | default: Bearer ] + # Sets the credentials. It is mutually exclusive with + # `credentials_file`. + [ credentials: ] + # Sets the credentials to the credentials read from the configured file. + # It is mutually exclusive with `credentials`. + [ credentials_file: ] + +# Optional OAuth 2.0 configuration. +oauth2: + [ ] + +# Optional proxy URL. +[ proxy_url: ] + +# Configure whether HTTP requests follow HTTP 3xx redirects. +[ follow_redirects: | default = true ] + +# Whether to enable HTTP2. +[ enable_http2: | default: true ] + +# TLS configuration. +tls_config: + [ ] +``` ### `` @@ -2866,6 +2937,10 @@ marathon_sd_configs: nerve_sd_configs: [ - ... ] +# List of Nomad service discovery configurations. +nomad_sd_configs: + [ - ... ] + # List of OpenStack service discovery configurations. openstack_sd_configs: [ - ... ] diff --git a/documentation/examples/prometheus-nomad.yml b/documentation/examples/prometheus-nomad.yml new file mode 100644 index 000000000..4811a54ce --- /dev/null +++ b/documentation/examples/prometheus-nomad.yml @@ -0,0 +1,23 @@ +# An example scrape configuration for running Prometheus with +# Nomad build in service discovery. +# +# The following config can be used to monitor services running on +# a nomad that is started using the getting started tutorial [1] +# +# sudo nomad agent -dev -bind 0.0.0.0 -log-level INFO +# +# [1] https://learn.hashicorp.com/tutorials/nomad/get-started-run?in=nomad/get-started + +scrape_configs: + # Make Prometheus scrape itself for metrics. + - job_name: "prometheus" + static_configs: + - targets: ["localhost:9090"] + + # Discover Nomad services to scrape. + - job_name: 'nomad_sd' + nomad_sd_configs: + - server: 'http://localhost:4646' + relabel_configs: + - source_labels: [__meta_nomad_service] + target_label: job diff --git a/go.mod b/go.mod index 60bc29fa9..94c3bc082 100644 --- a/go.mod +++ b/go.mod @@ -28,6 +28,7 @@ require ( github.com/grafana/regexp v0.0.0-20220304095617-2e8d9baf4ac2 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/hashicorp/consul/api v1.13.0 + github.com/hashicorp/nomad/api v0.0.0-20220621200911-46b41bc256ee github.com/hetznercloud/hcloud-go v1.33.2 github.com/ionos-cloud/sdk-go/v6 v6.0.5851 github.com/json-iterator/go v1.1.12 @@ -128,7 +129,9 @@ require ( github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.2.0 // indirect github.com/googleapis/gax-go/v2 v2.4.0 // indirect + github.com/gorilla/websocket v1.4.2 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.2 // indirect + github.com/hashicorp/cronexpr v1.1.1 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-hclog v0.12.2 // indirect github.com/hashicorp/go-immutable-radix v1.2.0 // indirect diff --git a/go.sum b/go.sum index 1e6309e53..48c2e5920 100644 --- a/go.sum +++ b/go.sum @@ -187,6 +187,7 @@ github.com/docker/docker v20.10.16+incompatible h1:2Db6ZR/+FUR3hqPMwnogOPHFn405c github.com/docker/docker v20.10.16+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= @@ -444,6 +445,7 @@ github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grafana/regexp v0.0.0-20220304095617-2e8d9baf4ac2 h1:uirlL/j72L93RhV4+mkWhjv0cov2I0MIgPOG9rMDr1k= github.com/grafana/regexp v0.0.0-20220304095617-2e8d9baf4ac2/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= @@ -462,6 +464,8 @@ github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.8.0 h1:OJtKBtEjboEZvG6AOUdh4Z1Zbyu0WcxQ0qatRrZHTVU= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= +github.com/hashicorp/cronexpr v1.1.1 h1:NJZDd87hGXjoZBdvyCF9mX4DCq5Wy7+A/w+A7q0wn6c= +github.com/hashicorp/cronexpr v1.1.1/go.mod h1:P4wA0KBl9C5q2hABiMO7cp6jcIg96CDh1Efb3g1PWA4= 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/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= @@ -507,6 +511,8 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/memberlist v0.3.1 h1:MXgUXLqva1QvpVEDQW1IQLG0wivQAtmFlHRQ+1vWZfM= github.com/hashicorp/memberlist v0.3.1/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/nomad/api v0.0.0-20220621200911-46b41bc256ee h1:mI5pzBBNGDNkvO28JkIIaQQ6L/pY+IG4uX3LVLrMb/o= +github.com/hashicorp/nomad/api v0.0.0-20220621200911-46b41bc256ee/go.mod h1:b/AoT79m3PEpb6tKCFKva/M+q1rKJNUk5mdu1S8DymM= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/serf v0.9.6 h1:uuEX1kLR6aoda1TBttmJQKDLZE1Ob7KN0NPdE7EtCDc= github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= @@ -566,8 +572,9 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -616,8 +623,9 @@ github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXx github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= @@ -764,6 +772,8 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= diff --git a/plugins.yml b/plugins.yml index ee1809ce4..c83c806db 100644 --- a/plugins.yml +++ b/plugins.yml @@ -11,6 +11,7 @@ - github.com/prometheus/prometheus/discovery/linode - github.com/prometheus/prometheus/discovery/marathon - github.com/prometheus/prometheus/discovery/moby +- github.com/prometheus/prometheus/discovery/nomad - github.com/prometheus/prometheus/discovery/openstack - github.com/prometheus/prometheus/discovery/puppetdb - github.com/prometheus/prometheus/discovery/scaleway diff --git a/plugins/plugins.go b/plugins/plugins.go index 6a7b6e531..60d8d791b 100644 --- a/plugins/plugins.go +++ b/plugins/plugins.go @@ -55,6 +55,9 @@ import ( // Register moby plugin. _ "github.com/prometheus/prometheus/discovery/moby" + // Register nomad plugin. + _ "github.com/prometheus/prometheus/discovery/nomad" + // Register openstack plugin. _ "github.com/prometheus/prometheus/discovery/openstack"