summaryrefslogtreecommitdiffstats
path: root/src/go/collectors/go.d.plugin/modules/unbound/config
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/go/collectors/go.d.plugin/modules/unbound/config/config.go78
-rw-r--r--src/go/collectors/go.d.plugin/modules/unbound/config/config_test.go172
-rw-r--r--src/go/collectors/go.d.plugin/modules/unbound/config/parse.go165
-rw-r--r--src/go/collectors/go.d.plugin/modules/unbound/config/parse_test.go93
-rw-r--r--src/go/collectors/go.d.plugin/modules/unbound/config/testdata/infinite_rec.conf85
-rw-r--r--src/go/collectors/go.d.plugin/modules/unbound/config/testdata/non_existent_glob_include.conf85
-rw-r--r--src/go/collectors/go.d.plugin/modules/unbound/config/testdata/non_existent_include.conf85
-rw-r--r--src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_glob.conf82
-rw-r--r--src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_glob2.conf80
-rw-r--r--src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_glob3.conf81
-rw-r--r--src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include.conf82
-rw-r--r--src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include2.conf81
-rw-r--r--src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include3.conf81
-rw-r--r--src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include_toplevel.conf82
-rw-r--r--src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include_toplevel2.conf81
-rw-r--r--src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include_toplevel3.conf81
-rw-r--r--src/go/collectors/go.d.plugin/modules/unbound/config_schema.json113
17 files changed, 1607 insertions, 0 deletions
diff --git a/src/go/collectors/go.d.plugin/modules/unbound/config/config.go b/src/go/collectors/go.d.plugin/modules/unbound/config/config.go
new file mode 100644
index 000000000..69dc5c219
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/unbound/config/config.go
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package config
+
+import (
+ "fmt"
+ "strings"
+)
+
+// UnboundConfig represents Unbound configuration file.
+type UnboundConfig struct {
+ cumulative string // statistics-cumulative
+ enable string // control-enable
+ iface string // control-interface
+ port string // control-port
+ useCert string // control-use-cert
+ keyFile string // control-key-file
+ certFile string // control-cert-file
+}
+
+func (c UnboundConfig) String() string {
+ format := strings.Join([]string{
+ "[",
+ `"statistics-cumulative": '%s', `,
+ `"control-enable": '%s', `,
+ `"control-interface": '%s', `,
+ `"control-port": '%s', `,
+ `"control-user-cert": '%s', `,
+ `"control-key-file": '%s', `,
+ `"control-cert-file": '%s'`,
+ "]",
+ }, "")
+ return fmt.Sprintf(format, c.cumulative, c.enable, c.iface, c.port, c.useCert, c.keyFile, c.certFile)
+}
+
+func (c UnboundConfig) Empty() bool { return c == UnboundConfig{} }
+func (c UnboundConfig) Cumulative() (bool, bool) { return c.cumulative == "yes", c.cumulative != "" }
+func (c UnboundConfig) ControlEnabled() (bool, bool) { return c.enable == "yes", c.enable != "" }
+func (c UnboundConfig) ControlInterface() (string, bool) { return c.iface, c.iface != "" }
+func (c UnboundConfig) ControlPort() (string, bool) { return c.port, c.port != "" }
+func (c UnboundConfig) ControlUseCert() (bool, bool) { return c.useCert == "yes", c.useCert != "" }
+func (c UnboundConfig) ControlKeyFile() (string, bool) { return c.keyFile, c.keyFile != "" }
+func (c UnboundConfig) ControlCertFile() (string, bool) { return c.certFile, c.certFile != "" }
+
+func fromOptions(options []option) *UnboundConfig {
+ cfg := &UnboundConfig{}
+ for _, opt := range options {
+ switch opt.name {
+ default:
+ case optInterface:
+ applyControlInterface(cfg, opt.value)
+ case optCumulative:
+ cfg.cumulative = opt.value
+ case optEnable:
+ cfg.enable = opt.value
+ case optPort:
+ cfg.port = opt.value
+ case optUseCert:
+ cfg.useCert = opt.value
+ case optKeyFile:
+ cfg.keyFile = opt.value
+ case optCertFile:
+ cfg.certFile = opt.value
+ }
+ }
+ return cfg
+}
+
+// Unbound doesn't allow to query stats from unix socket when control-interface is enabled on ip interface.
+func applyControlInterface(cfg *UnboundConfig, value string) {
+ if cfg.iface == "" || !isUnixSocket(value) || isUnixSocket(cfg.iface) {
+ cfg.iface = value
+ }
+}
+
+func isUnixSocket(address string) bool {
+ return strings.HasPrefix(address, "/")
+}
diff --git a/src/go/collectors/go.d.plugin/modules/unbound/config/config_test.go b/src/go/collectors/go.d.plugin/modules/unbound/config/config_test.go
new file mode 100644
index 000000000..0375c1368
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/unbound/config/config_test.go
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package config
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestUnboundConfig_Empty(t *testing.T) {
+ assert.True(t, UnboundConfig{}.Empty())
+ assert.False(t, UnboundConfig{enable: "yes"}.Empty())
+}
+
+func TestUnboundConfig_Cumulative(t *testing.T) {
+ tests := []struct {
+ input string
+ wantValue bool
+ wantOK bool
+ }{
+ {input: "yes", wantValue: true, wantOK: true},
+ {input: "no", wantValue: false, wantOK: true},
+ {input: "", wantValue: false, wantOK: false},
+ {input: "some value", wantValue: false, wantOK: true},
+ }
+
+ for _, test := range tests {
+ t.Run(test.input, func(t *testing.T) {
+ cfg := UnboundConfig{cumulative: test.input}
+
+ v, ok := cfg.Cumulative()
+ assert.Equal(t, test.wantValue, v)
+ assert.Equal(t, test.wantOK, ok)
+ })
+ }
+}
+
+func TestUnboundConfig_ControlEnabled(t *testing.T) {
+ tests := []struct {
+ input string
+ wantValue bool
+ wantOK bool
+ }{
+ {input: "yes", wantValue: true, wantOK: true},
+ {input: "no", wantValue: false, wantOK: true},
+ {input: "", wantValue: false, wantOK: false},
+ {input: "some value", wantValue: false, wantOK: true},
+ }
+
+ for _, test := range tests {
+ t.Run(test.input, func(t *testing.T) {
+ cfg := UnboundConfig{enable: test.input}
+
+ v, ok := cfg.ControlEnabled()
+ assert.Equal(t, test.wantValue, v)
+ assert.Equal(t, test.wantOK, ok)
+ })
+ }
+}
+
+func TestUnboundConfig_ControlInterface(t *testing.T) {
+ tests := []struct {
+ input string
+ wantValue string
+ wantOK bool
+ }{
+ {input: "127.0.0.1", wantValue: "127.0.0.1", wantOK: true},
+ {input: "/var/run/unbound.sock", wantValue: "/var/run/unbound.sock", wantOK: true},
+ {input: "", wantValue: "", wantOK: false},
+ {input: "some value", wantValue: "some value", wantOK: true},
+ }
+
+ for _, test := range tests {
+ t.Run(test.input, func(t *testing.T) {
+ cfg := UnboundConfig{iface: test.input}
+
+ v, ok := cfg.ControlInterface()
+ assert.Equal(t, test.wantValue, v)
+ assert.Equal(t, test.wantOK, ok)
+ })
+ }
+}
+
+func TestUnboundConfig_ControlPort(t *testing.T) {
+ tests := []struct {
+ input string
+ wantValue string
+ wantOK bool
+ }{
+ {input: "8953", wantValue: "8953", wantOK: true},
+ {input: "", wantValue: "", wantOK: false},
+ {input: "some value", wantValue: "some value", wantOK: true},
+ }
+
+ for _, test := range tests {
+ t.Run(test.input, func(t *testing.T) {
+ cfg := UnboundConfig{port: test.input}
+
+ v, ok := cfg.ControlPort()
+ assert.Equal(t, test.wantValue, v)
+ assert.Equal(t, test.wantOK, ok)
+ })
+ }
+}
+
+func TestUnboundConfig_ControlUseCert(t *testing.T) {
+ tests := []struct {
+ input string
+ wantValue bool
+ wantOK bool
+ }{
+ {input: "yes", wantValue: true, wantOK: true},
+ {input: "no", wantValue: false, wantOK: true},
+ {input: "", wantValue: false, wantOK: false},
+ {input: "some value", wantValue: false, wantOK: true},
+ }
+
+ for _, test := range tests {
+ t.Run(test.input, func(t *testing.T) {
+ cfg := UnboundConfig{useCert: test.input}
+
+ v, ok := cfg.ControlUseCert()
+ assert.Equal(t, test.wantValue, v)
+ assert.Equal(t, test.wantOK, ok)
+ })
+ }
+}
+
+func TestUnboundConfig_ControlKeyFile(t *testing.T) {
+ tests := []struct {
+ input string
+ wantValue string
+ wantOK bool
+ }{
+ {input: "/etc/unbound/unbound_control.key", wantValue: "/etc/unbound/unbound_control.key", wantOK: true},
+ {input: "", wantValue: "", wantOK: false},
+ {input: "some value", wantValue: "some value", wantOK: true},
+ }
+
+ for _, test := range tests {
+ t.Run(test.input, func(t *testing.T) {
+ cfg := UnboundConfig{keyFile: test.input}
+
+ v, ok := cfg.ControlKeyFile()
+ assert.Equal(t, test.wantValue, v)
+ assert.Equal(t, test.wantOK, ok)
+ })
+ }
+}
+
+func TestUnboundConfig_ControlCertFile(t *testing.T) {
+ tests := []struct {
+ input string
+ wantValue string
+ wantOK bool
+ }{
+ {input: "/etc/unbound/unbound_control.pem", wantValue: "/etc/unbound/unbound_control.pem", wantOK: true},
+ {input: "", wantValue: "", wantOK: false},
+ {input: "some value", wantValue: "some value", wantOK: true},
+ }
+
+ for _, test := range tests {
+ t.Run(test.input, func(t *testing.T) {
+ cfg := UnboundConfig{certFile: test.input}
+
+ v, ok := cfg.ControlCertFile()
+ assert.Equal(t, test.wantValue, v)
+ assert.Equal(t, test.wantOK, ok)
+ })
+ }
+}
diff --git a/src/go/collectors/go.d.plugin/modules/unbound/config/parse.go b/src/go/collectors/go.d.plugin/modules/unbound/config/parse.go
new file mode 100644
index 000000000..99a632d50
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/unbound/config/parse.go
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package config
+
+import (
+ "bufio"
+ "errors"
+ "fmt"
+ "os"
+ "path/filepath"
+ "runtime"
+ "strings"
+)
+
+type option struct{ name, value string }
+
+const (
+ optInclude = "include"
+ optIncludeToplevel = "include-toplevel"
+ optCumulative = "statistics-cumulative"
+ optEnable = "control-enable"
+ optInterface = "control-interface"
+ optPort = "control-port"
+ optUseCert = "control-use-cert"
+ optKeyFile = "control-key-file"
+ optCertFile = "control-cert-file"
+)
+
+func isOptionUsed(opt option) bool {
+ switch opt.name {
+ case optInclude,
+ optIncludeToplevel,
+ optCumulative,
+ optEnable,
+ optInterface,
+ optPort,
+ optUseCert,
+ optKeyFile,
+ optCertFile:
+ return true
+ }
+ return false
+}
+
+// TODO:
+// If also using chroot, using full path names for the included files works, relative pathnames for the included names
+// work if the directory where the daemon is started equals its chroot/working directory or is specified before
+// the include statement with directory: dir.
+
+// Parse parses Unbound configuration files into UnboundConfig.
+// It follows logic described in the 'man unbound.conf':
+// - Files can be included using the 'include:' directive. It can appear anywhere, it accepts a single file name as argument.
+// - Processing continues as if the text from the included file was copied into the config file at that point.
+// - Wildcards can be used to include multiple files.
+//
+// It stops processing on any error: syntax error, recursive include, glob matches directory etc.
+func Parse(entryPath string) (*UnboundConfig, error) {
+ options, err := parse(entryPath, nil)
+ if err != nil {
+ return nil, err
+ }
+ return fromOptions(options), nil
+}
+
+func parse(filename string, visited map[string]bool) ([]option, error) {
+ if visited == nil {
+ visited = make(map[string]bool)
+ }
+ if visited[filename] {
+ return nil, fmt.Errorf("'%s' already visited", filename)
+ }
+ visited[filename] = true
+
+ f, err := open(filename)
+ if err != nil {
+ return nil, err
+ }
+ defer func() { _ = f.Close() }()
+
+ var options []option
+ sc := bufio.NewScanner(f)
+
+ for sc.Scan() {
+ line := strings.TrimSpace(sc.Text())
+ if line == "" || strings.HasPrefix(line, "#") {
+ continue
+ }
+
+ opt, err := parseLine(line)
+ if err != nil {
+ return nil, fmt.Errorf("file '%s', error on parsing line '%s': %v", filename, line, err)
+ }
+
+ if !isOptionUsed(opt) {
+ continue
+ }
+
+ if opt.name != optInclude && opt.name != optIncludeToplevel {
+ options = append(options, opt)
+ continue
+ }
+
+ filenames, err := globInclude(opt.value)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, name := range filenames {
+ opts, err := parse(name, visited)
+ if err != nil {
+ return nil, err
+ }
+ options = append(options, opts...)
+ }
+ }
+ return options, nil
+}
+
+func globInclude(include string) ([]string, error) {
+ if isGlobPattern(include) {
+ return filepath.Glob(include)
+ }
+ return []string{include}, nil
+}
+
+func parseLine(line string) (option, error) {
+ parts := strings.Split(line, ":")
+ if len(parts) < 2 {
+ return option{}, errors.New("bad syntax")
+ }
+ key, value := cleanKeyValue(parts[0], parts[1])
+ return option{name: key, value: value}, nil
+}
+
+func cleanKeyValue(key, value string) (string, string) {
+ if i := strings.IndexByte(value, '#'); i > 0 {
+ value = value[:i-1]
+ }
+ key = strings.TrimSpace(key)
+ value = strings.Trim(strings.TrimSpace(value), "\"'")
+ return key, value
+}
+
+func isGlobPattern(value string) bool {
+ magicChars := `*?[`
+ if runtime.GOOS != "windows" {
+ magicChars = `*?[\`
+ }
+ return strings.ContainsAny(value, magicChars)
+}
+
+func open(filename string) (*os.File, error) {
+ f, err := os.Open(filename)
+ if err != nil {
+ return nil, err
+ }
+ fi, err := f.Stat()
+ if err != nil {
+ return nil, err
+ }
+ if !fi.Mode().IsRegular() {
+ return nil, fmt.Errorf("'%s' is not a regular file", filename)
+ }
+ return f, nil
+}
diff --git a/src/go/collectors/go.d.plugin/modules/unbound/config/parse_test.go b/src/go/collectors/go.d.plugin/modules/unbound/config/parse_test.go
new file mode 100644
index 000000000..72542a861
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/unbound/config/parse_test.go
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package config
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestParse(t *testing.T) {
+ tests := map[string]struct {
+ path string
+ wantCfg UnboundConfig
+ wantErr bool
+ }{
+ "valid include": {
+ path: "testdata/valid_include.conf",
+ wantCfg: UnboundConfig{
+ cumulative: "yes",
+ enable: "yes",
+ iface: "10.0.0.1",
+ port: "8955",
+ useCert: "yes",
+ keyFile: "/etc/unbound/unbound_control_2.key",
+ certFile: "/etc/unbound/unbound_control_2.pem",
+ },
+ },
+ "valid include-toplevel": {
+ path: "testdata/valid_include_toplevel.conf",
+ wantCfg: UnboundConfig{
+ cumulative: "yes",
+ enable: "yes",
+ iface: "10.0.0.1",
+ port: "8955",
+ useCert: "yes",
+ keyFile: "/etc/unbound/unbound_control_2.key",
+ certFile: "/etc/unbound/unbound_control_2.pem",
+ },
+ },
+ "valid glob include": {
+ path: "testdata/valid_glob.conf",
+ wantCfg: UnboundConfig{
+ cumulative: "yes",
+ enable: "yes",
+ iface: "10.0.0.1",
+ port: "8955",
+ useCert: "yes",
+ keyFile: "/etc/unbound/unbound_control_2.key",
+ certFile: "/etc/unbound/unbound_control_2.pem",
+ },
+ },
+ "non existent glob include": {
+ path: "testdata/non_existent_glob_include.conf",
+ wantCfg: UnboundConfig{
+ cumulative: "yes",
+ enable: "yes",
+ iface: "10.0.0.1",
+ port: "8953",
+ useCert: "yes",
+ keyFile: "/etc/unbound/unbound_control.key",
+ certFile: "/etc/unbound/unbound_control.pem",
+ },
+ },
+ "infinite recursion include": {
+ path: "testdata/infinite_rec.conf",
+ wantErr: true,
+ },
+ "non existent include": {
+ path: "testdata/non_existent_include.conf",
+ wantErr: true,
+ },
+ "non existent path": {
+ path: "testdata/non_existent_path.conf",
+ wantErr: true,
+ },
+ }
+
+ for name, test := range tests {
+ name = fmt.Sprintf("%s (%s)", name, test.path)
+ t.Run(name, func(t *testing.T) {
+ cfg, err := Parse(test.path)
+
+ if test.wantErr {
+ assert.Error(t, err)
+ } else {
+ assert.NoError(t, err)
+ assert.Equal(t, test.wantCfg, *cfg)
+ }
+ })
+ }
+}
diff --git a/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/infinite_rec.conf b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/infinite_rec.conf
new file mode 100644
index 000000000..904f75b30
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/infinite_rec.conf
@@ -0,0 +1,85 @@
+#
+# Example configuration file.
+#
+# See unbound.conf(5) man page, version 1.9.4.
+#
+# this is a comment.
+
+#Use this to include other text into the file.
+include: "testdata/infinite_rec.conf"
+
+# The server clause sets the main parameters.
+server:
+ # whitespace is not necessary, but looks cleaner.
+
+ # verbosity number, 0 is least verbose. 1 is default.
+ # verbosity: 1
+
+ # print statistics to the log (for every thread) every N seconds.
+ # Set to "" or 0 to disable. Default is disabled.
+ # statistics-interval: 0
+
+ # enable shm for stats, default no. if you enable also enable
+ # statistics-interval, every time it also writes stats to the
+ # shared memory segment keyed with shm-key.
+ # shm-enable: no
+
+ # shm for stats uses this key, and key+1 for the shared mem segment.
+ # shm-key: 11777
+
+ # enable cumulative statistics, without clearing them after printing.
+ # statistics-cumulative: no
+ statistics-cumulative: yes
+
+ # enable extended statistics (query types, answer codes, status)
+ # printed from unbound-control. default off, because of speed.
+ # extended-statistics: no
+ # extended-statistics: yes
+
+ # number of threads to create. 1 disables threading.
+ # num-threads: 2
+
+# Python config section. To enable:
+# o use --with-pythonmodule to configure before compiling.
+# o list python in the module-config string (above) to enable.
+# It can be at the start, it gets validated results, or just before
+# the iterator and process before DNSSEC validation.
+# o and give a python-script to run.
+python:
+ # Script file to load
+ # python-script: "/etc/unbound/ubmodule-tst.py"
+
+# Remote control config section.
+remote-control:
+ # Enable remote control with unbound-control(8) here.
+ # set up the keys and certificates with unbound-control-setup.
+ control-enable: yes
+
+ # what interfaces are listened to for remote control.
+ # give 0.0.0.0 and ::0 to listen to all interfaces.
+ # set to an absolute path to use a unix local name pipe, certificates
+ # are not used for that, so key and cert files need not be present.
+ # control-interface: 127.0.0.1
+ control-interface: 10.0.0.1
+ # control-interface: ::1
+ # control-interface: /var/run/test.sock
+
+ # port number for remote control operations.
+ control-port: 8953
+
+ # for localhost, you can disable use of TLS by setting this to "no"
+ # For local sockets this option is ignored, and TLS is not used.
+ # control-use-cert: "yes"
+ control-use-cert: "yes"
+
+ # unbound server key file.
+ # server-key-file: "/etc/unbound/unbound_server.key"
+
+ # unbound server certificate file.
+ # server-cert-file: "/etc/unbound/unbound_server.pem"
+
+ # unbound-control key file.
+ control-key-file: "/etc/unbound/unbound_control.key"
+
+ # unbound-control certificate file.
+ control-cert-file: "/etc/unbound/unbound_control.pem"
diff --git a/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/non_existent_glob_include.conf b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/non_existent_glob_include.conf
new file mode 100644
index 000000000..21620f7d5
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/non_existent_glob_include.conf
@@ -0,0 +1,85 @@
+#
+# Example configuration file.
+#
+# See unbound.conf(5) man page, version 1.9.4.
+#
+# this is a comment.
+
+#Use this to include other text into the file.
+include: "testdata/__non_existent_glob__*.conf"
+
+# The server clause sets the main parameters.
+server:
+ # whitespace is not necessary, but looks cleaner.
+
+ # verbosity number, 0 is least verbose. 1 is default.
+ # verbosity: 1
+
+ # print statistics to the log (for every thread) every N seconds.
+ # Set to "" or 0 to disable. Default is disabled.
+ # statistics-interval: 0
+
+ # enable shm for stats, default no. if you enable also enable
+ # statistics-interval, every time it also writes stats to the
+ # shared memory segment keyed with shm-key.
+ # shm-enable: no
+
+ # shm for stats uses this key, and key+1 for the shared mem segment.
+ # shm-key: 11777
+
+ # enable cumulative statistics, without clearing them after printing.
+ # statistics-cumulative: no
+ statistics-cumulative: yes
+
+ # enable extended statistics (query types, answer codes, status)
+ # printed from unbound-control. default off, because of speed.
+ # extended-statistics: no
+ # extended-statistics: yes
+
+ # number of threads to create. 1 disables threading.
+ # num-threads: 2
+
+# Python config section. To enable:
+# o use --with-pythonmodule to configure before compiling.
+# o list python in the module-config string (above) to enable.
+# It can be at the start, it gets validated results, or just before
+# the iterator and process before DNSSEC validation.
+# o and give a python-script to run.
+python:
+ # Script file to load
+ # python-script: "/etc/unbound/ubmodule-tst.py"
+
+# Remote control config section.
+remote-control:
+ # Enable remote control with unbound-control(8) here.
+ # set up the keys and certificates with unbound-control-setup.
+ control-enable: yes
+
+ # what interfaces are listened to for remote control.
+ # give 0.0.0.0 and ::0 to listen to all interfaces.
+ # set to an absolute path to use a unix local name pipe, certificates
+ # are not used for that, so key and cert files need not be present.
+ # control-interface: 127.0.0.1
+ control-interface: 10.0.0.1
+ # control-interface: ::1
+ # control-interface: /var/run/test.sock
+
+ # port number for remote control operations.
+ control-port: 8953
+
+ # for localhost, you can disable use of TLS by setting this to "no"
+ # For local sockets this option is ignored, and TLS is not used.
+ # control-use-cert: "yes"
+ control-use-cert: "yes"
+
+ # unbound server key file.
+ # server-key-file: "/etc/unbound/unbound_server.key"
+
+ # unbound server certificate file.
+ # server-cert-file: "/etc/unbound/unbound_server.pem"
+
+ # unbound-control key file.
+ control-key-file: "/etc/unbound/unbound_control.key"
+
+ # unbound-control certificate file.
+ control-cert-file: "/etc/unbound/unbound_control.pem"
diff --git a/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/non_existent_include.conf b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/non_existent_include.conf
new file mode 100644
index 000000000..e493e35bb
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/non_existent_include.conf
@@ -0,0 +1,85 @@
+#
+# Example configuration file.
+#
+# See unbound.conf(5) man page, version 1.9.4.
+#
+# this is a comment.
+
+#Use this to include other text into the file.
+include: "testdata/__non_existent_include__.conf"
+
+# The server clause sets the main parameters.
+server:
+ # whitespace is not necessary, but looks cleaner.
+
+ # verbosity number, 0 is least verbose. 1 is default.
+ # verbosity: 1
+
+ # print statistics to the log (for every thread) every N seconds.
+ # Set to "" or 0 to disable. Default is disabled.
+ # statistics-interval: 0
+
+ # enable shm for stats, default no. if you enable also enable
+ # statistics-interval, every time it also writes stats to the
+ # shared memory segment keyed with shm-key.
+ # shm-enable: no
+
+ # shm for stats uses this key, and key+1 for the shared mem segment.
+ # shm-key: 11777
+
+ # enable cumulative statistics, without clearing them after printing.
+ # statistics-cumulative: no
+ statistics-cumulative: yes
+
+ # enable extended statistics (query types, answer codes, status)
+ # printed from unbound-control. default off, because of speed.
+ # extended-statistics: no
+ # extended-statistics: yes
+
+ # number of threads to create. 1 disables threading.
+ # num-threads: 2
+
+# Python config section. To enable:
+# o use --with-pythonmodule to configure before compiling.
+# o list python in the module-config string (above) to enable.
+# It can be at the start, it gets validated results, or just before
+# the iterator and process before DNSSEC validation.
+# o and give a python-script to run.
+python:
+ # Script file to load
+ # python-script: "/etc/unbound/ubmodule-tst.py"
+
+# Remote control config section.
+remote-control:
+ # Enable remote control with unbound-control(8) here.
+ # set up the keys and certificates with unbound-control-setup.
+ control-enable: yes
+
+ # what interfaces are listened to for remote control.
+ # give 0.0.0.0 and ::0 to listen to all interfaces.
+ # set to an absolute path to use a unix local name pipe, certificates
+ # are not used for that, so key and cert files need not be present.
+ # control-interface: 127.0.0.1
+ control-interface: 10.0.0.1
+ # control-interface: ::1
+ # control-interface: /var/run/test.sock
+
+ # port number for remote control operations.
+ control-port: 8953
+
+ # for localhost, you can disable use of TLS by setting this to "no"
+ # For local sockets this option is ignored, and TLS is not used.
+ # control-use-cert: "yes"
+ control-use-cert: "yes"
+
+ # unbound server key file.
+ # server-key-file: "/etc/unbound/unbound_server.key"
+
+ # unbound server certificate file.
+ # server-cert-file: "/etc/unbound/unbound_server.pem"
+
+ # unbound-control key file.
+ control-key-file: "/etc/unbound/unbound_control.key"
+
+ # unbound-control certificate file.
+ control-cert-file: "/etc/unbound/unbound_control.pem"
diff --git a/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_glob.conf b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_glob.conf
new file mode 100644
index 000000000..f020c580a
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_glob.conf
@@ -0,0 +1,82 @@
+#
+# Example configuration file.
+#
+# See unbound.conf(5) man page, version 1.9.4.
+#
+# this is a comment.
+
+#Use this to include other text into the file.
+include: "testdata/valid_glob[2-3].conf"
+
+# The server clause sets the main parameters.
+server:
+ # whitespace is not necessary, but looks cleaner.
+
+ # verbosity number, 0 is least verbose. 1 is default.
+ # verbosity: 1
+
+ # print statistics to the log (for every thread) every N seconds.
+ # Set to "" or 0 to disable. Default is disabled.
+ # statistics-interval: 0
+
+ # enable shm for stats, default no. if you enable also enable
+ # statistics-interval, every time it also writes stats to the
+ # shared memory segment keyed with shm-key.
+ # shm-enable: no
+
+ # shm for stats uses this key, and key+1 for the shared mem segment.
+ # shm-key: 11777
+
+ # enable cumulative statistics, without clearing them after printing.
+ statistics-cumulative: yes
+
+ # enable extended statistics (query types, answer codes, status)
+ # printed from unbound-control. default off, because of speed.
+ # extended-statistics: no
+
+ # number of threads to create. 1 disables threading.
+ # num-threads: 2
+
+# Python config section. To enable:
+# o use --with-pythonmodule to configure before compiling.
+# o list python in the module-config string (above) to enable.
+# It can be at the start, it gets validated results, or just before
+# the iterator and process before DNSSEC validation.
+# o and give a python-script to run.
+python:
+ # Script file to load
+ # python-script: "/etc/unbound/ubmodule-tst.py"
+
+# Remote control config section.
+remote-control:
+ # Enable remote control with unbound-control(8) here.
+ # set up the keys and certificates with unbound-control-setup.
+ control-enable: yes
+
+ # what interfaces are listened to for remote control.
+ # give 0.0.0.0 and ::0 to listen to all interfaces.
+ # set to an absolute path to use a unix local name pipe, certificates
+ # are not used for that, so key and cert files need not be present.
+ # control-interface: 127.0.0.1
+ control-interface: 10.0.0.1
+ # control-interface: ::1
+ # control-interface: /var/run/test.sock
+
+ # port number for remote control operations.
+ # control-port: 8955
+
+ # for localhost, you can disable use of TLS by setting this to "no"
+ # For local sockets this option is ignored, and TLS is not used.
+ control-use-cert: "yes"
+
+ # unbound server key file.
+ # server-key-file: "/etc/unbound/unbound_server.key"
+
+ # unbound server certificate file.
+ # server-cert-file: "/etc/unbound/unbound_server.pem"
+
+ # unbound-control key file.
+ # control-key-file: "/etc/unbound/unbound_control_2.key"
+
+ # unbound-control certificate file.
+ # control-cert-file: "/etc/unbound/unbound_control_2.pem"
diff --git a/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_glob2.conf b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_glob2.conf
new file mode 100644
index 000000000..85bd80e0d
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_glob2.conf
@@ -0,0 +1,80 @@
+#
+# Example configuration file.
+#
+# See unbound.conf(5) man page, version 1.9.4.
+#
+# this is a comment.
+
+#Use this to include other text into the file.
+
+# The server clause sets the main parameters.
+server:
+ # whitespace is not necessary, but looks cleaner.
+
+ # verbosity number, 0 is least verbose. 1 is default.
+ # verbosity: 1
+
+ # print statistics to the log (for every thread) every N seconds.
+ # Set to "" or 0 to disable. Default is disabled.
+ # statistics-interval: 0
+
+ # enable shm for stats, default no. if you enable also enable
+ # statistics-interval, every time it also writes stats to the
+ # shared memory segment keyed with shm-key.
+ # shm-enable: no
+
+ # shm for stats uses this key, and key+1 for the shared mem segment.
+ # shm-key: 11777
+
+ # enable cumulative statistics, without clearing them after printing.
+ # statistics-cumulative: no
+
+ # enable extended statistics (query types, answer codes, status)
+ # printed from unbound-control. default off, because of speed.
+ # extended-statistics: no
+
+ # number of threads to create. 1 disables threading.
+ # num-threads: 2
+
+# Python config section. To enable:
+# o use --with-pythonmodule to configure before compiling.
+# o list python in the module-config string (above) to enable.
+# It can be at the start, it gets validated results, or just before
+# the iterator and process before DNSSEC validation.
+# o and give a python-script to run.
+python:
+ # Script file to load
+ # python-script: "/etc/unbound/ubmodule-tst.py"
+
+# Remote control config section.
+remote-control:
+ # Enable remote control with unbound-control(8) here.
+ # set up the keys and certificates with unbound-control-setup.
+ # control-enable: no
+
+ # what interfaces are listened to for remote control.
+ # give 0.0.0.0 and ::0 to listen to all interfaces.
+ # set to an absolute path to use a unix local name pipe, certificates
+ # are not used for that, so key and cert files need not be present.
+ # control-interface: 127.0.0.1
+ # control-interface: ::1
+ control-interface: /var/run/test.sock
+
+ # port number for remote control operations.
+ # control-port: 8955
+
+ # for localhost, you can disable use of TLS by setting this to "no"
+ # For local sockets this option is ignored, and TLS is not used.
+ # control-use-cert: "yes"
+
+ # unbound server key file.
+ # server-key-file: "/etc/unbound/unbound_server.key"
+
+ # unbound server certificate file.
+ # server-cert-file: "/etc/unbound/unbound_server.pem"
+
+ # unbound-control key file.
+ control-key-file: "/etc/unbound/unbound_control_2.key"
+
+ # unbound-control certificate file.
+ control-cert-file: "/etc/unbound/unbound_control_2.pem"
diff --git a/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_glob3.conf b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_glob3.conf
new file mode 100644
index 000000000..f20eacf1a
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_glob3.conf
@@ -0,0 +1,81 @@
+#
+# Example configuration file.
+#
+# See unbound.conf(5) man page, version 1.9.4.
+#
+# this is a comment.
+
+#Use this to include other text into the file.
+
+# The server clause sets the main parameters.
+server:
+ # whitespace is not necessary, but looks cleaner.
+
+ # verbosity number, 0 is least verbose. 1 is default.
+ # verbosity: 1
+
+ # print statistics to the log (for every thread) every N seconds.
+ # Set to "" or 0 to disable. Default is disabled.
+ # statistics-interval: 0
+
+ # enable shm for stats, default no. if you enable also enable
+ # statistics-interval, every time it also writes stats to the
+ # shared memory segment keyed with shm-key.
+ # shm-enable: no
+
+ # shm for stats uses this key, and key+1 for the shared mem segment.
+ # shm-key: 11777
+
+ # enable cumulative statistics, without clearing them after printing.
+ # statistics-cumulative: no
+
+ # enable extended statistics (query types, answer codes, status)
+ # printed from unbound-control. default off, because of speed.
+ # extended-statistics: no
+
+ # number of threads to create. 1 disables threading.
+ # num-threads: 2
+
+# Python config section. To enable:
+# o use --with-pythonmodule to configure before compiling.
+# o list python in the module-config string (above) to enable.
+# It can be at the start, it gets validated results, or just before
+# the iterator and process before DNSSEC validation.
+# o and give a python-script to run.
+python:
+ # Script file to load
+ # python-script: "/etc/unbound/ubmodule-tst.py"
+
+# Remote control config section.
+remote-control:
+ # Enable remote control with unbound-control(8) here.
+ # set up the keys and certificates with unbound-control-setup.
+ # control-enable: no
+
+ # what interfaces are listened to for remote control.
+ # give 0.0.0.0 and ::0 to listen to all interfaces.
+ # set to an absolute path to use a unix local name pipe, certificates
+ # are not used for that, so key and cert files need not be present.
+ # control-interface: 127.0.0.1
+ control-interface: 10.0.0.3
+ # control-interface: ::1
+ # control-interface: /var/run/test.sock
+
+ # port number for remote control operations.
+ control-port: 8955
+
+ # for localhost, you can disable use of TLS by setting this to "no"
+ # For local sockets this option is ignored, and TLS is not used.
+ # control-use-cert: "yes"
+
+ # unbound server key file.
+ # server-key-file: "/etc/unbound/unbound_server.key"
+
+ # unbound server certificate file.
+ # server-cert-file: "/etc/unbound/unbound_server.pem"
+
+ # unbound-control key file.
+ # control-key-file: "/etc/unbound/unbound_control.key"
+
+ # unbound-control certificate file.
+ # control-cert-file: "/etc/unbound/unbound_control.pem"
diff --git a/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include.conf b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include.conf
new file mode 100644
index 000000000..1974f6178
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include.conf
@@ -0,0 +1,82 @@
+#
+# Example configuration file.
+#
+# See unbound.conf(5) man page, version 1.9.4.
+#
+# this is a comment.
+
+#Use this to include other text into the file.
+include: "testdata/valid_include2.conf"
+
+# The server clause sets the main parameters.
+server:
+ # whitespace is not necessary, but looks cleaner.
+
+ # verbosity number, 0 is least verbose. 1 is default.
+ # verbosity: 1
+
+ # print statistics to the log (for every thread) every N seconds.
+ # Set to "" or 0 to disable. Default is disabled.
+ # statistics-interval: 0
+
+ # enable shm for stats, default no. if you enable also enable
+ # statistics-interval, every time it also writes stats to the
+ # shared memory segment keyed with shm-key.
+ # shm-enable: no
+
+ # shm for stats uses this key, and key+1 for the shared mem segment.
+ # shm-key: 11777
+
+ # enable cumulative statistics, without clearing them after printing.
+ statistics-cumulative: yes
+
+ # enable extended statistics (query types, answer codes, status)
+ # printed from unbound-control. default off, because of speed.
+ # extended-statistics: no
+
+ # number of threads to create. 1 disables threading.
+ # num-threads: 2
+
+# Python config section. To enable:
+# o use --with-pythonmodule to configure before compiling.
+# o list python in the module-config string (above) to enable.
+# It can be at the start, it gets validated results, or just before
+# the iterator and process before DNSSEC validation.
+# o and give a python-script to run.
+python:
+ # Script file to load
+ # python-script: "/etc/unbound/ubmodule-tst.py"
+
+# Remote control config section.
+remote-control:
+ # Enable remote control with unbound-control(8) here.
+ # set up the keys and certificates with unbound-control-setup.
+ control-enable: yes
+
+ # what interfaces are listened to for remote control.
+ # give 0.0.0.0 and ::0 to listen to all interfaces.
+ # set to an absolute path to use a unix local name pipe, certificates
+ # are not used for that, so key and cert files need not be present.
+ # control-interface: 127.0.0.1
+ control-interface: 10.0.0.1
+ # control-interface: ::1
+ # control-interface: /var/run/test.sock
+
+ # port number for remote control operations.
+ # control-port: 8955
+
+ # for localhost, you can disable use of TLS by setting this to "no"
+ # For local sockets this option is ignored, and TLS is not used.
+ control-use-cert: "yes"
+
+ # unbound server key file.
+ # server-key-file: "/etc/unbound/unbound_server.key"
+
+ # unbound server certificate file.
+ # server-cert-file: "/etc/unbound/unbound_server.pem"
+
+ # unbound-control key file.
+ # control-key-file: "/etc/unbound/unbound_control_2.key"
+
+ # unbound-control certificate file.
+ # control-cert-file: "/etc/unbound/unbound_control_2.pem"
diff --git a/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include2.conf b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include2.conf
new file mode 100644
index 000000000..c956d44d5
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include2.conf
@@ -0,0 +1,81 @@
+#
+# Example configuration file.
+#
+# See unbound.conf(5) man page, version 1.9.4.
+#
+# this is a comment.
+
+#Use this to include other text into the file.
+include: "testdata/valid_include3.conf"
+
+# The server clause sets the main parameters.
+server:
+ # whitespace is not necessary, but looks cleaner.
+
+ # verbosity number, 0 is least verbose. 1 is default.
+ # verbosity: 1
+
+ # print statistics to the log (for every thread) every N seconds.
+ # Set to "" or 0 to disable. Default is disabled.
+ # statistics-interval: 0
+
+ # enable shm for stats, default no. if you enable also enable
+ # statistics-interval, every time it also writes stats to the
+ # shared memory segment keyed with shm-key.
+ # shm-enable: no
+
+ # shm for stats uses this key, and key+1 for the shared mem segment.
+ # shm-key: 11777
+
+ # enable cumulative statistics, without clearing them after printing.
+ # statistics-cumulative: no
+
+ # enable extended statistics (query types, answer codes, status)
+ # printed from unbound-control. default off, because of speed.
+ # extended-statistics: no
+
+ # number of threads to create. 1 disables threading.
+ # num-threads: 2
+
+# Python config section. To enable:
+# o use --with-pythonmodule to configure before compiling.
+# o list python in the module-config string (above) to enable.
+# It can be at the start, it gets validated results, or just before
+# the iterator and process before DNSSEC validation.
+# o and give a python-script to run.
+python:
+ # Script file to load
+ # python-script: "/etc/unbound/ubmodule-tst.py"
+
+# Remote control config section.
+remote-control:
+ # Enable remote control with unbound-control(8) here.
+ # set up the keys and certificates with unbound-control-setup.
+ # control-enable: no
+
+ # what interfaces are listened to for remote control.
+ # give 0.0.0.0 and ::0 to listen to all interfaces.
+ # set to an absolute path to use a unix local name pipe, certificates
+ # are not used for that, so key and cert files need not be present.
+ # control-interface: 127.0.0.1
+ # control-interface: ::1
+ control-interface: /var/run/test.sock
+
+ # port number for remote control operations.
+ # control-port: 8955
+
+ # for localhost, you can disable use of TLS by setting this to "no"
+ # For local sockets this option is ignored, and TLS is not used.
+ # control-use-cert: "yes"
+
+ # unbound server key file.
+ # server-key-file: "/etc/unbound/unbound_server.key"
+
+ # unbound server certificate file.
+ # server-cert-file: "/etc/unbound/unbound_server.pem"
+
+ # unbound-control key file.
+ control-key-file: "/etc/unbound/unbound_control_2.key"
+
+ # unbound-control certificate file.
+ control-cert-file: "/etc/unbound/unbound_control_2.pem"
diff --git a/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include3.conf b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include3.conf
new file mode 100644
index 000000000..f20eacf1a
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include3.conf
@@ -0,0 +1,81 @@
+#
+# Example configuration file.
+#
+# See unbound.conf(5) man page, version 1.9.4.
+#
+# this is a comment.
+
+#Use this to include other text into the file.
+
+# The server clause sets the main parameters.
+server:
+ # whitespace is not necessary, but looks cleaner.
+
+ # verbosity number, 0 is least verbose. 1 is default.
+ # verbosity: 1
+
+ # print statistics to the log (for every thread) every N seconds.
+ # Set to "" or 0 to disable. Default is disabled.
+ # statistics-interval: 0
+
+ # enable shm for stats, default no. if you enable also enable
+ # statistics-interval, every time it also writes stats to the
+ # shared memory segment keyed with shm-key.
+ # shm-enable: no
+
+ # shm for stats uses this key, and key+1 for the shared mem segment.
+ # shm-key: 11777
+
+ # enable cumulative statistics, without clearing them after printing.
+ # statistics-cumulative: no
+
+ # enable extended statistics (query types, answer codes, status)
+ # printed from unbound-control. default off, because of speed.
+ # extended-statistics: no
+
+ # number of threads to create. 1 disables threading.
+ # num-threads: 2
+
+# Python config section. To enable:
+# o use --with-pythonmodule to configure before compiling.
+# o list python in the module-config string (above) to enable.
+# It can be at the start, it gets validated results, or just before
+# the iterator and process before DNSSEC validation.
+# o and give a python-script to run.
+python:
+ # Script file to load
+ # python-script: "/etc/unbound/ubmodule-tst.py"
+
+# Remote control config section.
+remote-control:
+ # Enable remote control with unbound-control(8) here.
+ # set up the keys and certificates with unbound-control-setup.
+ # control-enable: no
+
+ # what interfaces are listened to for remote control.
+ # give 0.0.0.0 and ::0 to listen to all interfaces.
+ # set to an absolute path to use a unix local name pipe, certificates
+ # are not used for that, so key and cert files need not be present.
+ # control-interface: 127.0.0.1
+ control-interface: 10.0.0.3
+ # control-interface: ::1
+ # control-interface: /var/run/test.sock
+
+ # port number for remote control operations.
+ control-port: 8955
+
+ # for localhost, you can disable use of TLS by setting this to "no"
+ # For local sockets this option is ignored, and TLS is not used.
+ # control-use-cert: "yes"
+
+ # unbound server key file.
+ # server-key-file: "/etc/unbound/unbound_server.key"
+
+ # unbound server certificate file.
+ # server-cert-file: "/etc/unbound/unbound_server.pem"
+
+ # unbound-control key file.
+ # control-key-file: "/etc/unbound/unbound_control.key"
+
+ # unbound-control certificate file.
+ # control-cert-file: "/etc/unbound/unbound_control.pem"
diff --git a/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include_toplevel.conf b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include_toplevel.conf
new file mode 100644
index 000000000..9e5675e10
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include_toplevel.conf
@@ -0,0 +1,82 @@
+#
+# Example configuration file.
+#
+# See unbound.conf(5) man page, version 1.9.4.
+#
+# this is a comment.
+
+#Use this to include other text into the file.
+include-toplevel: "testdata/valid_include_toplevel2.conf"
+
+# The server clause sets the main parameters.
+server:
+ # whitespace is not necessary, but looks cleaner.
+
+ # verbosity number, 0 is least verbose. 1 is default.
+ # verbosity: 1
+
+ # print statistics to the log (for every thread) every N seconds.
+ # Set to "" or 0 to disable. Default is disabled.
+ # statistics-interval: 0
+
+ # enable shm for stats, default no. if you enable also enable
+ # statistics-interval, every time it also writes stats to the
+ # shared memory segment keyed with shm-key.
+ # shm-enable: no
+
+ # shm for stats uses this key, and key+1 for the shared mem segment.
+ # shm-key: 11777
+
+ # enable cumulative statistics, without clearing them after printing.
+ statistics-cumulative: yes
+
+ # enable extended statistics (query types, answer codes, status)
+ # printed from unbound-control. default off, because of speed.
+ # extended-statistics: no
+
+ # number of threads to create. 1 disables threading.
+ # num-threads: 2
+
+# Python config section. To enable:
+# o use --with-pythonmodule to configure before compiling.
+# o list python in the module-config string (above) to enable.
+# It can be at the start, it gets validated results, or just before
+# the iterator and process before DNSSEC validation.
+# o and give a python-script to run.
+python:
+# Script file to load
+# python-script: "/etc/unbound/ubmodule-tst.py"
+
+# Remote control config section.
+remote-control:
+ # Enable remote control with unbound-control(8) here.
+ # set up the keys and certificates with unbound-control-setup.
+ control-enable: yes
+
+ # what interfaces are listened to for remote control.
+ # give 0.0.0.0 and ::0 to listen to all interfaces.
+ # set to an absolute path to use a unix local name pipe, certificates
+ # are not used for that, so key and cert files need not be present.
+ # control-interface: 127.0.0.1
+ control-interface: 10.0.0.1
+ # control-interface: ::1
+ # control-interface: /var/run/test.sock
+
+ # port number for remote control operations.
+ # control-port: 8955
+
+ # for localhost, you can disable use of TLS by setting this to "no"
+ # For local sockets this option is ignored, and TLS is not used.
+ control-use-cert: "yes"
+
+ # unbound server key file.
+ # server-key-file: "/etc/unbound/unbound_server.key"
+
+ # unbound server certificate file.
+ # server-cert-file: "/etc/unbound/unbound_server.pem"
+
+ # unbound-control key file.
+ # control-key-file: "/etc/unbound/unbound_control_2.key"
+
+ # unbound-control certificate file.
+ # control-cert-file: "/etc/unbound/unbound_control_2.pem"
diff --git a/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include_toplevel2.conf b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include_toplevel2.conf
new file mode 100644
index 000000000..f3f69470d
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include_toplevel2.conf
@@ -0,0 +1,81 @@
+#
+# Example configuration file.
+#
+# See unbound.conf(5) man page, version 1.9.4.
+#
+# this is a comment.
+
+#Use this to include other text into the file.
+include-toplevel: "testdata/valid_include_toplevel3.conf"
+
+# The server clause sets the main parameters.
+server:
+# whitespace is not necessary, but looks cleaner.
+
+# verbosity number, 0 is least verbose. 1 is default.
+# verbosity: 1
+
+# print statistics to the log (for every thread) every N seconds.
+# Set to "" or 0 to disable. Default is disabled.
+# statistics-interval: 0
+
+# enable shm for stats, default no. if you enable also enable
+# statistics-interval, every time it also writes stats to the
+# shared memory segment keyed with shm-key.
+# shm-enable: no
+
+# shm for stats uses this key, and key+1 for the shared mem segment.
+# shm-key: 11777
+
+# enable cumulative statistics, without clearing them after printing.
+# statistics-cumulative: no
+
+# enable extended statistics (query types, answer codes, status)
+# printed from unbound-control. default off, because of speed.
+# extended-statistics: no
+
+# number of threads to create. 1 disables threading.
+# num-threads: 2
+
+# Python config section. To enable:
+# o use --with-pythonmodule to configure before compiling.
+# o list python in the module-config string (above) to enable.
+# It can be at the start, it gets validated results, or just before
+# the iterator and process before DNSSEC validation.
+# o and give a python-script to run.
+python:
+# Script file to load
+# python-script: "/etc/unbound/ubmodule-tst.py"
+
+# Remote control config section.
+remote-control:
+ # Enable remote control with unbound-control(8) here.
+ # set up the keys and certificates with unbound-control-setup.
+ # control-enable: no
+
+ # what interfaces are listened to for remote control.
+ # give 0.0.0.0 and ::0 to listen to all interfaces.
+ # set to an absolute path to use a unix local name pipe, certificates
+ # are not used for that, so key and cert files need not be present.
+ # control-interface: 127.0.0.1
+ # control-interface: ::1
+ control-interface: /var/run/test.sock
+
+ # port number for remote control operations.
+ # control-port: 8955
+
+ # for localhost, you can disable use of TLS by setting this to "no"
+ # For local sockets this option is ignored, and TLS is not used.
+ # control-use-cert: "yes"
+
+ # unbound server key file.
+ # server-key-file: "/etc/unbound/unbound_server.key"
+
+ # unbound server certificate file.
+ # server-cert-file: "/etc/unbound/unbound_server.pem"
+
+ # unbound-control key file.
+ control-key-file: "/etc/unbound/unbound_control_2.key"
+
+ # unbound-control certificate file.
+ control-cert-file: "/etc/unbound/unbound_control_2.pem"
diff --git a/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include_toplevel3.conf b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include_toplevel3.conf
new file mode 100644
index 000000000..d30778c01
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/unbound/config/testdata/valid_include_toplevel3.conf
@@ -0,0 +1,81 @@
+#
+# Example configuration file.
+#
+# See unbound.conf(5) man page, version 1.9.4.
+#
+# this is a comment.
+
+#Use this to include other text into the file.
+
+# The server clause sets the main parameters.
+server:
+# whitespace is not necessary, but looks cleaner.
+
+# verbosity number, 0 is least verbose. 1 is default.
+# verbosity: 1
+
+# print statistics to the log (for every thread) every N seconds.
+# Set to "" or 0 to disable. Default is disabled.
+# statistics-interval: 0
+
+# enable shm for stats, default no. if you enable also enable
+# statistics-interval, every time it also writes stats to the
+# shared memory segment keyed with shm-key.
+# shm-enable: no
+
+# shm for stats uses this key, and key+1 for the shared mem segment.
+# shm-key: 11777
+
+# enable cumulative statistics, without clearing them after printing.
+# statistics-cumulative: no
+
+# enable extended statistics (query types, answer codes, status)
+# printed from unbound-control. default off, because of speed.
+# extended-statistics: no
+
+# number of threads to create. 1 disables threading.
+# num-threads: 2
+
+# Python config section. To enable:
+# o use --with-pythonmodule to configure before compiling.
+# o list python in the module-config string (above) to enable.
+# It can be at the start, it gets validated results, or just before
+# the iterator and process before DNSSEC validation.
+# o and give a python-script to run.
+python:
+# Script file to load
+# python-script: "/etc/unbound/ubmodule-tst.py"
+
+# Remote control config section.
+remote-control:
+ # Enable remote control with unbound-control(8) here.
+ # set up the keys and certificates with unbound-control-setup.
+ # control-enable: no
+
+ # what interfaces are listened to for remote control.
+ # give 0.0.0.0 and ::0 to listen to all interfaces.
+ # set to an absolute path to use a unix local name pipe, certificates
+ # are not used for that, so key and cert files need not be present.
+ # control-interface: 127.0.0.1
+ control-interface: 10.0.0.3
+ # control-interface: ::1
+ # control-interface: /var/run/test.sock
+
+ # port number for remote control operations.
+ control-port: 8955
+
+ # for localhost, you can disable use of TLS by setting this to "no"
+ # For local sockets this option is ignored, and TLS is not used.
+ # control-use-cert: "yes"
+
+ # unbound server key file.
+ # server-key-file: "/etc/unbound/unbound_server.key"
+
+ # unbound server certificate file.
+ # server-cert-file: "/etc/unbound/unbound_server.pem"
+
+ # unbound-control key file.
+ # control-key-file: "/etc/unbound/unbound_control.key"
+
+ # unbound-control certificate file.
+ # control-cert-file: "/etc/unbound/unbound_control.pem"
diff --git a/src/go/collectors/go.d.plugin/modules/unbound/config_schema.json b/src/go/collectors/go.d.plugin/modules/unbound/config_schema.json
new file mode 100644
index 000000000..500b60169
--- /dev/null
+++ b/src/go/collectors/go.d.plugin/modules/unbound/config_schema.json
@@ -0,0 +1,113 @@
+{
+ "jsonSchema": {
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "Unbound collector configuration.",
+ "type": "object",
+ "properties": {
+ "update_every": {
+ "title": "Update every",
+ "description": "Data collection interval, measured in seconds.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 1
+ },
+ "address": {
+ "title": "Address",
+ "description": "The IP address and port where the Unbound server listens for connections.",
+ "type": "string",
+ "default": "127.0.0.1:8953"
+ },
+ "timeout": {
+ "title": "Timeout",
+ "description": "The timeout duration, in seconds, for connection, read, write, and SSL handshake operations.",
+ "type": "number",
+ "minimum": 0.5,
+ "default": 1
+ },
+ "conf_path": {
+ "title": "Path to unbound.conf",
+ "description": "The absolute path to the Unbound configuration file. Providing this path enables the tool to make adjustments based on the 'remote-control' section.",
+ "type": "string",
+ "default": "/etc/unbound/unbound.conf"
+ },
+ "cumulative_stats": {
+ "title": "Cumulative stats",
+ "description": "Specifies whether statistics collection mode is enabled. Should match the 'statistics-cumulative' parameter in unbound.conf.",
+ "type": "boolean",
+ "default": false
+ },
+ "use_tls": {
+ "title": "Use TLS",
+ "description": "Indicates whether TLS should be used for secure communication.",
+ "type": "boolean",
+ "default": true
+ },
+ "tls_skip_verify": {
+ "title": "Skip TLS verification",
+ "description": "If set, TLS certificate verification will be skipped.",
+ "type": "boolean",
+ "default": true
+ },
+ "tls_ca": {
+ "title": "TLS CA",
+ "description": "The path to the CA certificate file for TLS verification.",
+ "type": "string",
+ "pattern": "^$|^/"
+ },
+ "tls_cert": {
+ "title": "TLS certificate",
+ "description": "The path to the client certificate file for TLS authentication.",
+ "type": "string",
+ "default": "/etc/unbound/unbound_control.pem",
+ "pattern": "^$|^/"
+ },
+ "tls_key": {
+ "title": "TLS key",
+ "description": "The path to the client key file for TLS authentication.",
+ "type": "string",
+ "default": "/etc/unbound/unbound_control.key",
+ "pattern": "^$|^/"
+ }
+ },
+ "required": [
+ "address"
+ ],
+ "additionalProperties": false,
+ "patternProperties": {
+ "^name$": {}
+ }
+ },
+ "uiSchema": {
+ "uiOptions": {
+ "fullPage": true
+ },
+ "timeout": {
+ "ui:help": "Accepts decimals for precise control (e.g., type 1.5 for 1.5 seconds)."
+ },
+ "ui:flavour": "tabs",
+ "ui:options": {
+ "tabs": [
+ {
+ "title": "Base",
+ "fields": [
+ "update_every",
+ "address",
+ "timeout",
+ "conf_path",
+ "cumulative_stats"
+ ]
+ },
+ {
+ "title": "TLS",
+ "fields": [
+ "use_tls",
+ "tls_skip_verify",
+ "tls_ca",
+ "tls_cert",
+ "tls_key"
+ ]
+ }
+ ]
+ }
+ }
+}