@cryptotaxi247 / netdata-1 / commits / 46d0c2de7

feat(go.d/dnsquery): support system DNS servers from /etc/resolv.conf (#19562)

Ilya Mashchenko committed Feb 3, 2025 at 13:58 UTC 46d0c2de79ddd04ac3e1e8c62029b8e81967e065
7 files changed +57 -23
src/go/go.mod
+1
@@ -71,6 +71,7 @@ require (
71 github.com/Masterminds/semver/v3 v3.3.0 // indirect
72 github.com/Microsoft/go-winio v0.6.1 // indirect
73 github.com/cespare/xxhash/v2 v2.3.0 // indirect
74 + github.com/containerd/log v0.1.0 // indirect
75 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
76 github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc // indirect
77 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
src/go/plugin/go.d/collector/dnsquery/collector.go
+4
@@ -83,6 +83,10 @@ func (c *Collector) Init(context.Context) error {
83 return fmt.Errorf("config validation: %v", err)
84 }
85
86 + if err := c.initServers(); err != nil {
87 + return fmt.Errorf("failed to initialize servers: %v", err)
88 + }
89 +
90 rt, err := c.initRecordTypes()
91 if err != nil {
92 return fmt.Errorf("init record type: %v", err)
src/go/plugin/go.d/collector/dnsquery/collector_test.go
-11
@@ -77,17 +77,6 @@ func TestCollector_Init(t *testing.T) {
77 Timeout: confopt.Duration(time.Second),
78 },
79 },
80 - "fail when servers not set": {
81 - wantFail: true,
82 - config: Config{
83 - Domains: []string{"example.com"},
84 - Servers: nil,
85 - Network: "udp",
86 - RecordTypes: []string{"A"},
87 - Port: 53,
88 - Timeout: confopt.Duration(time.Second),
89 - },
90 - },
80 "fail when network is invalid": {
81 wantFail: true,
82 config: Config{
src/go/plugin/go.d/collector/dnsquery/config_schema.json
+2 -4
@@ -65,7 +65,7 @@
65 },
66 "servers": {
67 "title": "Servers",
68 - "description": "List of DNS servers to query.",
68 + "description": "List of DNS servers to query. If empty, the collector will automatically use DNS servers from `/etc/resolv.conf`.",
69 "type": [
70 "array",
71 "null"
@@ -78,8 +78,7 @@
78 "default": [
79 "8.8.8.8"
80 ],
81 - "uniqueItems": true,
82 - "minItems": 1
81 + "uniqueItems": true
82 },
83 "domains": {
84 "title": "Domains",
@@ -107,7 +106,6 @@
106 },
107 "required": [
108 "domains",
110 - "servers",
109 "network"
110 ],
111 "patternProperties": {
src/go/plugin/go.d/collector/dnsquery/init.go
+18 -4
@@ -16,10 +16,6 @@ func (c *Collector) verifyConfig() error {
16 return errors.New("no domains specified")
17 }
18
19 - if len(c.Servers) == 0 {
20 - return errors.New("no servers specified")
21 - }
22 -
19 if !(c.Network == "" || c.Network == "udp" || c.Network == "tcp" || c.Network == "tcp-tls") {
20 return fmt.Errorf("wrong network transport : %s", c.Network)
21 }
@@ -36,6 +32,24 @@ func (c *Collector) verifyConfig() error {
32 return nil
33 }
34
35 +func (c *Collector) initServers() error {
36 + if len(c.Servers) != 0 {
37 + return nil
38 + }
39 + servers, err := getResolvConfNameservers()
40 + if err != nil {
41 + return err
42 + }
43 + if len(servers) == 0 {
44 + return errors.New("no resolv conf nameservers")
45 + }
46 +
47 + c.Debugf("resolv conf nameservers: %v", servers)
48 + c.Servers = servers
49 +
50 + return nil
51 +}
52 +
53 func (c *Collector) initRecordTypes() (map[string]uint16, error) {
54 types := make(map[string]uint16)
55 for _, v := range c.RecordTypes {
src/go/plugin/go.d/collector/dnsquery/metadata.yaml
+16 -4
@@ -62,9 +62,9 @@ modules:
62 default_value: ""
63 required: true
64 - name: servers
65 - description: Servers to query.
65 + description: Servers to query. If empty, the collector will automatically use DNS servers from `/etc/resolv.conf`.
66 default_value: ""
67 - required: true
67 + required: false
68 - name: port
69 description: DNS server port.
70 default_value: 53
@@ -86,8 +86,8 @@ modules:
86 title: Config
87 enabled: true
88 list:
89 - - name: Basic
90 - description: An example configuration.
89 + - name: Specific DNS servers
90 + description: An example configuration using Google's public DNS servers.
91 config: |
92 jobs:
93 - name: job1
@@ -101,6 +101,18 @@ modules:
101 servers:
102 - 8.8.8.8
103 - 8.8.4.4
104 + - name: System DNS
105 + description: An example configuration using DNS servers from `/etc/resolv.conf`.
106 + config: |
107 + jobs:
108 + - name: job1
109 + record_types:
110 + - A
111 + - AAAA
112 + domains:
113 + - google.com
114 + - github.com
115 + - reddit.com
116 troubleshooting:
117 problems:
118 list: []
src/go/plugin/go.d/collector/dnsquery/resolvconf.go new
+16
@@ -0,0 +1,16 @@
1 +package dnsquery
2 +
3 +import (
4 + "os"
5 +
6 + "github.com/docker/docker/libnetwork/resolvconf"
7 +)
8 +
9 +func getResolvConfNameservers() ([]string, error) {
10 + path := resolvconf.Path()
11 + bs, err := os.ReadFile(path)
12 + if err != nil {
13 + return nil, err
14 + }
15 + return resolvconf.GetNameservers(bs, resolvconf.IP), nil
16 +}