fix(go.d): derive sd pipeline names from source context (#22105)
* go.d: derive sd pipeline names from source context * docs(go.d): document net_listeners TUID placeholder
Ilya Mashchenko committed
Apr 1, 2026 at 13:10 UTC
3c2ad5b05593d0815b7c654cc5b0c45fd9f28a18
15 files changed
+125
-92
src/go/plugin/agent/discovery/sd/dyncfg.go
+25
-6
@@ -39,6 +39,13 @@ func dyncfgSDTemplateCmds() string {
39
)
40
}
41
42
+func dyncfgTemplateJobName(fn dyncfg.Function) string {
43
+ if name := fn.JobName(); name != "" {
44
+ return name
45
+ }
46
+ return "test"
47
+}
48
+
49
func (d *ServiceDiscovery) dyncfgSDTemplateCreate(discovererType string) {
50
d.dyncfgApi.ConfigCreate(netdataapi.ConfigOpts{
51
ID: d.dyncfgTemplateID(discovererType),
@@ -78,7 +85,7 @@ func (cb *sdCallbacks) ExtractKey(fn dyncfg.Function) (key, name string, ok bool
85
86
func (cb *sdCallbacks) ParseAndValidate(fn dyncfg.Function, name string) (sdConfig, error) {
87
dt, _, _ := cb.sd.extractDiscovererAndName(fn.ID())
81
- if _, err := parseDyncfgPayload(fn.Payload(), dt, cb.sd.configDefaults, cb.sd.discovererRegistry(), true); err != nil {
88
+ if _, err := parseDyncfgPayload(fn.Payload(), dt, name, cb.sd.configDefaults, cb.sd.discovererRegistry(), true); err != nil {
89
return nil, err
90
}
91
pkey := pipelineKey(dt, name)
@@ -241,8 +248,17 @@ func (d *ServiceDiscovery) dyncfgCmdTest(fn dyncfg.Function) {
248
return
249
}
250
251
+ if !isJob {
252
+ name = dyncfgTemplateJobName(fn)
253
+ }
254
+ if err := dyncfg.ValidateJobName(name); err != nil {
255
+ d.Warningf("dyncfg: test: unacceptable job name '%s' for '%s': %v", name, dt, err)
256
+ d.dyncfgApi.SendCodef(fn, 400, "Unacceptable job name '%s': %v.", name, err)
257
+ return
258
+ }
259
+
260
// Parse and validate the config without storing it
245
- _, err := parseDyncfgPayload(fn.Payload(), dt, d.configDefaults, d.discovererRegistry(), true)
261
+ _, err := parseDyncfgPayload(fn.Payload(), dt, name, d.configDefaults, d.discovererRegistry(), true)
262
if err != nil {
263
d.Warningf("dyncfg: test: failed to parse config for '%s': %v", dt, err)
264
d.dyncfgApi.SendCodef(fn, 400, "Failed to parse config: %v", err)
@@ -261,7 +277,7 @@ func (d *ServiceDiscovery) dyncfgCmdTest(fn dyncfg.Function) {
277
// Returns YAML representation of the config for user-friendly file format
278
func (d *ServiceDiscovery) dyncfgCmdUserconfig(fn dyncfg.Function) {
279
id := fn.ID()
264
- dt, _, _ := d.extractDiscovererAndName(id)
280
+ dt, name, isJob := d.extractDiscovererAndName(id)
281
282
if !d.hasDiscovererType(dt) {
283
d.Warningf("dyncfg: userconfig: invalid discoverer type in ID '%s'", id)
@@ -275,14 +291,17 @@ func (d *ServiceDiscovery) dyncfgCmdUserconfig(fn dyncfg.Function) {
291
return
292
}
293
278
- if _, err := parseDyncfgPayload(fn.Payload(), dt, d.configDefaults, d.discovererRegistry(), false); err != nil {
294
+ jobName := name
295
+ if !isJob || jobName == "" {
296
+ jobName = dyncfgTemplateJobName(fn)
297
+ }
298
+
299
+ if _, err := parseDyncfgPayload(fn.Payload(), dt, jobName, d.configDefaults, d.discovererRegistry(), false); err != nil {
300
d.Warningf("dyncfg: userconfig: failed to parse config for '%s': %v", id, err)
301
d.dyncfgApi.SendCodef(fn, 400, "Failed to parse config: %v", err)
302
return
303
}
304
284
- jobName := fn.JobName() // May be empty - userConfigFromPayload will use name from payload or default
285
-
305
bs, err := userConfigFromPayload(fn.Payload(), dt, jobName)
306
if err != nil {
307
d.Warningf("dyncfg: userconfig: failed to create config for '%s': %v", id, err)
src/go/plugin/agent/discovery/sd/dyncfg_cache.go
+17
-3
@@ -5,6 +5,7 @@ package sd
5
import (
6
"encoding/json"
7
"fmt"
8
+ "path/filepath"
9
"strings"
10
11
"github.com/netdata/netdata/go/plugins/pkg/pluginconfig"
@@ -89,6 +90,7 @@ func (c sdConfig) ToPipelineConfig(configDefaults confgroup.Registry) (pipeline.
90
if err := json.Unmarshal(data, &cfg); err != nil {
91
return pipeline.Config{}, fmt.Errorf("unmarshal pipeline config: %w", err)
92
}
93
+ cfg.Name = c.Name()
94
95
cfg.ConfigDefaults = configDefaults
96
@@ -117,7 +119,8 @@ func (c sdConfig) DataJSON() []byte {
119
}
120
121
// newSDConfigFromYAML creates an sdConfig from YAML bytes.
120
-// Used when loading file configs. Cleans the name for dyncfg compatibility.
122
+// Used when loading file configs. The stored name prefers raw config content,
123
+// falling back to the file basename, and is cleaned for dyncfg compatibility.
124
func newSDConfigFromYAML(data []byte, source, sourceType, pipelineKey string) (sdConfig, error) {
125
// First unmarshal to pipeline.Config to get discoverer type and apply YAML processing
126
var cfg pipeline.Config
@@ -136,8 +139,11 @@ func newSDConfigFromYAML(data []byte, source, sourceType, pipelineKey string) (s
139
return nil, fmt.Errorf("unmarshal to map: %w", err)
140
}
141
139
- // Clean the name for dyncfg compatibility
140
- if name := m.Name(); name != "" {
142
+ name := strings.TrimSpace(cfg.Name)
143
+ if name == "" {
144
+ name = configNameFromSource(source)
145
+ }
146
+ if name != "" {
147
m["name"] = naming.Sanitize(name)
148
}
149
@@ -182,3 +188,11 @@ func sourceTypeFromPath(path string) string {
188
}
189
return confgroup.TypeUser
190
}
191
+
192
+func configNameFromSource(source string) string {
193
+ base := filepath.Base(strings.TrimSpace(source))
194
+ if strings.HasSuffix(base, ".conf") {
195
+ base = strings.TrimSuffix(base, ".conf")
196
+ }
197
+ return base
198
+}
src/go/plugin/agent/discovery/sd/dyncfg_parse.go
+6
-12
@@ -12,10 +12,9 @@ import (
12
"gopkg.in/yaml.v2"
13
)
14
15
-// parseDyncfgPayload parses a dyncfg JSON payload into a pipeline.Config.
16
-// Since pipeline.Config now has proper JSON tags matching the schema,
17
-// we can unmarshal directly without type-specific parsing.
18
-func parseDyncfgPayload(payload []byte, discovererType string, configDefaults confgroup.Registry, reg Registry, validate bool) (pipeline.Config, error) {
15
+// parseDyncfgPayload parses a dyncfg JSON payload into a runtime pipeline.Config.
16
+// The dyncfg job name is authoritative and overrides any serialized payload name.
17
+func parseDyncfgPayload(payload []byte, discovererType, name string, configDefaults confgroup.Registry, reg Registry, validate bool) (pipeline.Config, error) {
18
if reg == nil {
19
return pipeline.Config{}, fmt.Errorf("discoverer registry is not configured")
20
}
@@ -25,6 +24,7 @@ func parseDyncfgPayload(payload []byte, discovererType string, configDefaults co
24
return pipeline.Config{}, fmt.Errorf("unmarshal %s config: %w", discovererType, err)
25
}
26
27
+ cfg.Name = name
28
cfg.ConfigDefaults = configDefaults
29
30
// Validate that the config has the expected discoverer type
@@ -75,20 +75,14 @@ func configToJSON(data []byte) ([]byte, error) {
75
}
76
77
// userConfigFromPayload converts a JSON payload to YAML format for user editing.
78
-// It unmarshals JSON into pipeline.Config, then marshals to YAML.
79
-// If jobName is provided (non-empty), it overrides the name from payload.
80
-// This ensures consistent field ordering and validates the structure.
78
+// The returned YAML always uses jobName (or "test") as the top-level pipeline name.
79
func userConfigFromPayload(payload []byte, discovererType, jobName string) ([]byte, error) {
80
var cfg pipeline.Config
81
if err := json.Unmarshal(payload, &cfg); err != nil {
82
return nil, fmt.Errorf("unmarshal json: %w", err)
83
}
84
87
- // Use jobName if provided, otherwise keep name from payload
88
- if jobName != "" {
89
- cfg.Name = jobName
90
- }
91
- // If still no name, use default
85
+ cfg.Name = jobName
86
if cfg.Name == "" {
87
cfg.Name = "test"
88
}
src/go/plugin/agent/discovery/sd/dyncfg_test.go
+7
-10
@@ -414,7 +414,7 @@ func TestServiceDiscovery_DyncfgGet(t *testing.T) {
414
}{
415
"get existing job": {
416
createSim: func() *dyncfgSim {
417
- cfg := newTestNetListenersConfig("test-job", 0, 0, defaultTestServices())
417
+ cfg := newTestNetListenersConfig("serialized-name", 0, 0, defaultTestServices())
418
payload, _ := json.Marshal(cfg)
419
420
return &dyncfgSim{
@@ -436,6 +436,7 @@ func TestServiceDiscovery_DyncfgGet(t *testing.T) {
436
assert.Contains(t, got, "FUNCTION_RESULT_BEGIN 2-get 200 application/json")
437
// JSON key order may vary, so check for presence of expected fields
438
assert.Contains(t, got, `"name":"test-job"`)
439
+ assert.NotContains(t, got, `"name":"serialized-name"`)
440
assert.Contains(t, got, `"discoverer":{`)
441
assert.Contains(t, got, `"net_listeners":{}`)
442
},
@@ -852,7 +853,7 @@ func TestServiceDiscovery_DyncfgUserconfig(t *testing.T) {
853
}{
854
"userconfig for template": {
855
createSim: func() *dyncfgSim {
855
- cfg := newTestNetListenersConfig("test-job", confopt.LongDuration(5*time.Second), 0, defaultTestServices())
856
+ cfg := newTestNetListenersConfig("serialized-name", confopt.LongDuration(5*time.Second), 0, defaultTestServices())
857
payload, _ := json.Marshal(cfg)
858
859
return &dyncfgSim{
@@ -863,7 +864,8 @@ func TestServiceDiscovery_DyncfgUserconfig(t *testing.T) {
864
},
865
wantDyncfgFunc: func(t *testing.T, got string) {
866
assert.Contains(t, got, "FUNCTION_RESULT_BEGIN 1-userconfig 200 application/yaml")
866
- assert.Contains(t, got, "name: test-job")
867
+ assert.Contains(t, got, "name: test")
868
+ assert.NotContains(t, got, "name: serialized-name")
869
assert.Contains(t, got, "discoverer:")
870
assert.Contains(t, got, "net_listeners:")
871
assert.Contains(t, got, "interval: 5")
@@ -874,7 +876,7 @@ func TestServiceDiscovery_DyncfgUserconfig(t *testing.T) {
876
},
877
"userconfig for existing job": {
878
createSim: func() *dyncfgSim {
877
- cfg := newTestNetListenersConfig("test-job", confopt.LongDuration(5*time.Second), 0, defaultTestServices())
879
+ cfg := newTestNetListenersConfig("serialized-name", confopt.LongDuration(5*time.Second), 0, defaultTestServices())
880
payload, _ := json.Marshal(cfg)
881
882
return &dyncfgSim{
@@ -893,6 +895,7 @@ func TestServiceDiscovery_DyncfgUserconfig(t *testing.T) {
895
assert.Contains(t, got, "FUNCTION_RESULT_BEGIN 1-add 202 application/json")
896
assert.Contains(t, got, "FUNCTION_RESULT_BEGIN 2-userconfig 200 application/yaml")
897
assert.Contains(t, got, "name: test-job")
898
+ assert.NotContains(t, got, "name: serialized-name")
899
assert.Contains(t, got, "discoverer:")
900
assert.Contains(t, got, "net_listeners:")
901
assert.Contains(t, got, "interval: 5")
@@ -913,7 +916,6 @@ func TestServiceDiscovery_DyncfgUserconfig(t *testing.T) {
916
},
917
wantDyncfgFunc: func(t *testing.T, got string) {
918
assert.Contains(t, got, "FUNCTION_RESULT_BEGIN 1-userconfig 200 application/yaml")
916
- assert.Contains(t, got, "name: docker-test")
919
assert.Contains(t, got, "discoverer:")
920
assert.Contains(t, got, "docker:")
921
assert.Contains(t, got, "address: unix:///var/run/docker.sock")
@@ -937,7 +939,6 @@ func TestServiceDiscovery_DyncfgUserconfig(t *testing.T) {
939
},
940
wantDyncfgFunc: func(t *testing.T, got string) {
941
assert.Contains(t, got, "FUNCTION_RESULT_BEGIN 1-userconfig 200 application/yaml")
940
- assert.Contains(t, got, "name: k8s-test")
942
assert.Contains(t, got, "discoverer:")
943
assert.Contains(t, got, "k8s:")
944
assert.Contains(t, got, "role: pod")
@@ -963,7 +964,6 @@ func TestServiceDiscovery_DyncfgUserconfig(t *testing.T) {
964
},
965
wantDyncfgFunc: func(t *testing.T, got string) {
966
assert.Contains(t, got, "FUNCTION_RESULT_BEGIN 1-userconfig 200 application/yaml")
966
- assert.Contains(t, got, "name: snmp-test")
967
assert.Contains(t, got, "discoverer:")
968
assert.Contains(t, got, "snmp:")
969
assert.Contains(t, got, "rescan_interval: 1h")
@@ -1133,7 +1133,6 @@ CONFIG test:sd:docker:docker-test create accepted job /collectors/test/ServiceDi
1133
},
1134
wantDyncfgFunc: func(t *testing.T, got string) {
1135
assert.Contains(t, got, "FUNCTION_RESULT_BEGIN 2-get 200 application/json")
1136
- assert.Contains(t, got, `"name":"docker-test"`)
1136
assert.Contains(t, got, `"discoverer":{`)
1137
assert.Contains(t, got, `"docker":{`)
1138
assert.Contains(t, got, `"address":"unix:///var/run/docker.sock"`)
@@ -1240,7 +1239,6 @@ CONFIG test:sd:k8s:k8s-test create accepted job /collectors/test/ServiceDiscover
1239
},
1240
wantDyncfgFunc: func(t *testing.T, got string) {
1241
assert.Contains(t, got, "FUNCTION_RESULT_BEGIN 2-get 200 application/json")
1243
- assert.Contains(t, got, `"name":"k8s-test"`)
1242
assert.Contains(t, got, `"discoverer":{`)
1243
assert.Contains(t, got, `"k8s":[`)
1244
assert.Contains(t, got, `"role":"pod"`)
@@ -1362,7 +1360,6 @@ CONFIG test:sd:snmp:snmp-test create accepted job /collectors/test/ServiceDiscov
1360
},
1361
wantDyncfgFunc: func(t *testing.T, got string) {
1362
assert.Contains(t, got, "FUNCTION_RESULT_BEGIN 2-get 200 application/json")
1365
- assert.Contains(t, got, `"name":"snmp-test"`)
1363
assert.Contains(t, got, `"discoverer":{`)
1364
assert.Contains(t, got, `"snmp":{`)
1365
assert.Contains(t, got, `"rescan_interval":"1h"`)
src/go/plugin/agent/discovery/sd/pipeline/config.go
+1
-1
@@ -320,7 +320,7 @@ func NewDiscovererPayload(typ string, cfg any) (DiscovererPayload, error) {
320
func (c Config) MarshalYAML() (any, error) {
321
type output struct {
322
Disabled bool `yaml:"disabled,omitempty"`
323
- Name string `yaml:"name"`
323
+ Name string `yaml:"name,omitempty"`
324
Discoverer DiscovererPayload `yaml:"discoverer,omitempty"`
325
Services []ServiceRuleConfig `yaml:"services,omitempty"`
326
}
src/go/plugin/agent/discovery/sd/pipeline/pipeline_test.go
+1
@@ -42,6 +42,7 @@ func Test_defaultConfigs(t *testing.T) {
42
43
var cfg Config
44
require.NoErrorf(t, yaml.Unmarshal(bs, &cfg), "unmarshal '%s'", e.Name())
45
+ cfg.Name = strings.TrimSuffix(e.Name(), filepath.Ext(e.Name()))
46
47
_, err = New(cfg, factory)
48
require.NoErrorf(t, err, "create pipeline '%s'", e.Name())
src/go/plugin/agent/discovery/sd/sd_test.go
+65
-18
@@ -16,7 +16,7 @@ func TestServiceDiscovery_Run(t *testing.T) {
16
tests := map[string]discoverySim{
17
"add pipeline": {
18
configs: []confFile{
19
- prepareConfigFile("source", "name"),
19
+ prepareConfigFile("name.conf", "name"),
20
},
21
wantPipelines: []*mockPipeline{
22
{name: "name", started: true, stopped: false},
@@ -24,14 +24,30 @@ func TestServiceDiscovery_Run(t *testing.T) {
24
},
25
"add disabled pipeline": {
26
configs: []confFile{
27
- prepareDisabledConfigFile("source", "name"),
27
+ prepareDisabledConfigFile("name.conf", "name"),
28
},
29
wantPipelines: nil,
30
},
31
+ "add pipeline without raw name uses basename": {
32
+ configs: []confFile{
33
+ prepareUnnamedConfigFile("basename.conf"),
34
+ },
35
+ wantPipelines: []*mockPipeline{
36
+ {name: "basename", started: true, stopped: false},
37
+ },
38
+ },
39
+ "raw file name overrides basename": {
40
+ configs: []confFile{
41
+ prepareConfigFile("basename.conf", "custom-name"),
42
+ },
43
+ wantPipelines: []*mockPipeline{
44
+ {name: "custom-name", started: true, stopped: false},
45
+ },
46
+ },
47
"remove pipeline": {
48
configs: []confFile{
33
- prepareConfigFile("source", "name"),
34
- prepareEmptyConfigFile("source"),
49
+ prepareConfigFile("name.conf", "name"),
50
+ prepareEmptyConfigFile("name.conf"),
51
},
52
wantPipelines: []*mockPipeline{
53
{name: "name", started: true, stopped: true},
@@ -41,9 +57,9 @@ func TestServiceDiscovery_Run(t *testing.T) {
57
// With the new stability logic, re-adding the same config from the same source
58
// when it's already running is a no-op. Only 1 pipeline should be created.
59
configs: []confFile{
44
- prepareConfigFile("source", "name"),
45
- prepareConfigFile("source", "name"),
46
- prepareConfigFile("source", "name"),
60
+ prepareConfigFile("name.conf", "name"),
61
+ prepareConfigFile("name.conf", "name"),
62
+ prepareConfigFile("name.conf", "name"),
63
},
64
wantPipelines: []*mockPipeline{
65
{name: "name", started: true, stopped: false},
@@ -51,8 +67,9 @@ func TestServiceDiscovery_Run(t *testing.T) {
67
},
68
"restart pipeline": {
69
configs: []confFile{
54
- prepareConfigFile("source", "name1"),
55
- prepareConfigFile("source", "name2"),
70
+ prepareConfigFile("name1.conf", "name1"),
71
+ prepareEmptyConfigFile("name1.conf"),
72
+ prepareConfigFile("name2.conf", "name2"),
73
},
74
wantPipelines: []*mockPipeline{
75
{name: "name1", started: true, stopped: true},
@@ -61,17 +78,17 @@ func TestServiceDiscovery_Run(t *testing.T) {
78
},
79
"invalid pipeline config": {
80
configs: []confFile{
64
- prepareConfigFile("source", "invalid"),
81
+ prepareInvalidConfigFile("invalid.conf"),
82
},
83
wantPipelines: nil,
84
},
68
- "invalid config for running pipeline": {
85
+ "invalid config for running pipeline with same basename is ignored": {
86
configs: []confFile{
70
- prepareConfigFile("source", "name"),
71
- prepareConfigFile("source", "invalid"),
87
+ prepareConfigFile("name.conf", "name"),
88
+ prepareInvalidConfigFile("name.conf"),
89
},
90
wantPipelines: []*mockPipeline{
74
- {name: "name", started: true, stopped: true},
91
+ {name: "name", started: true, stopped: false},
92
},
93
},
94
}
@@ -99,6 +116,7 @@ func prepareConfigFile(source, name string) confFile {
116
cfg := pipeline.Config{
117
Name: name,
118
Discoverer: disc,
119
+ Services: defaultTestServices(),
120
}
121
bs, _ := yaml.Marshal(cfg)
122
@@ -113,6 +131,21 @@ func prepareUnsupportedDiscovererConfigFile(source, name string) confFile {
131
cfg := pipeline.Config{
132
Name: name,
133
Discoverer: disc,
134
+ Services: defaultTestServices(),
135
+ }
136
+ bs, _ := yaml.Marshal(cfg)
137
+
138
+ return confFile{
139
+ source: source,
140
+ content: bs,
141
+ }
142
+}
143
+
144
+func prepareUnnamedConfigFile(source string) confFile {
145
+ disc, _ := pipeline.NewDiscovererPayload(testDiscovererTypeNetListeners, testNetListenersConfig{})
146
+ cfg := pipeline.Config{
147
+ Discoverer: disc,
148
+ Services: defaultTestServices(),
149
}
150
bs, _ := yaml.Marshal(cfg)
151
@@ -134,6 +167,20 @@ func prepareDisabledConfigFile(source, name string) confFile {
167
Name: name,
168
Disabled: true,
169
Discoverer: disc,
170
+ Services: defaultTestServices(),
171
+ }
172
+ bs, _ := yaml.Marshal(cfg)
173
+
174
+ return confFile{
175
+ source: source,
176
+ content: bs,
177
+ }
178
+}
179
+
180
+func prepareInvalidConfigFile(source string) confFile {
181
+ disc, _ := pipeline.NewDiscovererPayload(testDiscovererTypeNetListeners, testNetListenersConfig{})
182
+ cfg := pipeline.Config{
183
+ Discoverer: disc,
184
}
185
bs, _ := yaml.Marshal(cfg)
186
@@ -191,8 +238,8 @@ func TestServiceDiscovery_Priority(t *testing.T) {
238
// Two stock configs with same name from different files
239
// Same priority + running = keep existing
240
configs: []confFile{
194
- prepareConfigFile("/usr/lib/netdata/conf.d/sd/file1.conf", "myconfig"),
195
- prepareConfigFile("/usr/lib/netdata/conf.d/sd/file2.conf", "myconfig"),
241
+ prepareConfigFile("/usr/lib/netdata/conf.d/sd/dir1/myconfig.conf", "myconfig"),
242
+ prepareConfigFile("/usr/lib/netdata/conf.d/sd/dir2/myconfig.conf", "myconfig"),
243
},
244
wantPipelines: []*mockPipeline{
245
{name: "myconfig", started: true, stopped: false}, // first stock keeps running
@@ -206,8 +253,8 @@ func TestServiceDiscovery_Priority(t *testing.T) {
253
// Two user configs with same name from different files
254
// Same priority + running = keep existing
255
configs: []confFile{
209
- prepareConfigFile("/etc/netdata/sd.d/file1.conf", "myconfig"),
210
- prepareConfigFile("/etc/netdata/sd.d/file2.conf", "myconfig"),
256
+ prepareConfigFile("/etc/netdata/sd.d/dir1/myconfig.conf", "myconfig"),
257
+ prepareConfigFile("/etc/netdata/sd.d/dir2/myconfig.conf", "myconfig"),
258
},
259
wantPipelines: []*mockPipeline{
260
{name: "myconfig", started: true, stopped: false}, // first user keeps running
src/go/plugin/agent/discovery/sd/sim_test.go
+1
-1
@@ -218,7 +218,7 @@ func (m *mockFactory) create(cfg pipeline.Config) (sdPipeline, error) {
218
lock.Lock()
219
defer lock.Unlock()
220
221
- if cfg.Name == "invalid" {
221
+ if cfg.Name == "invalid" || len(cfg.Services) == 0 {
222
return nil, errors.New("mock sdPipelineFactory.create() error")
223
}
224
src/go/plugin/go.d/config/go.d/sd/docker.conf
-2
@@ -1,7 +1,5 @@
1
disabled: no
2
3
-name: 'docker'
4
-
3
discoverer:
4
docker:
5
address: "unix:///var/run/docker.sock"
src/go/plugin/go.d/config/go.d/sd/net_listeners.conf
-3
@@ -1,8 +1,5 @@
1
disabled: no
2
3
-name: 'network listeners'
4
-
5
-
3
discoverer:
4
net_listeners: { }
5
src/go/plugin/go.d/config/go.d/sd/snmp.conf
-2
@@ -6,8 +6,6 @@
6
7
disabled: yes
8
9
-name: 'snmp'
10
-
9
discoverer:
10
snmp:
11
## how often to scan the networks for devices (default: 30m)
src/go/plugin/go.d/discovery/sdext/config_schema_docker.json
-8
@@ -5,12 +5,6 @@
5
"description": "Discovers services running in Docker containers.",
6
"type": "object",
7
"properties": {
8
- "name": {
9
- "title": "Name",
10
- "description": "Pipeline name (must be unique).",
11
- "type": "string",
12
- "minLength": 1
13
- },
8
"discoverer": {
9
"title": "Discoverer",
10
"type": "object",
@@ -71,7 +65,6 @@
65
}
66
},
67
"required": [
74
- "name",
68
"discoverer",
69
"services"
70
]
@@ -86,7 +79,6 @@
79
{
80
"title": "Base",
81
"fields": [
89
- "name",
82
"discoverer"
83
]
84
},
src/go/plugin/go.d/discovery/sdext/config_schema_k8s.json
-8
@@ -5,12 +5,6 @@
5
"description": "Discovers services running in Kubernetes cluster.",
6
"type": "object",
7
"properties": {
8
- "name": {
9
- "title": "Name",
10
- "description": "Pipeline name (must be unique).",
11
- "type": "string",
12
- "minLength": 1
13
- },
8
"discoverer": {
9
"title": "Discoverer",
10
"type": "object",
@@ -113,7 +107,6 @@
107
}
108
},
109
"required": [
116
- "name",
110
"discoverer",
111
"services"
112
]
@@ -128,7 +121,6 @@
121
{
122
"title": "Base",
123
"fields": [
131
- "name",
124
"discoverer"
125
]
126
},
src/go/plugin/go.d/discovery/sdext/config_schema_net_listeners.json
+2
-10
@@ -5,12 +5,6 @@
5
"description": "Discovers services by scanning local listening network ports.",
6
"type": "object",
7
"properties": {
8
- "name": {
9
- "title": "Name",
10
- "description": "Pipeline name (must be unique).",
11
- "type": "string",
12
- "minLength": 1
13
- },
8
"discoverer": {
9
"title": "Discoverer",
10
"type": "object",
@@ -72,7 +66,6 @@
66
}
67
},
68
"required": [
75
- "name",
69
"discoverer",
70
"services"
71
]
@@ -87,7 +80,6 @@
80
{
81
"title": "Base",
82
"fields": [
90
- "name",
83
"discoverer"
84
]
85
},
@@ -121,11 +113,11 @@
113
"match": {
114
"ui:widget": "textarea",
115
"ui:placeholder": "{{ eq .Comm \"nginx\" }}",
124
- "ui:help": "| Field | Description |\n|-------|-------------|\n| `.Protocol` | TCP, TCP6, UDP, UDP6 |\n| `.IPAddress` | IP address |\n| `.Port` | Port number |\n| `.Address` | IP:Port combined |\n| `.Comm` | Process name |\n| `.Cmdline` | Full command line |\n\n**Functions:** eq, ne, glob, regexp, and, or, not"
116
+ "ui:help": "| Field | Description |\n|-------|-------------|\n| `.Protocol` | TCP, TCP6, UDP, UDP6 |\n| `.IPAddress` | IP address |\n| `.Port` | Port number |\n| `.Address` | IP:Port combined |\n| `.Comm` | Process name |\n| `.Cmdline` | Full command line |\n| `.TUID` | Unique target ID (`protocol_port_hash`) |\n\n**Functions:** eq, ne, glob, regexp, and, or, not"
117
},
118
"config_template": {
119
"ui:widget": "textarea",
128
- "ui:placeholder": "module: nginx\nname: {{.Name}}-{{.Address}}\nurl: http://{{.Address}}/stub_status"
120
+ "ui:placeholder": "module: nginx\nname: {{.TUID}}\nurl: http://{{.Address}}/stub_status"
121
}
122
}
123
}
src/go/plugin/go.d/discovery/sdext/config_schema_snmp.json
-8
@@ -5,12 +5,6 @@
5
"description": "Discovers SNMP devices by scanning network subnets.",
6
"type": "object",
7
"properties": {
8
- "name": {
9
- "title": "Name",
10
- "description": "Pipeline name (must be unique).",
11
- "type": "string",
12
- "minLength": 1
13
- },
8
"discoverer": {
9
"title": "Discoverer",
10
"type": "object",
@@ -208,7 +202,6 @@
202
}
203
},
204
"required": [
211
- "name",
205
"discoverer",
206
"services"
207
]
@@ -223,7 +216,6 @@
216
{
217
"title": "Base",
218
"fields": [
226
- "name",
219
"discoverer"
220
]
221
},