| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | package unbound |
| 4 | |
| 5 | import ( |
| 6 | "crypto/tls" |
| 7 | "errors" |
| 8 | "net" |
| 9 | |
| 10 | "github.com/netdata/netdata/go/plugins/pkg/tlscfg" |
| 11 | "github.com/netdata/netdata/go/plugins/plugin/go.d/collector/unbound/config" |
| 12 | "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/socket" |
| 13 | ) |
| 14 | |
| 15 | func (c *Collector) initConfig() (enabled bool) { |
| 16 | if c.ConfPath == "" { |
| 17 | c.Info("'conf_path' not set, skipping parameters auto detection") |
| 18 | return true |
| 19 | } |
| 20 | |
| 21 | c.Infof("reading '%s'", c.ConfPath) |
| 22 | cfg, err := config.Parse(c.ConfPath) |
| 23 | if err != nil { |
| 24 | c.Warningf("%v, skipping parameters auto detection", err) |
| 25 | return true |
| 26 | } |
| 27 | |
| 28 | if cfg.Empty() { |
| 29 | c.Debug("empty configuration") |
| 30 | return true |
| 31 | } |
| 32 | |
| 33 | if enabled, ok := cfg.ControlEnabled(); ok && !enabled { |
| 34 | c.Info("remote control is disabled in the configuration file") |
| 35 | return false |
| 36 | } |
| 37 | |
| 38 | c.applyConfig(cfg) |
| 39 | return true |
| 40 | } |
| 41 | |
| 42 | func (c *Collector) applyConfig(cfg *config.UnboundConfig) { |
| 43 | c.Infof("applying configuration: %s", cfg) |
| 44 | if cumulative, ok := cfg.Cumulative(); ok && cumulative != c.Cumulative { |
| 45 | c.Debugf("changing 'cumulative_stats': %v => %v", c.Cumulative, cumulative) |
| 46 | c.Cumulative = cumulative |
| 47 | } |
| 48 | if useCert, ok := cfg.ControlUseCert(); ok && useCert != c.UseTLS { |
| 49 | c.Debugf("changing 'use_tls': %v => %v", c.UseTLS, useCert) |
| 50 | c.UseTLS = useCert |
| 51 | } |
| 52 | if keyFile, ok := cfg.ControlKeyFile(); ok && keyFile != c.TLSKey { |
| 53 | c.Debugf("changing 'tls_key': '%s' => '%s'", c.TLSKey, keyFile) |
| 54 | c.TLSKey = keyFile |
| 55 | } |
| 56 | if certFile, ok := cfg.ControlCertFile(); ok && certFile != c.TLSCert { |
| 57 | c.Debugf("changing 'tls_cert': '%s' => '%s'", c.TLSCert, certFile) |
| 58 | c.TLSCert = certFile |
| 59 | } |
| 60 | if iface, ok := cfg.ControlInterface(); ok && adjustControlInterface(iface) != c.Address { |
| 61 | address := adjustControlInterface(iface) |
| 62 | c.Debugf("changing 'address': '%s' => '%s'", c.Address, address) |
| 63 | c.Address = address |
| 64 | } |
| 65 | if port, ok := cfg.ControlPort(); ok && !socket.IsUnixSocket(c.Address) { |
| 66 | if host, curPort, err := net.SplitHostPort(c.Address); err == nil && curPort != port { |
| 67 | address := net.JoinHostPort(host, port) |
| 68 | c.Debugf("changing 'address': '%s' => '%s'", c.Address, address) |
| 69 | c.Address = address |
| 70 | } |
| 71 | } |
| 72 | } |
| 73 | |
| 74 | func (c *Collector) initClient() (err error) { |
| 75 | var tlsCfg *tls.Config |
| 76 | useTLS := !socket.IsUnixSocket(c.Address) && c.UseTLS |
| 77 | |
| 78 | if useTLS && (c.TLSConfig.TLSCert == "" || c.TLSConfig.TLSKey == "") { |
| 79 | return errors.New("'tls_cert' or 'tls_key' is missing") |
| 80 | } |
| 81 | |
| 82 | if useTLS { |
| 83 | if tlsCfg, err = tlscfg.NewTLSConfig(c.TLSConfig); err != nil { |
| 84 | return err |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | c.client = socket.New(socket.Config{ |
| 89 | Address: c.Address, |
| 90 | Timeout: c.Timeout.Duration(), |
| 91 | TLSConf: tlsCfg, |
| 92 | }) |
| 93 | return nil |
| 94 | } |
| 95 | |
| 96 | func adjustControlInterface(value string) string { |
| 97 | if socket.IsUnixSocket(value) { |
| 98 | return value |
| 99 | } |
| 100 | if value == "0.0.0.0" { |
| 101 | value = "127.0.0.1" |
| 102 | } |
| 103 | return net.JoinHostPort(value, "8953") |
| 104 | } |