mirror of
https://github.com/prometheus/prometheus.git
synced 2025-01-12 06:17:27 -08:00
parent
1ef5ed0cf2
commit
a1574aa2b3
|
@ -108,13 +108,18 @@ func checkConfig(t cli.Term, filename string) ([]string, error) {
|
|||
return nil, fmt.Errorf("error checking bearer token file %q: %s", scfg.BearerTokenFile, err)
|
||||
}
|
||||
|
||||
if scfg.ClientCert != nil {
|
||||
if err := check(scfg.ClientCert.Cert); err != nil {
|
||||
return nil, fmt.Errorf("error checking client cert file %q: %s", scfg.ClientCert.Cert, err)
|
||||
}
|
||||
if err := check(scfg.ClientCert.Key); err != nil {
|
||||
return nil, fmt.Errorf("error checking client key file %q: %s", scfg.ClientCert.Key, err)
|
||||
}
|
||||
if err := check(scfg.TLSConfig.CertFile); err != nil {
|
||||
return nil, fmt.Errorf("error checking client cert file %q: %s", scfg.TLSConfig.CertFile, err)
|
||||
}
|
||||
if err := check(scfg.TLSConfig.KeyFile); err != nil {
|
||||
return nil, fmt.Errorf("error checking client key file %q: %s", scfg.TLSConfig.KeyFile, err)
|
||||
}
|
||||
|
||||
if len(scfg.TLSConfig.CertFile) > 0 && len(scfg.TLSConfig.KeyFile) == 0 {
|
||||
return nil, fmt.Errorf("client cert file %s specified without client key file", scfg.TLSConfig.CertFile)
|
||||
}
|
||||
if len(scfg.TLSConfig.KeyFile) > 0 && len(scfg.TLSConfig.CertFile) == 0 {
|
||||
return nil, fmt.Errorf("client key file %s specified without client cert file", scfg.TLSConfig.KeyFile)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -187,10 +187,15 @@ func resolveFilepaths(baseDir string, cfg *Config) {
|
|||
|
||||
for _, scfg := range cfg.ScrapeConfigs {
|
||||
scfg.BearerTokenFile = join(scfg.BearerTokenFile)
|
||||
scfg.TLSConfig.CAFile = join(scfg.TLSConfig.CAFile)
|
||||
scfg.TLSConfig.CertFile = join(scfg.TLSConfig.CertFile)
|
||||
scfg.TLSConfig.KeyFile = join(scfg.TLSConfig.KeyFile)
|
||||
|
||||
if scfg.ClientCert != nil {
|
||||
scfg.ClientCert.Cert = join(scfg.ClientCert.Cert)
|
||||
scfg.ClientCert.Key = join(scfg.ClientCert.Key)
|
||||
for _, kcfg := range scfg.KubernetesSDConfigs {
|
||||
kcfg.BearerTokenFile = join(kcfg.BearerTokenFile)
|
||||
kcfg.TLSConfig.CAFile = join(kcfg.TLSConfig.CAFile)
|
||||
kcfg.TLSConfig.CertFile = join(kcfg.TLSConfig.CertFile)
|
||||
kcfg.TLSConfig.KeyFile = join(kcfg.TLSConfig.KeyFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -293,6 +298,18 @@ func (c *GlobalConfig) isZero() bool {
|
|||
c.EvaluationInterval == 0
|
||||
}
|
||||
|
||||
// TLSConfig configures the options for TLS connections.
|
||||
type TLSConfig struct {
|
||||
// The CA cert to use for the targets.
|
||||
CAFile string `yaml:"ca_file,omitempty"`
|
||||
// The client cert file for the targets.
|
||||
CertFile string `yaml:"cert_file,omitempty"`
|
||||
// The client key file for the targets.
|
||||
KeyFile string `yaml:"key_file,omitempty"`
|
||||
// Disable target certificate validation.
|
||||
InsecureSkipVerify bool `yaml:"insecure_skip_verify"`
|
||||
}
|
||||
|
||||
// ScrapeConfig configures a scraping unit for Prometheus.
|
||||
type ScrapeConfig struct {
|
||||
// The job name to which the job label is set by default.
|
||||
|
@ -315,12 +332,10 @@ type ScrapeConfig struct {
|
|||
BearerToken string `yaml:"bearer_token,omitempty"`
|
||||
// The bearer token file for the targets.
|
||||
BearerTokenFile string `yaml:"bearer_token_file,omitempty"`
|
||||
// The ca cert to use for the targets.
|
||||
CACert string `yaml:"ca_cert,omitempty"`
|
||||
// The client cert authentication credentials for the targets.
|
||||
ClientCert *ClientCert `yaml:"client_cert,omitempty"`
|
||||
// HTTP proxy server to use to connect to the targets.
|
||||
ProxyURL URL `yaml:"proxy_url,omitempty"`
|
||||
// Inlined TLSConfig.
|
||||
TLSConfig TLSConfig `yaml:"tls_config,omitempty"`
|
||||
|
||||
// List of labeled target groups for this job.
|
||||
TargetGroups []*TargetGroup `yaml:"target_groups,omitempty"`
|
||||
|
@ -605,18 +620,15 @@ type MarathonSDConfig struct {
|
|||
|
||||
// KubernetesSDConfig is the configuration for Kubernetes service discovery.
|
||||
type KubernetesSDConfig struct {
|
||||
Masters []URL `yaml:"masters"`
|
||||
KubeletPort int `yaml:"kubelet_port,omitempty"`
|
||||
InCluster bool `yaml:"in_cluster,omitempty"`
|
||||
BearerTokenFile string `yaml:"bearer_token_file,omitempty"`
|
||||
Username string `yaml:"username,omitempty"`
|
||||
Password string `yaml:"password,omitempty"`
|
||||
Insecure bool `yaml:"insecure,omitempty"`
|
||||
CertFile string `yaml:"cert_file,omitempty"`
|
||||
KeyFile string `yaml:"key_file,omitempty"`
|
||||
CAFile string `yaml:"ca_file,omitempty"`
|
||||
RetryInterval Duration `yaml:"retry_interval,omitempty"`
|
||||
RequestTimeout Duration `yaml:"request_timeout,omitempty"`
|
||||
Masters []URL `yaml:"masters"`
|
||||
KubeletPort int `yaml:"kubelet_port,omitempty"`
|
||||
InCluster bool `yaml:"in_cluster,omitempty"`
|
||||
BearerTokenFile string `yaml:"bearer_token_file,omitempty"`
|
||||
Username string `yaml:"username,omitempty"`
|
||||
Password string `yaml:"password,omitempty"`
|
||||
RetryInterval Duration `yaml:"retry_interval,omitempty"`
|
||||
RequestTimeout Duration `yaml:"request_timeout,omitempty"`
|
||||
TLSConfig TLSConfig `yaml:"tls_config,omitempty"`
|
||||
|
||||
// Catches all undefined fields and must be empty after parsing.
|
||||
XXX map[string]interface{} `yaml:",inline"`
|
||||
|
|
|
@ -180,10 +180,11 @@ var expectedConf = &Config{
|
|||
MetricsPath: "/metrics",
|
||||
Scheme: "http",
|
||||
|
||||
ClientCert: &ClientCert{
|
||||
Cert: "testdata/valid_cert_file",
|
||||
Key: "testdata/valid_key_file",
|
||||
TLSConfig: TLSConfig{
|
||||
CertFile: "testdata/valid_cert_file",
|
||||
KeyFile: "testdata/valid_key_file",
|
||||
},
|
||||
|
||||
BearerToken: "avalidtoken",
|
||||
},
|
||||
{
|
||||
|
|
6
config/testdata/conf.good.yml
vendored
6
config/testdata/conf.good.yml
vendored
|
@ -94,9 +94,9 @@ scrape_configs:
|
|||
|
||||
- job_name: service-z
|
||||
|
||||
client_cert:
|
||||
cert: valid_cert_file
|
||||
key: valid_key_file
|
||||
tls_config:
|
||||
cert_file: valid_cert_file
|
||||
key_file: valid_key_file
|
||||
|
||||
bearer_token: avalidtoken
|
||||
|
||||
|
|
|
@ -8,7 +8,9 @@ global:
|
|||
scrape_configs:
|
||||
- job_name: 'kubernetes'
|
||||
|
||||
ca_cert: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
||||
tls_config:
|
||||
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
||||
|
||||
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
|
||||
|
||||
kubernetes_sd_configs:
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
package kubernetes
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
@ -574,7 +572,7 @@ func (kd *Discovery) updateServiceEndpoints(endpoints *Endpoints, eventType Even
|
|||
|
||||
func newKubernetesHTTPClient(conf *config.KubernetesSDConfig) (*http.Client, error) {
|
||||
bearerTokenFile := conf.BearerTokenFile
|
||||
caFile := conf.CAFile
|
||||
caFile := conf.TLSConfig.CAFile
|
||||
if conf.InCluster {
|
||||
if len(bearerTokenFile) == 0 {
|
||||
bearerTokenFile = serviceAccountToken
|
||||
|
@ -582,46 +580,31 @@ func newKubernetesHTTPClient(conf *config.KubernetesSDConfig) (*http.Client, err
|
|||
if len(caFile) == 0 {
|
||||
// With recent versions, the CA certificate is provided as a token
|
||||
// but we need to handle older versions too. In this case, don't
|
||||
// set the CAFile & the configuration will have to use Insecure.
|
||||
// set the CAFile & the configuration will have to use InsecureSkipVerify.
|
||||
if _, err := os.Stat(serviceAccountCACert); err == nil {
|
||||
caFile = serviceAccountCACert
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tlsConfig := &tls.Config{InsecureSkipVerify: conf.Insecure}
|
||||
|
||||
// Load client cert if specified.
|
||||
if len(conf.CertFile) > 0 && len(conf.KeyFile) > 0 {
|
||||
cert, err := tls.LoadX509KeyPair(conf.CertFile, conf.KeyFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tlsConfig.Certificates = []tls.Certificate{cert}
|
||||
tlsOpts := httputil.TLSOptions{
|
||||
InsecureSkipVerify: conf.TLSConfig.InsecureSkipVerify,
|
||||
CAFile: caFile,
|
||||
CertFile: conf.TLSConfig.CertFile,
|
||||
KeyFile: conf.TLSConfig.KeyFile,
|
||||
}
|
||||
tlsConfig, err := httputil.NewTLSConfig(tlsOpts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
caCertPool := x509.NewCertPool()
|
||||
if len(caFile) > 0 {
|
||||
// Load CA cert.
|
||||
caCert, err := ioutil.ReadFile(caFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
caCertPool.AppendCertsFromPEM(caCert)
|
||||
}
|
||||
tlsConfig.RootCAs = caCertPool
|
||||
|
||||
tlsConfig.BuildNameToCertificate()
|
||||
|
||||
tr := &http.Transport{
|
||||
var rt http.RoundTripper = &http.Transport{
|
||||
Dial: func(netw, addr string) (c net.Conn, err error) {
|
||||
c, err = net.DialTimeout(netw, addr, time.Duration(conf.RequestTimeout))
|
||||
return
|
||||
},
|
||||
TLSClientConfig: tlsConfig,
|
||||
}
|
||||
tr.TLSClientConfig = tlsConfig
|
||||
var rt http.RoundTripper
|
||||
rt = tr
|
||||
|
||||
bearerToken, err := ioutil.ReadFile(bearerTokenFile)
|
||||
if err != nil {
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
package retrieval
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -249,33 +247,21 @@ func (t *Target) Update(cfg *config.ScrapeConfig, baseLabels, metaLabels model.L
|
|||
}
|
||||
|
||||
func newHTTPClient(cfg *config.ScrapeConfig) (*http.Client, error) {
|
||||
tlsConfig := &tls.Config{}
|
||||
|
||||
// If a CA cert is provided then let's read it in so we can validate the
|
||||
// scrape target's certificate properly.
|
||||
if len(cfg.CACert) > 0 {
|
||||
caCertPool := x509.NewCertPool()
|
||||
// Load CA cert.
|
||||
caCert, err := ioutil.ReadFile(cfg.CACert)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to use specified CA cert %s: %s", cfg.CACert, err)
|
||||
}
|
||||
caCertPool.AppendCertsFromPEM(caCert)
|
||||
tlsConfig.RootCAs = caCertPool
|
||||
}
|
||||
|
||||
// If a client cert & key is provided then configure TLS config accordingly.
|
||||
if cfg.ClientCert != nil && len(cfg.ClientCert.Cert) > 0 && len(cfg.ClientCert.Key) > 0 {
|
||||
cert, err := tls.LoadX509KeyPair(cfg.ClientCert.Cert, cfg.ClientCert.Key)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to use specified client cert (%s) & key (%s): %s", cfg.ClientCert.Cert, cfg.ClientCert.Key, err)
|
||||
}
|
||||
tlsConfig.Certificates = []tls.Certificate{cert}
|
||||
}
|
||||
tlsConfig.BuildNameToCertificate()
|
||||
|
||||
// Get a default roundtripper with the scrape timeout.
|
||||
rt := httputil.NewDeadlineRoundTripper(time.Duration(cfg.ScrapeTimeout), cfg.ProxyURL.URL)
|
||||
|
||||
tlsOpts := httputil.TLSOptions{
|
||||
InsecureSkipVerify: cfg.TLSConfig.InsecureSkipVerify,
|
||||
CAFile: cfg.TLSConfig.CAFile,
|
||||
}
|
||||
if len(cfg.TLSConfig.CertFile) > 0 && len(cfg.TLSConfig.KeyFile) > 0 {
|
||||
tlsOpts.CertFile = cfg.TLSConfig.CertFile
|
||||
tlsOpts.KeyFile = cfg.TLSConfig.KeyFile
|
||||
}
|
||||
tlsConfig, err := httputil.NewTLSConfig(tlsOpts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Get a default roundtripper with the scrape timeout.
|
||||
tr := rt.(*http.Transport)
|
||||
// Set the TLS config from above
|
||||
tr.TLSClientConfig = tlsConfig
|
||||
|
|
|
@ -563,7 +563,9 @@ func TestNewHTTPCACert(t *testing.T) {
|
|||
|
||||
cfg := &config.ScrapeConfig{
|
||||
ScrapeTimeout: config.Duration(1 * time.Second),
|
||||
CACert: "testdata/ca.cer",
|
||||
TLSConfig: config.TLSConfig{
|
||||
CAFile: "testdata/ca.cer",
|
||||
},
|
||||
}
|
||||
c, err := newHTTPClient(cfg)
|
||||
if err != nil {
|
||||
|
@ -594,10 +596,10 @@ func TestNewHTTPClientCert(t *testing.T) {
|
|||
|
||||
cfg := &config.ScrapeConfig{
|
||||
ScrapeTimeout: config.Duration(1 * time.Second),
|
||||
CACert: "testdata/ca.cer",
|
||||
ClientCert: &config.ClientCert{
|
||||
Cert: "testdata/client.cer",
|
||||
Key: "testdata/client.key",
|
||||
TLSConfig: config.TLSConfig{
|
||||
CAFile: "testdata/ca.cer",
|
||||
CertFile: "testdata/client.cer",
|
||||
KeyFile: "testdata/client.key",
|
||||
},
|
||||
}
|
||||
c, err := newHTTPClient(cfg)
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
package httputil
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
@ -108,3 +112,39 @@ func cloneRequest(r *http.Request) *http.Request {
|
|||
}
|
||||
return r2
|
||||
}
|
||||
|
||||
type TLSOptions struct {
|
||||
InsecureSkipVerify bool
|
||||
CAFile string
|
||||
CertFile string
|
||||
KeyFile string
|
||||
}
|
||||
|
||||
func NewTLSConfig(opts TLSOptions) (*tls.Config, error) {
|
||||
tlsConfig := &tls.Config{InsecureSkipVerify: opts.InsecureSkipVerify}
|
||||
|
||||
// If a CA cert is provided then let's read it in so we can validate the
|
||||
// scrape target's certificate properly.
|
||||
if len(opts.CAFile) > 0 {
|
||||
caCertPool := x509.NewCertPool()
|
||||
// Load CA cert.
|
||||
caCert, err := ioutil.ReadFile(opts.CAFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to use specified CA cert %s: %s", opts.CAFile, err)
|
||||
}
|
||||
caCertPool.AppendCertsFromPEM(caCert)
|
||||
tlsConfig.RootCAs = caCertPool
|
||||
}
|
||||
|
||||
// If a client cert & key is provided then configure TLS config accordingly.
|
||||
if len(opts.CertFile) > 0 && len(opts.KeyFile) > 0 {
|
||||
cert, err := tls.LoadX509KeyPair(opts.CertFile, opts.KeyFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to use specified client cert (%s) & key (%s): %s", opts.CertFile, opts.KeyFile, err)
|
||||
}
|
||||
tlsConfig.Certificates = []tls.Certificate{cert}
|
||||
}
|
||||
tlsConfig.BuildNameToCertificate()
|
||||
|
||||
return tlsConfig, nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue