diff --git a/internal/exporter/exporter.go b/internal/exporter/exporter.go index 2b371ca..7241dee 100644 --- a/internal/exporter/exporter.go +++ b/internal/exporter/exporter.go @@ -25,7 +25,7 @@ var ( ) // NewPuppetDBExporter returns a new exporter of PuppetDB metrics. -func NewPuppetDBExporter(url, certPath, caPath, keyPath string, sslSkipVerify bool, categories map[string]struct{}) (e *Exporter, err error) { +func NewPuppetDBExporter(url, certPath, caPath, keyPath string, sslSkipVerify bool, authType, authUser, authPass string, categories map[string]struct{}) (e *Exporter, err error) { e = &Exporter{ namespace: "puppetdb", } @@ -36,6 +36,9 @@ func NewPuppetDBExporter(url, certPath, caPath, keyPath string, sslSkipVerify bo CACertPath: caPath, KeyPath: keyPath, SSLVerify: sslSkipVerify, + AuthType: authType, + AuthUser: authUser, + AuthPass: authPass, } e.client, err = puppetdb.NewClient(opts) diff --git a/internal/puppetdb/puppetdb.go b/internal/puppetdb/puppetdb.go index 35e99ca..0674d2d 100644 --- a/internal/puppetdb/puppetdb.go +++ b/internal/puppetdb/puppetdb.go @@ -26,6 +26,9 @@ type Options struct { CACertPath string KeyPath string SSLVerify bool + AuthType string + AuthUser string + AuthPass string } // Node is a structure returned by a PuppetDB @@ -61,28 +64,35 @@ func NewClient(options *Options) (p *PuppetDB, err error) { } if puppetdbURL.Scheme == "https" { - // Load client cert - cert, err := tls.LoadX509KeyPair(options.CertPath, options.KeyPath) - if err != nil { - err = fmt.Errorf("failed to load keypair: %s", err) - return nil, err + // Setup HTTPS client + tlsConfig := &tls.Config{ + InsecureSkipVerify: !options.SSLVerify, } - // Load CA cert - caCert, err := ioutil.ReadFile(options.CACertPath) - if err != nil { - err = fmt.Errorf("failed to load ca certificate: %s", err) - return nil, err + if options.AuthType == "x509" { + // Load client cert + cert, err := tls.LoadX509KeyPair(options.CertPath, options.KeyPath) + if err != nil { + err = fmt.Errorf("failed to load keypair: %s", err) + return nil, err + } + + tlsConfig.Certificates = []tls.Certificate{cert} } - caCertPool := x509.NewCertPool() - caCertPool.AppendCertsFromPEM(caCert) - // Setup HTTPS client - tlsConfig := &tls.Config{ - Certificates: []tls.Certificate{cert}, - RootCAs: caCertPool, - InsecureSkipVerify: !options.SSLVerify, + if options.CACertPath != "" { + // Load CA cert + caCert, err := ioutil.ReadFile(options.CACertPath) + if err != nil { + err = fmt.Errorf("failed to load ca certificate: %s", err) + return nil, err + } + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + + tlsConfig.RootCAs = caCertPool } + tlsConfig.BuildNameToCertificate() transport = &http.Transport{TLSClientConfig: tlsConfig} } else { @@ -133,6 +143,10 @@ func (p *PuppetDB) get(endpoint string, query string, object interface{}) (err e log.Debugln("req:", req) + if p.options.AuthType == "basic" { + req.SetBasicAuth(p.options.AuthUser, p.options.AuthPass) + } + resp, err := p.client.Do(req) if err != nil { err = fmt.Errorf("failed to call API: %s", err) diff --git a/main.go b/main.go index 8d04edb..4739764 100644 --- a/main.go +++ b/main.go @@ -29,6 +29,9 @@ type Config struct { Verbose bool `long:"verbose" description:"Enable debug mode" env:"PUPPETDB_VERBOSE"` UnreportedNode string `long:"unreported-node" description:"Tag nodes as unreported if the latest report is older than the defined duration." env:"PUPPETDB_UNREPORTED_NODE" default:"2h"` Categories string `long:"categories" description:"Report metrics categories to scrape." env:"REPORT_METRICS_CATEGORIES" default:"resources,time,changes,events"` + BasicAuth bool `long:"basic-auth" description:"Enable http basic auth" env:"PUPPETDB_BASIC_AUTH"` + AuthUser string `long:"user" description:"Http basic auth user" env:"PUPPETDB_USER"` + AuthPass string `long:"pass" description:"Http basic auth password" env:"PUPPETDB_PASS"` } var ( @@ -76,7 +79,11 @@ func main() { for _, category := range cats { categories[category] = struct{}{} } - exp, err := exporter.NewPuppetDBExporter(c.PuppetDBUrl, c.CertFile, c.CACertFile, c.KeyFile, c.SSLSkipVerify, categories) + authType := "x509" + if c.BasicAuth { + authType = "basic" + } + exp, err := exporter.NewPuppetDBExporter(c.PuppetDBUrl, c.CertFile, c.CACertFile, c.KeyFile, c.SSLSkipVerify, authType, c.AuthUser, c.AuthPass, categories) if err != nil { log.Fatalf("failed to initialize exporter: %s", err) }