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
+}