Skip to content

Commit

Permalink
Add a "snmp_context" argument to the URL (#1163)
Browse files Browse the repository at this point in the history
Signed-off-by: Paulin Todev <paulin.todev@gmail.com>
  • Loading branch information
ptodev authored May 1, 2024
1 parent 5a4a581 commit 5f907e6
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 6 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ is not necessary within the Prometheus configuration file.
Metrics concerning the operation of the exporter itself are available at the
endpoint <http://localhost:9116/metrics>.

It is possible to supply an optional `snmp_context` parameter in the URL, like this:
<http://localhost:9116/snmp?auth=my_secure_v3&module=ddwrt&target=192.0.0.8&snmp_context=vrf-mgmt>
The `snmp_context` parameter in the URL would override the `context_name` parameter in the `snmp.yml` file.

## Multi-Module Handling
The multi-module functionality allows you to specify multiple modules, enabling the retrieval of information from several modules in a single scrape.
The concurrency can be specified using the snmp-exporter option `--snmp.module-concurrency` (the default is 1).
Expand Down
7 changes: 4 additions & 3 deletions collector/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,10 +299,11 @@ type Collector struct {
logger log.Logger
metrics Metrics
concurrency int
snmpContext string
}

func New(ctx context.Context, target, authName string, auth *config.Auth, modules []*NamedModule, logger log.Logger, metrics Metrics, conc int) *Collector {
return &Collector{ctx: ctx, target: target, authName: authName, auth: auth, modules: modules, logger: logger, metrics: metrics, concurrency: conc}
func New(ctx context.Context, target, authName, snmpContext string, auth *config.Auth, modules []*NamedModule, logger log.Logger, metrics Metrics, conc int) *Collector {
return &Collector{ctx: ctx, target: target, authName: authName, auth: auth, modules: modules, logger: logger, metrics: metrics, concurrency: conc, snmpContext: snmpContext}
}

// Describe implements Prometheus.Collector.
Expand Down Expand Up @@ -429,7 +430,7 @@ func (c Collector) Collect(ch chan<- prometheus.Metric) {
// Set the options.
client.SetOptions(func(g *gosnmp.GoSNMP) {
g.Context = ctx
c.auth.ConfigureSNMP(g)
c.auth.ConfigureSNMP(g, c.snmpContext)
})
if err = client.Connect(); err != nil {
level.Info(logger).Log("msg", "Error connecting to target", "err", err)
Expand Down
9 changes: 7 additions & 2 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ func (c *Module) UnmarshalYAML(unmarshal func(interface{}) error) error {
}

// ConfigureSNMP sets the various version and auth settings.
func (c Auth) ConfigureSNMP(g *gosnmp.GoSNMP) {
func (c Auth) ConfigureSNMP(g *gosnmp.GoSNMP, snmpContext string) {
switch c.Version {
case 1:
g.Version = gosnmp.Version1
Expand All @@ -139,7 +139,12 @@ func (c Auth) ConfigureSNMP(g *gosnmp.GoSNMP) {
g.Version = gosnmp.Version3
}
g.Community = string(c.Community)
g.ContextName = c.ContextName

if snmpContext == "" {
g.ContextName = c.ContextName
} else {
g.ContextName = snmpContext
}

// v3 security settings.
g.SecurityModel = gosnmp.UserSecurityModel
Expand Down
9 changes: 8 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ func handler(w http.ResponseWriter, r *http.Request, logger log.Logger, exporter
authName = "public_v2"
}

snmpContext := query.Get("snmp_context")
if len(query["snmp_context"]) > 1 {
http.Error(w, "'snmp_context' parameter must only be specified once", http.StatusBadRequest)
snmpRequestErrors.Inc()
return
}

queryModule := query["module"]
if len(queryModule) == 0 {
queryModule = append(queryModule, "if_mib")
Expand Down Expand Up @@ -141,7 +148,7 @@ func handler(w http.ResponseWriter, r *http.Request, logger log.Logger, exporter
sc.RUnlock()
logger = log.With(logger, "auth", authName, "target", target)
registry := prometheus.NewRegistry()
c := collector.New(r.Context(), target, authName, auth, nmodules, logger, exporterMetrics, *concurrency)
c := collector.New(r.Context(), target, authName, snmpContext, auth, nmodules, logger, exporterMetrics, *concurrency)
registry.MustRegister(c)
// Delegate http serving to Prometheus client library, which will call collector.Collect.
h := promhttp.HandlerFor(registry, promhttp.HandlerOpts{})
Expand Down

0 comments on commit 5f907e6

Please sign in to comment.