mirror of
https://github.com/ClusterCockpit/cc-metric-collector.git
synced 2024-12-25 23:19:06 +01:00
Add SNMP test tool
This commit is contained in:
parent
668da6ab1b
commit
c396a1254f
@ -24,6 +24,7 @@ This allows to specify
|
|||||||
- [`http`](./httpReceiver.md): Listen for HTTP Post requests transporting metrics in InfluxDB line protocol
|
- [`http`](./httpReceiver.md): Listen for HTTP Post requests transporting metrics in InfluxDB line protocol
|
||||||
- [`ipmi`](./ipmiReceiver.md): Read IPMI sensor readings
|
- [`ipmi`](./ipmiReceiver.md): Read IPMI sensor readings
|
||||||
- [`redfish`](redfishReceiver.md) Use the Redfish (specification) to query thermal and power metrics
|
- [`redfish`](redfishReceiver.md) Use the Redfish (specification) to query thermal and power metrics
|
||||||
|
- [`snmp`](./snmpReceiver.md) Query SNMP endpoints in the network
|
||||||
|
|
||||||
## Contributing own receivers
|
## Contributing own receivers
|
||||||
|
|
||||||
|
@ -54,3 +54,7 @@ Each network-attached device that should be queried. A target consits of
|
|||||||
- `unit` can be empty, an OID or a user-given string
|
- `unit` can be empty, an OID or a user-given string
|
||||||
|
|
||||||
If a OID is used for `name` or `unit`, the receiver will use the returned values to create the output metric. If there are any issues with the returned values, it uses the `OID`.
|
If a OID is used for `name` or `unit`, the receiver will use the returned values to create the output metric. If there are any issues with the returned values, it uses the `OID`.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
For testing an SNMP endpoint and OIDs, you can use [`scripts/snmpReceiverTest`](../scripts/snmpReceiverTest)
|
37
scripts/snmpReceiverTest/README.md
Normal file
37
scripts/snmpReceiverTest/README.md
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# snmpReceiverTest
|
||||||
|
|
||||||
|
This script is a basic implementation of how the SNMPReceiver to test the connection before configuring
|
||||||
|
the collector to get the data periodically.
|
||||||
|
|
||||||
|
It does not support the specification of the `type`, `type-id`, `stype` and `stype-id` but since they are
|
||||||
|
not required to test the functionality, they are left out.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ go run snmpReceiverTest -h
|
||||||
|
Usage of snmpReceiverTest:
|
||||||
|
-community string
|
||||||
|
SNMP community (default "public")
|
||||||
|
-hostname string
|
||||||
|
Hostname (default "127.0.0.1")
|
||||||
|
-name string
|
||||||
|
Name of metric or OID
|
||||||
|
-port string
|
||||||
|
Port number (default "161")
|
||||||
|
-timeout string
|
||||||
|
Timeout for SNMP request (default "1s")
|
||||||
|
-unit string
|
||||||
|
Unit of metric or OID
|
||||||
|
-value string
|
||||||
|
Value OID
|
||||||
|
-version string
|
||||||
|
SNMP version (default "2c")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ go run scripts/snmpReceiverTest/snmpReceiverTest.go -name serialNumber -value .1.3.6.1.4.1.6574.1.5.2.0 -hostname $IP -community $COMMUNITY
|
||||||
|
Name: serialNumber, Tags: map[type:node], Meta: map[], fields: map[value:18B0PCNXXXXX], Timestamp: 1702050709599311288
|
||||||
|
```
|
167
scripts/snmpReceiverTest/snmpReceiverTest.go
Normal file
167
scripts/snmpReceiverTest/snmpReceiverTest.go
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
lp "github.com/ClusterCockpit/cc-metric-collector/pkg/ccMetric"
|
||||||
|
"github.com/gosnmp/gosnmp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ReadCLI() map[string]string {
|
||||||
|
args := map[string]string{
|
||||||
|
"port": "161",
|
||||||
|
"community": "public",
|
||||||
|
"version": "2c",
|
||||||
|
"hostname": "127.0.0.1",
|
||||||
|
"timeout": "1s",
|
||||||
|
}
|
||||||
|
|
||||||
|
host_cfg := flag.String("hostname", "127.0.0.1", "Hostname")
|
||||||
|
port_cfg := flag.String("port", "161", "Port number")
|
||||||
|
comm_cfg := flag.String("community", "public", "SNMP community")
|
||||||
|
vers_cfg := flag.String("version", "2c", "SNMP version")
|
||||||
|
time_cfg := flag.String("timeout", "1s", "Timeout for SNMP request")
|
||||||
|
|
||||||
|
name_cfg := flag.String("name", "", "Name of metric or OID")
|
||||||
|
value_cfg := flag.String("value", "", "Value OID")
|
||||||
|
unit_cfg := flag.String("unit", "", "Unit of metric or OID")
|
||||||
|
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
args["port"] = *port_cfg
|
||||||
|
args["community"] = *comm_cfg
|
||||||
|
args["hostname"] = *host_cfg
|
||||||
|
args["version"] = *vers_cfg
|
||||||
|
args["timeout"] = *time_cfg
|
||||||
|
|
||||||
|
args["name"] = *name_cfg
|
||||||
|
args["value"] = *value_cfg
|
||||||
|
args["unit"] = *unit_cfg
|
||||||
|
|
||||||
|
if len(args["name"]) == 0 || len(args["value"]) == 0 {
|
||||||
|
fmt.Printf("Required arguments: --name and --value\n")
|
||||||
|
flag.Usage()
|
||||||
|
}
|
||||||
|
|
||||||
|
return args
|
||||||
|
}
|
||||||
|
|
||||||
|
func validOid(oid string) bool {
|
||||||
|
// Regex from https://github.com/BornToBeRoot/NETworkManager/blob/6805740762bf19b95051c7eaa73cf2b4727733c3/Source/NETworkManager.Utilities/RegexHelper.cs#L88
|
||||||
|
// Match on leading dot added by Thomas Gruber <thomas.gruber@fau.de>
|
||||||
|
match, err := regexp.MatchString(`^[\.]?[012]\.(?:[0-9]|[1-3][0-9])(\.\d+)*$`, oid)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return match
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
args := ReadCLI()
|
||||||
|
|
||||||
|
if len(args["name"]) == 0 || len(args["value"]) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
version := gosnmp.Version2c
|
||||||
|
if len(args["version"]) > 0 {
|
||||||
|
switch args["version"] {
|
||||||
|
case "1":
|
||||||
|
version = gosnmp.Version1
|
||||||
|
case "2c":
|
||||||
|
version = gosnmp.Version2c
|
||||||
|
case "3":
|
||||||
|
version = gosnmp.Version3
|
||||||
|
default:
|
||||||
|
fmt.Printf("Invalid SNMP version '%s'\n", args["version"])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v, err := strconv.ParseInt(args["port"], 10, 16)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Failed to parse port number '%s'\n", args["port"])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
port := uint16(v)
|
||||||
|
|
||||||
|
t, err := time.ParseDuration(args["timeout"])
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Failed to parse timeout '%s'\n", args["timeout"])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
timeout := t
|
||||||
|
|
||||||
|
params := &gosnmp.GoSNMP{
|
||||||
|
Target: args["hostname"],
|
||||||
|
Port: port,
|
||||||
|
Community: args["community"],
|
||||||
|
Version: version,
|
||||||
|
Timeout: timeout,
|
||||||
|
}
|
||||||
|
err = params.Connect()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Failed to connect to %s:%d : %v\n", params.Target, params.Port, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
oids := make([]string, 0)
|
||||||
|
idx := 0
|
||||||
|
name := gosnmp.SnmpPDU{
|
||||||
|
Value: args["name"],
|
||||||
|
Name: args["name"],
|
||||||
|
}
|
||||||
|
nameidx := -1
|
||||||
|
value := gosnmp.SnmpPDU{
|
||||||
|
Value: nil,
|
||||||
|
Name: args["value"],
|
||||||
|
}
|
||||||
|
valueidx := -1
|
||||||
|
unit := gosnmp.SnmpPDU{
|
||||||
|
Value: args["unit"],
|
||||||
|
Name: args["unit"],
|
||||||
|
}
|
||||||
|
unitidx := -1
|
||||||
|
if validOid(args["name"]) {
|
||||||
|
oids = append(oids, args["name"])
|
||||||
|
nameidx = idx
|
||||||
|
idx++
|
||||||
|
}
|
||||||
|
if validOid(args["value"]) {
|
||||||
|
oids = append(oids, args["value"])
|
||||||
|
valueidx = idx
|
||||||
|
idx++
|
||||||
|
}
|
||||||
|
if len(args["unit"]) > 0 && validOid(args["unit"]) {
|
||||||
|
oids = append(oids, args["unit"])
|
||||||
|
unitidx = idx
|
||||||
|
}
|
||||||
|
result, err := params.Get(oids)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Failed to get data for OIDs [%s] : %v\n", strings.Join(oids, ", "), err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if nameidx >= 0 && len(result.Variables) > nameidx {
|
||||||
|
name = result.Variables[nameidx]
|
||||||
|
}
|
||||||
|
if valueidx >= 0 && len(result.Variables) > valueidx {
|
||||||
|
value = result.Variables[valueidx]
|
||||||
|
}
|
||||||
|
if unitidx >= 0 && len(result.Variables) > unitidx {
|
||||||
|
unit = result.Variables[unitidx]
|
||||||
|
}
|
||||||
|
if value.Value != nil {
|
||||||
|
y, err := lp.New(name.Value.(string), map[string]string{"type": "node"}, map[string]string{}, map[string]interface{}{"value": value.Value}, time.Now())
|
||||||
|
if err == nil {
|
||||||
|
if len(unit.Name) > 0 && unit.Value != nil {
|
||||||
|
y.AddMeta("unit", unit.Value.(string))
|
||||||
|
}
|
||||||
|
fmt.Println(y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user