diff --git a/config/config_test.go b/config/config_test.go index 905792a25..bd992bedb 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -30,6 +30,7 @@ import ( "github.com/prometheus/prometheus/discovery/file" "github.com/prometheus/prometheus/discovery/kubernetes" "github.com/prometheus/prometheus/discovery/marathon" + "github.com/prometheus/prometheus/discovery/openstack" "github.com/prometheus/prometheus/discovery/targetgroup" "github.com/prometheus/prometheus/discovery/triton" "github.com/prometheus/prometheus/discovery/zookeeper" @@ -538,6 +539,31 @@ var expectedConf = &Config{ }, }, }, + { + JobName: "service-openstack", + + ScrapeInterval: model.Duration(15 * time.Second), + ScrapeTimeout: DefaultGlobalConfig.ScrapeTimeout, + + MetricsPath: DefaultScrapeConfig.MetricsPath, + Scheme: DefaultScrapeConfig.Scheme, + + ServiceDiscoveryConfig: sd_config.ServiceDiscoveryConfig{ + OpenstackSDConfigs: []*openstack.SDConfig{ + { + Role: "instance", + Region: "RegionOne", + Port: 80, + RefreshInterval: model.Duration(60 * time.Second), + TLSConfig: config_util.TLSConfig{ + CAFile: "valid_ca_file", + CertFile: "valid_cert_file", + KeyFile: "valid_key_file", + }, + }, + }, + }, + }, }, AlertingConfig: AlertingConfig{ AlertmanagerConfigs: []*AlertmanagerConfig{ diff --git a/config/testdata/conf.good.yml b/config/testdata/conf.good.yml index e7c6030a1..5abadc212 100644 --- a/config/testdata/conf.good.yml +++ b/config/testdata/conf.good.yml @@ -233,6 +233,17 @@ scrape_configs: cert_file: testdata/valid_cert_file key_file: testdata/valid_key_file +- job_name: service-openstack + openstack_sd_configs: + - role: instance + region: RegionOne + port: 80 + refresh_interval: 1m + tls_config: + ca_file: valid_ca_file + cert_file: valid_cert_file + key_file: valid_key_file + alerting: alertmanagers: - scheme: https diff --git a/discovery/openstack/hypervisor.go b/discovery/openstack/hypervisor.go index 3d7a304f7..9e81c7aa8 100644 --- a/discovery/openstack/hypervisor.go +++ b/discovery/openstack/hypervisor.go @@ -39,6 +39,7 @@ const ( // HypervisorDiscovery discovers OpenStack hypervisors. type HypervisorDiscovery struct { + provider *gophercloud.ProviderClient authOpts *gophercloud.AuthOptions region string interval time.Duration @@ -47,9 +48,9 @@ type HypervisorDiscovery struct { } // NewHypervisorDiscovery returns a new hypervisor discovery. -func NewHypervisorDiscovery(opts *gophercloud.AuthOptions, +func NewHypervisorDiscovery(provider *gophercloud.ProviderClient, opts *gophercloud.AuthOptions, interval time.Duration, port int, region string, l log.Logger) *HypervisorDiscovery { - return &HypervisorDiscovery{authOpts: opts, + return &HypervisorDiscovery{provider: provider, authOpts: opts, region: region, interval: interval, port: port, logger: l} } @@ -100,11 +101,11 @@ func (h *HypervisorDiscovery) refresh() (*targetgroup.Group, error) { } }() - provider, err := openstack.AuthenticatedClient(*h.authOpts) + err = openstack.Authenticate(h.provider, *h.authOpts) if err != nil { - return nil, fmt.Errorf("could not create OpenStack session: %s", err) + return nil, fmt.Errorf("could not authenticate to OpenStack: %s", err) } - client, err := openstack.NewComputeV2(provider, gophercloud.EndpointOpts{ + client, err := openstack.NewComputeV2(h.provider, gophercloud.EndpointOpts{ Region: h.region, }) if err != nil { diff --git a/discovery/openstack/instance.go b/discovery/openstack/instance.go index f588f6573..a5a54c3c5 100644 --- a/discovery/openstack/instance.go +++ b/discovery/openstack/instance.go @@ -45,6 +45,7 @@ const ( // InstanceDiscovery discovers OpenStack instances. type InstanceDiscovery struct { + provider *gophercloud.ProviderClient authOpts *gophercloud.AuthOptions region string interval time.Duration @@ -53,12 +54,12 @@ type InstanceDiscovery struct { } // NewInstanceDiscovery returns a new instance discovery. -func NewInstanceDiscovery(opts *gophercloud.AuthOptions, +func NewInstanceDiscovery(provider *gophercloud.ProviderClient, opts *gophercloud.AuthOptions, interval time.Duration, port int, region string, l log.Logger) *InstanceDiscovery { if l == nil { l = log.NewNopLogger() } - return &InstanceDiscovery{authOpts: opts, + return &InstanceDiscovery{provider: provider, authOpts: opts, region: region, interval: interval, port: port, logger: l} } @@ -109,11 +110,11 @@ func (i *InstanceDiscovery) refresh() (*targetgroup.Group, error) { } }() - provider, err := openstack.AuthenticatedClient(*i.authOpts) + err = openstack.Authenticate(i.provider, *i.authOpts) if err != nil { - return nil, fmt.Errorf("could not create OpenStack session: %s", err) + return nil, fmt.Errorf("could not authenticate to OpenStack: %s", err) } - client, err := openstack.NewComputeV2(provider, gophercloud.EndpointOpts{ + client, err := openstack.NewComputeV2(i.provider, gophercloud.EndpointOpts{ Region: i.region, }) if err != nil { diff --git a/discovery/openstack/openstack.go b/discovery/openstack/openstack.go index 813330281..b248aaed8 100644 --- a/discovery/openstack/openstack.go +++ b/discovery/openstack/openstack.go @@ -17,14 +17,17 @@ import ( "context" "errors" "fmt" + "net/http" "time" "github.com/go-kit/kit/log" "github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud/openstack" + "github.com/mwitkow/go-conntrack" "github.com/prometheus/client_golang/prometheus" config_util "github.com/prometheus/common/config" "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/discovery/targetgroup" ) @@ -48,18 +51,19 @@ var ( // SDConfig is the configuration for OpenStack based service discovery. type SDConfig struct { - IdentityEndpoint string `yaml:"identity_endpoint"` - Username string `yaml:"username"` - UserID string `yaml:"userid"` - Password config_util.Secret `yaml:"password"` - ProjectName string `yaml:"project_name"` - ProjectID string `yaml:"project_id"` - DomainName string `yaml:"domain_name"` - DomainID string `yaml:"domain_id"` - Role Role `yaml:"role"` - Region string `yaml:"region"` - RefreshInterval model.Duration `yaml:"refresh_interval,omitempty"` - Port int `yaml:"port"` + IdentityEndpoint string `yaml:"identity_endpoint"` + Username string `yaml:"username"` + UserID string `yaml:"userid"` + Password config_util.Secret `yaml:"password"` + ProjectName string `yaml:"project_name"` + ProjectID string `yaml:"project_id"` + DomainName string `yaml:"domain_name"` + DomainID string `yaml:"domain_id"` + Role Role `yaml:"role"` + Region string `yaml:"region"` + RefreshInterval model.Duration `yaml:"refresh_interval,omitempty"` + Port int `yaml:"port"` + TLSConfig config_util.TLSConfig `yaml:"tls_config,omitempty"` } // OpenStackRole is role of the target in OpenStack. @@ -138,13 +142,32 @@ func NewDiscovery(conf *SDConfig, l log.Logger) (Discovery, error) { DomainID: conf.DomainID, } } + client, err := openstack.NewClient(conf.IdentityEndpoint) + if err != nil { + return nil, err + } + tls, err := config_util.NewTLSConfig(&conf.TLSConfig) + if err != nil { + return nil, err + } + client.HTTPClient = http.Client{ + Transport: &http.Transport{ + IdleConnTimeout: 5 * time.Duration(conf.RefreshInterval), + TLSClientConfig: tls, + DialContext: conntrack.NewDialContextFunc( + conntrack.DialWithTracing(), + conntrack.DialWithName("openstack_sd"), + ), + }, + Timeout: 5 * time.Duration(conf.RefreshInterval), + } switch conf.Role { case OpenStackRoleHypervisor: - hypervisor := NewHypervisorDiscovery(&opts, + hypervisor := NewHypervisorDiscovery(client, &opts, time.Duration(conf.RefreshInterval), conf.Port, conf.Region, l) return hypervisor, nil case OpenStackRoleInstance: - instance := NewInstanceDiscovery(&opts, + instance := NewInstanceDiscovery(client, &opts, time.Duration(conf.RefreshInterval), conf.Port, conf.Region, l) return instance, nil default: diff --git a/docs/configuration/configuration.md b/docs/configuration/configuration.md index ca0275d20..96e76e160 100644 --- a/docs/configuration/configuration.md +++ b/docs/configuration/configuration.md @@ -535,6 +535,10 @@ region: # The port to scrape metrics from. If using the public IP address, this must # instead be specified in the relabeling rule. [ port: | default = 80 ] + +# TLS configuration. +tls_config: + [ ] ``` ### ``