From 315599bae27198c7e69810393f279003a83c5548 Mon Sep 17 00:00:00 2001 From: Paulin Todev Date: Fri, 24 May 2024 14:12:11 +0100 Subject: [PATCH] Add a snmp_context argument (#6923) --- CHANGELOG.md | 3 +++ .../components/prometheus.exporter.snmp.md | 13 +++++----- .../integrations-next/snmp-config.md | 3 +++ .../configuration/integrations/snmp-config.md | 5 +++- .../prometheus/exporter/snmp/snmp.go | 25 +++++++++++-------- .../prometheus/exporter/snmp/snmp_test.go | 12 ++++++--- .../internal/build/snmp_exporter.go | 22 ++++++++-------- .../snmp_exporter/snmp_exporter.go | 14 +++++++---- static/integrations/v2/snmp_exporter/snmp.go | 6 +++++ 9 files changed, 67 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ea545a3531d..0480ade1dac4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,9 @@ Main (unreleased) - A new `loki.rules.kubernetes` component that discovers `PrometheusRule` Kubernetes resources and loads them into a Loki Ruler instance. (@EStork09) +- A new `snmp_context` configuration argument for `prometheus.exporter.snmp` and the `snmp` Static mode integration. + It overrides the `context_name` parameter in the SNMP configuration file. (@ptodev) + ### Bugfixes - Fix panic for `prometheus.exporter.snmp` and snmp_exporter integration diff --git a/docs/sources/flow/reference/components/prometheus.exporter.snmp.md b/docs/sources/flow/reference/components/prometheus.exporter.snmp.md index cdf39557380b..033bfbd26139 100644 --- a/docs/sources/flow/reference/components/prometheus.exporter.snmp.md +++ b/docs/sources/flow/reference/components/prometheus.exporter.snmp.md @@ -68,12 +68,13 @@ The following blocks are supported inside the definition of The `target` block defines an individual SNMP target. The `target` block may be specified multiple times to define multiple targets. The label of the block is required and will be used in the target's `job` label. -| Name | Type | Description | Default | Required | -| ------------- | -------- | ----------------------------------- | ------- | -------- | -| `address` | `string` | The address of SNMP device. | | yes | -| `module` | `string` | SNMP module to use for polling. | `""` | no | -| `auth` | `string` | SNMP authentication profile to use. | `""` | no | -| `walk_params` | `string` | Config to use for this target. | `""` | no | +| Name | Type | Description | Default | Required | +| -------------- | -------- | --------------------------------------------------------------------- | ------- | -------- | +| `address` | `string` | The address of SNMP device. | | yes | +| `module` | `string` | SNMP module to use for polling. | `""` | no | +| `auth` | `string` | SNMP authentication profile to use. | `""` | no | +| `walk_params` | `string` | Config to use for this target. | `""` | no | +| `snmp_context` | `string` | Override the `context_name` parameter in the SNMP configuration file. | `""` | no | ### walk_param block diff --git a/docs/sources/static/configuration/integrations/integrations-next/snmp-config.md b/docs/sources/static/configuration/integrations/integrations-next/snmp-config.md index c49f37e72c9c..0adf62f2b663 100644 --- a/docs/sources/static/configuration/integrations/integrations-next/snmp-config.md +++ b/docs/sources/static/configuration/integrations/integrations-next/snmp-config.md @@ -152,6 +152,9 @@ Full reference of options: # walk_param config to use for this snmp_target [walk_params: | default = ""] + + # snmp_context overrides the `context_name` parameter in the SNMP configuration file. + [snmp_context: | default = ""] ``` ## walk_param config diff --git a/docs/sources/static/configuration/integrations/snmp-config.md b/docs/sources/static/configuration/integrations/snmp-config.md index d4b519782f8b..b52beafe9ea8 100644 --- a/docs/sources/static/configuration/integrations/snmp-config.md +++ b/docs/sources/static/configuration/integrations/snmp-config.md @@ -15,7 +15,7 @@ which is an embedded version of [`snmp_exporter`](https://github.com/prometheus/snmp_exporter). This allows collection of SNMP metrics from the network devices with ease. {{< admonition type="note" >}} -`snmp config` uses the latest configuration introduced in version 0.23 of the Prometheus `snmp_exporter`. +`snmp config` uses the latest configuration introduced in version 0.26 of the Prometheus `snmp_exporter`. {{< /admonition >}} ## Quick configuration example @@ -167,6 +167,9 @@ Full reference of options: # walk_param config to use for this snmp_target [walk_params: | default = ""] + + # snmp_context overrides the `context_name` parameter in the SNMP configuration file. + [snmp_context: | default = ""] ``` ## walk_param config diff --git a/internal/component/prometheus/exporter/snmp/snmp.go b/internal/component/prometheus/exporter/snmp/snmp.go index aa855e8bd662..d2991c292064 100644 --- a/internal/component/prometheus/exporter/snmp/snmp.go +++ b/internal/component/prometheus/exporter/snmp/snmp.go @@ -51,6 +51,9 @@ func buildSNMPTargets(baseTarget discovery.Target, args component.Arguments) []d if tgt.WalkParams != "" { target["__param_walk_params"] = tgt.WalkParams } + if tgt.SNMPContext != "" { + target["__param_snmp_context"] = tgt.SNMPContext + } if tgt.Auth != "" { target["__param_auth"] = tgt.Auth } @@ -63,11 +66,12 @@ func buildSNMPTargets(baseTarget discovery.Target, args component.Arguments) []d // SNMPTarget defines a target to be used by the exporter. type SNMPTarget struct { - Name string `river:",label"` - Target string `river:"address,attr"` - Module string `river:"module,attr,optional"` - Auth string `river:"auth,attr,optional"` - WalkParams string `river:"walk_params,attr,optional"` + Name string `river:",label"` + Target string `river:"address,attr"` + Module string `river:"module,attr,optional"` + Auth string `river:"auth,attr,optional"` + WalkParams string `river:"walk_params,attr,optional"` + SNMPContext string `river:"snmp_context,attr,optional"` } type TargetBlock []SNMPTarget @@ -77,11 +81,12 @@ func (t TargetBlock) Convert() []snmp_exporter.SNMPTarget { targets := make([]snmp_exporter.SNMPTarget, 0, len(t)) for _, target := range t { targets = append(targets, snmp_exporter.SNMPTarget{ - Name: target.Name, - Target: target.Target, - Module: target.Module, - Auth: target.Auth, - WalkParams: target.WalkParams, + Name: target.Name, + Target: target.Target, + Module: target.Module, + Auth: target.Auth, + WalkParams: target.WalkParams, + SNMPContext: target.SNMPContext, }) } return targets diff --git a/internal/component/prometheus/exporter/snmp/snmp_test.go b/internal/component/prometheus/exporter/snmp/snmp_test.go index 6d5a0e97d7d2..3e2d3dddd239 100644 --- a/internal/component/prometheus/exporter/snmp/snmp_test.go +++ b/internal/component/prometheus/exporter/snmp/snmp_test.go @@ -21,6 +21,7 @@ func TestUnmarshalRiver(t *testing.T) { module = "if_mib" walk_params = "public" auth = "public_v2" + snmp_context = "testcontext" } target "network_router_2" { address = "192.168.1.3" @@ -45,6 +46,7 @@ func TestUnmarshalRiver(t *testing.T) { require.Contains(t, "if_mib", args.Targets[0].Module) require.Contains(t, "public", args.Targets[0].WalkParams) require.Contains(t, "public_v2", args.Targets[0].Auth) + require.Contains(t, "testcontext", args.Targets[0].SNMPContext) require.Contains(t, "network_router_2", args.Targets[1].Name) require.Contains(t, "192.168.1.3", args.Targets[1].Target) @@ -88,10 +90,11 @@ func TestConvertConfigWithInlineConfig(t *testing.T) { func TestConvertTargets(t *testing.T) { targets := TargetBlock{{ - Name: "network_switch_1", - Target: "192.168.1.2", - Module: "if_mib", - Auth: "public_v2", + Name: "network_switch_1", + Target: "192.168.1.2", + Module: "if_mib", + Auth: "public_v2", + SNMPContext: "testcontext", }} res := targets.Convert() @@ -100,6 +103,7 @@ func TestConvertTargets(t *testing.T) { require.Equal(t, "192.168.1.2", res[0].Target) require.Equal(t, "if_mib", res[0].Module) require.Equal(t, "public_v2", res[0].Auth) + require.Equal(t, "testcontext", res[0].SNMPContext) } func TestConvertWalkParams(t *testing.T) { diff --git a/internal/converter/internal/staticconvert/internal/build/snmp_exporter.go b/internal/converter/internal/staticconvert/internal/build/snmp_exporter.go index cd6a8f9f9237..69d26b267eed 100644 --- a/internal/converter/internal/staticconvert/internal/build/snmp_exporter.go +++ b/internal/converter/internal/staticconvert/internal/build/snmp_exporter.go @@ -19,11 +19,12 @@ func toSnmpExporter(config *snmp_exporter.Config) *snmp.Arguments { targets := make([]snmp.SNMPTarget, len(config.SnmpTargets)) for i, t := range config.SnmpTargets { targets[i] = snmp.SNMPTarget{ - Name: common.SanitizeIdentifierPanics(t.Name), - Target: t.Target, - Module: t.Module, - Auth: t.Auth, - WalkParams: t.WalkParams, + Name: common.SanitizeIdentifierPanics(t.Name), + Target: t.Target, + Module: t.Module, + Auth: t.Auth, + WalkParams: t.WalkParams, + SNMPContext: t.SNMPContext, } } @@ -67,11 +68,12 @@ func toSnmpExporterV2(config *snmp_exporter_v2.Config) *snmp.Arguments { targets := make([]snmp.SNMPTarget, len(config.SnmpTargets)) for i, t := range config.SnmpTargets { targets[i] = snmp.SNMPTarget{ - Name: common.SanitizeIdentifierPanics(t.Name), - Target: t.Target, - Module: t.Module, - Auth: t.Auth, - WalkParams: t.WalkParams, + Name: common.SanitizeIdentifierPanics(t.Name), + Target: t.Target, + Module: t.Module, + Auth: t.Auth, + WalkParams: t.WalkParams, + SNMPContext: t.SNMPContext, } } diff --git a/static/integrations/snmp_exporter/snmp_exporter.go b/static/integrations/snmp_exporter/snmp_exporter.go index 47754801e02a..2d0f3aa82f09 100644 --- a/static/integrations/snmp_exporter/snmp_exporter.go +++ b/static/integrations/snmp_exporter/snmp_exporter.go @@ -27,11 +27,12 @@ var DefaultConfig = Config{ // SNMPTarget defines a target device to be used by the integration. type SNMPTarget struct { - Name string `yaml:"name"` - Target string `yaml:"address"` - Module string `yaml:"module"` - Auth string `yaml:"auth"` - WalkParams string `yaml:"walk_params,omitempty"` + Name string `yaml:"name"` + Target string `yaml:"address"` + Module string `yaml:"module"` + Auth string `yaml:"auth"` + WalkParams string `yaml:"walk_params,omitempty"` + SNMPContext string `yaml:"snmp_context,omitempty"` } // Config configures the SNMP integration. @@ -199,6 +200,9 @@ func (i *Integration) ScrapeConfigs() []config.ScrapeConfig { if target.WalkParams != "" { queryParams.Add("walk_params", target.WalkParams) } + if target.SNMPContext != "" { + queryParams.Add("snmp_context", target.SNMPContext) + } res = append(res, config.ScrapeConfig{ JobName: i.sh.cfg.Name() + "/" + target.Name, MetricsPath: "/metrics", diff --git a/static/integrations/v2/snmp_exporter/snmp.go b/static/integrations/v2/snmp_exporter/snmp.go index 071c0de4c7e9..4283e9525c56 100644 --- a/static/integrations/v2/snmp_exporter/snmp.go +++ b/static/integrations/v2/snmp_exporter/snmp.go @@ -68,6 +68,12 @@ func (sh *snmpHandler) Targets(ep integrations.Endpoint) []*targetgroup.Group { }) } + if t.SNMPContext != "" { + labelSet = labelSet.Merge(model.LabelSet{ + "__param_snmp_context": model.LabelValue(t.SNMPContext), + }) + } + if t.Auth != "" { labelSet = labelSet.Merge(model.LabelSet{ "__param_auth": model.LabelValue(t.Auth),