@cryptotaxi247 / netdata-1 / commits / 3c2ad5b05

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