fix: collapsed fields by calling more indepth function (#10430)
This commit is contained in:
parent
bfac209fe3
commit
84c1efbef1
|
|
@ -0,0 +1,22 @@
|
||||||
|
TGTEST-MIB DEFINITIONS ::= BEGIN
|
||||||
|
|
||||||
|
org OBJECT IDENTIFIER ::= { iso 3 } -- "iso" = 1
|
||||||
|
dod OBJECT IDENTIFIER ::= { org 6 }
|
||||||
|
internet OBJECT IDENTIFIER ::= { dod 1 }
|
||||||
|
mgmt OBJECT IDENTIFIER ::= { internet 2 }
|
||||||
|
mibs OBJECT IDENTIFIER ::= { mgmt 1 }
|
||||||
|
system OBJECT IDENTIFIER ::= { mibs 1 }
|
||||||
|
systemUpTime OBJECT IDENTIFIER ::= { system 3 }
|
||||||
|
sysUpTimeInstance OBJECT IDENTIFIER ::= { systemUpTime 0 }
|
||||||
|
|
||||||
|
private OBJECT IDENTIFIER ::= { internet 4 }
|
||||||
|
enterprises OBJECT IDENTIFIER ::= { private 1 }
|
||||||
|
|
||||||
|
snmpV2 OBJECT IDENTIFIER ::= { internet 6 }
|
||||||
|
snmpModules OBJECT IDENTIFIER ::= { snmpV2 3 }
|
||||||
|
snmpMIB OBJECT IDENTIFIER ::= { snmpModules 1 }
|
||||||
|
snmpMIBObjects OBJECT IDENTIFIER ::= { snmpMIB 1 }
|
||||||
|
snmpTraps OBJECT IDENTIFIER ::= { snmpMIBObjects 5 }
|
||||||
|
coldStart OBJECT IDENTIFIER ::= { snmpTraps 1 }
|
||||||
|
|
||||||
|
END
|
||||||
|
|
@ -111,22 +111,29 @@ type MibEntry struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TrapLookup(oid string) (e MibEntry, err error) {
|
func TrapLookup(oid string) (e MibEntry, err error) {
|
||||||
var node gosmi.SmiNode
|
var givenOid types.Oid
|
||||||
node, err = gosmi.GetNodeByOID(types.OidMustFromString(oid))
|
if givenOid, err = types.OidFromString(oid); err != nil {
|
||||||
|
return e, fmt.Errorf("could not convert OID %s: %w", oid, err)
|
||||||
|
}
|
||||||
|
|
||||||
// ensure modules are loaded or node will be empty (might not error)
|
// Get node name
|
||||||
if err != nil {
|
var node gosmi.SmiNode
|
||||||
|
if node, err = gosmi.GetNodeByOID(givenOid); err != nil {
|
||||||
return e, err
|
return e, err
|
||||||
}
|
}
|
||||||
|
e.OidText = node.Name
|
||||||
|
|
||||||
e.OidText = node.RenderQualified()
|
// Add not found OID part
|
||||||
|
if !givenOid.Equals(node.Oid) {
|
||||||
i := strings.Index(e.OidText, "::")
|
e.OidText += "." + givenOid[len(node.Oid):].String()
|
||||||
if i == -1 {
|
|
||||||
return e, fmt.Errorf("not found")
|
|
||||||
}
|
}
|
||||||
e.MibName = e.OidText[:i]
|
|
||||||
e.OidText = e.OidText[i+2:]
|
// Get module name
|
||||||
|
module := node.GetModule()
|
||||||
|
if module.Name != "<well-known>" {
|
||||||
|
e.MibName = module.Name
|
||||||
|
}
|
||||||
|
|
||||||
return e, nil
|
return e, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
package snmp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/influxdata/telegraf/testutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTrapLookup(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
oid string
|
||||||
|
expected MibEntry
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Known trap OID",
|
||||||
|
oid: ".1.3.6.1.6.3.1.1.5.1",
|
||||||
|
expected: MibEntry{
|
||||||
|
MibName: "TGTEST-MIB",
|
||||||
|
OidText: "coldStart",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Known trap value OID",
|
||||||
|
oid: ".1.3.6.1.2.1.1.3.0",
|
||||||
|
expected: MibEntry{
|
||||||
|
MibName: "TGTEST-MIB",
|
||||||
|
OidText: "sysUpTimeInstance",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Unknown enterprise sub-OID",
|
||||||
|
oid: ".1.3.6.1.4.1.0.1.2.3",
|
||||||
|
expected: MibEntry{
|
||||||
|
MibName: "TGTEST-MIB",
|
||||||
|
OidText: "enterprises.0.1.2.3",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Unknown MIB",
|
||||||
|
oid: ".1.2.3",
|
||||||
|
expected: MibEntry{OidText: "iso.2.3"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the MIBs
|
||||||
|
require.NoError(t, LoadMibsFromPath([]string{"testdata/mibs"}, testutil.Logger{}))
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
// Run the actual test
|
||||||
|
actual, err := TrapLookup(tt.oid)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, tt.expected, actual)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTrapLookupFail(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
oid string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "New top level OID",
|
||||||
|
oid: ".3.6.1.3.0",
|
||||||
|
expected: "Could not find node for OID 3.6.1.3.0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Malformed OID",
|
||||||
|
oid: ".1.3.dod.1.3.0",
|
||||||
|
expected: "could not convert OID .1.3.dod.1.3.0: strconv.ParseUint: parsing \"dod\": invalid syntax",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the MIBs
|
||||||
|
require.NoError(t, LoadMibsFromPath([]string{"testdata/mibs"}, testutil.Logger{}))
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
// Run the actual test
|
||||||
|
_, err := TrapLookup(tt.oid)
|
||||||
|
require.EqualError(t, err, tt.expected)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,6 @@ package snmp_trap
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"path/filepath"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
@ -1312,96 +1311,3 @@ func TestReceiveTrap(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGosmiSingleMib(t *testing.T) {
|
|
||||||
// We would prefer to specify port 0 and let the network
|
|
||||||
// stack choose an unused port for us but TrapListener
|
|
||||||
// doesn't have a way to return the autoselected port.
|
|
||||||
// Instead, we'll use an unusual port and hope it's
|
|
||||||
// unused.
|
|
||||||
const port = 12399
|
|
||||||
|
|
||||||
// Hook into the trap handler so the test knows when the
|
|
||||||
// trap has been received
|
|
||||||
received := make(chan int)
|
|
||||||
wrap := func(f gosnmp.TrapHandlerFunc) gosnmp.TrapHandlerFunc {
|
|
||||||
return func(p *gosnmp.SnmpPacket, a *net.UDPAddr) {
|
|
||||||
f(p, a)
|
|
||||||
received <- 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fakeTime := time.Unix(456456456, 456)
|
|
||||||
now := uint32(123123123)
|
|
||||||
|
|
||||||
testDataPath, err := filepath.Abs("./testdata")
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
trap := gosnmp.SnmpTrap{
|
|
||||||
Variables: []gosnmp.SnmpPDU{
|
|
||||||
{
|
|
||||||
Name: ".1.3.6.1.2.1.1.3.0",
|
|
||||||
Type: gosnmp.TimeTicks,
|
|
||||||
Value: now,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: ".1.3.6.1.6.3.1.1.4.1.0", // SNMPv2-MIB::snmpTrapOID.0
|
|
||||||
Type: gosnmp.ObjectIdentifier,
|
|
||||||
Value: ".1.3.6.1.6.3.1.1.5.1", // coldStart
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
metrics := []telegraf.Metric{
|
|
||||||
testutil.MustMetric(
|
|
||||||
"snmp_trap", // name
|
|
||||||
map[string]string{ // tags
|
|
||||||
"oid": ".1.3.6.1.6.3.1.1.5.1",
|
|
||||||
"name": "coldStart",
|
|
||||||
"mib": "SNMPv2-MIB",
|
|
||||||
"version": "2c",
|
|
||||||
"source": "127.0.0.1",
|
|
||||||
"community": "public",
|
|
||||||
},
|
|
||||||
map[string]interface{}{ // fields
|
|
||||||
"sysUpTimeInstance": now,
|
|
||||||
},
|
|
||||||
fakeTime,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up the service input plugin
|
|
||||||
s := &SnmpTrap{
|
|
||||||
ServiceAddress: "udp://:" + strconv.Itoa(port),
|
|
||||||
makeHandlerWrapper: wrap,
|
|
||||||
timeFunc: func() time.Time {
|
|
||||||
return fakeTime
|
|
||||||
},
|
|
||||||
lookupFunc: snmp.TrapLookup,
|
|
||||||
Log: testutil.Logger{},
|
|
||||||
Version: "2c",
|
|
||||||
Path: []string{testDataPath},
|
|
||||||
}
|
|
||||||
require.NoError(t, s.Init())
|
|
||||||
|
|
||||||
var acc testutil.Accumulator
|
|
||||||
require.Nil(t, s.Start(&acc))
|
|
||||||
defer s.Stop()
|
|
||||||
|
|
||||||
goSNMP := newGoSNMP(gosnmp.Version2c, port)
|
|
||||||
|
|
||||||
// Send the trap
|
|
||||||
sendTrap(t, goSNMP, trap)
|
|
||||||
|
|
||||||
// Wait for trap to be received
|
|
||||||
select {
|
|
||||||
case <-received:
|
|
||||||
case <-time.After(2 * time.Second):
|
|
||||||
t.Fatal("timed out waiting for trap to be received")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify plugin output
|
|
||||||
testutil.RequireMetricsEqual(t,
|
|
||||||
metrics, acc.GetTelegrafMetrics(),
|
|
||||||
testutil.SortMetrics())
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
SNMPv2-MIB DEFINITIONS ::= BEGIN
|
|
||||||
|
|
||||||
IMPORTS
|
|
||||||
NOTIFICATION-TYPE, NOTIFICATION-GROUP
|
|
||||||
FROM test2;
|
|
||||||
|
|
||||||
|
|
||||||
snmpMIB MODULE-IDENTITY
|
|
||||||
LAST-UPDATED "2021060900Z"
|
|
||||||
ORGANIZATION "testing"
|
|
||||||
CONTACT-INFO
|
|
||||||
"EMail: testing@emai.com"
|
|
||||||
DESCRIPTION
|
|
||||||
"MIB module for testing snmp_trap plugin
|
|
||||||
for telegraf
|
|
||||||
"
|
|
||||||
::={ coldStart 1 }
|
|
||||||
|
|
||||||
snmpMIBObjects OBJECT IDENTIFIER ::= { snmpMIB 1 }
|
|
||||||
|
|
||||||
system OBJECT IDENTIFIER ::= { sysUpTimeInstance 1 }
|
|
||||||
|
|
||||||
coldStart NOTIFICATION-TYPE
|
|
||||||
STATUS current
|
|
||||||
DESCRIPTION
|
|
||||||
"A coldStart trap signifies that the SNMP entity,
|
|
||||||
supporting a notification originator application, is
|
|
||||||
reinitializing itself and that its configuration may
|
|
||||||
have been altered."
|
|
||||||
::= { snmpTraps 1 }
|
|
||||||
|
|
||||||
snmpBasicNotificationsGroup NOTIFICATION-GROUP
|
|
||||||
NOTIFICATIONS { coldStart, authenticationFailure }
|
|
||||||
STATUS current
|
|
||||||
DESCRIPTION
|
|
||||||
"The basic notifications implemented by an SNMP entity
|
|
||||||
supporting command responder applications."
|
|
||||||
::= { snmpMIBGroups 7 }
|
|
||||||
|
|
||||||
END
|
|
||||||
|
|
@ -1,97 +0,0 @@
|
||||||
SNMPv2-MIB DEFINITIONS ::= BEGIN
|
|
||||||
|
|
||||||
org OBJECT IDENTIFIER ::= { iso 3 } -- "iso" = 1
|
|
||||||
dod OBJECT IDENTIFIER ::= { org 6 }
|
|
||||||
internet OBJECT IDENTIFIER ::= { dod 1 }
|
|
||||||
|
|
||||||
directory OBJECT IDENTIFIER ::= { internet 1 }
|
|
||||||
|
|
||||||
mgmt OBJECT IDENTIFIER ::= { internet 2 }
|
|
||||||
sysUpTimeInstance OBJECT IDENTIFIER ::= { mgmt 1 }
|
|
||||||
transmission OBJECT IDENTIFIER ::= { sysUpTimeInstance 10 }
|
|
||||||
|
|
||||||
experimental OBJECT IDENTIFIER ::= { internet 3 }
|
|
||||||
|
|
||||||
private OBJECT IDENTIFIER ::= { internet 4 }
|
|
||||||
enterprises OBJECT IDENTIFIER ::= { private 1 }
|
|
||||||
|
|
||||||
security OBJECT IDENTIFIER ::= { internet 5 }
|
|
||||||
|
|
||||||
snmpV2 OBJECT IDENTIFIER ::= { internet 6 }
|
|
||||||
|
|
||||||
-- transport domains
|
|
||||||
snmpDomains OBJECT IDENTIFIER ::= { snmpV2 1 }
|
|
||||||
|
|
||||||
-- transport proxies
|
|
||||||
snmpProxys OBJECT IDENTIFIER ::= { snmpV2 2 }
|
|
||||||
|
|
||||||
-- module identities
|
|
||||||
coldStart OBJECT IDENTIFIER ::= { snmpV2 3 }
|
|
||||||
|
|
||||||
NOTIFICATION-TYPE MACRO ::=
|
|
||||||
BEGIN
|
|
||||||
TYPE NOTATION ::=
|
|
||||||
ObjectsPart
|
|
||||||
"STATUS" Status
|
|
||||||
"DESCRIPTION" Text
|
|
||||||
ReferPart
|
|
||||||
|
|
||||||
VALUE NOTATION ::=
|
|
||||||
value(VALUE NotificationName)
|
|
||||||
|
|
||||||
ObjectsPart ::=
|
|
||||||
"OBJECTS" "{" Objects "}"
|
|
||||||
| empty
|
|
||||||
Objects ::=
|
|
||||||
Object
|
|
||||||
|
|
||||||
| Objects "," Object
|
|
||||||
Object ::=
|
|
||||||
value(ObjectName)
|
|
||||||
|
|
||||||
Status ::=
|
|
||||||
"current"
|
|
||||||
| "deprecated"
|
|
||||||
| "obsolete"
|
|
||||||
|
|
||||||
ReferPart ::=
|
|
||||||
"REFERENCE" Text
|
|
||||||
| empty
|
|
||||||
|
|
||||||
-- a character string as defined in section 3.1.1
|
|
||||||
Text ::= value(IA5String)
|
|
||||||
END
|
|
||||||
|
|
||||||
NOTIFICATION-GROUP MACRO ::=
|
|
||||||
BEGIN
|
|
||||||
TYPE NOTATION ::=
|
|
||||||
NotificationsPart
|
|
||||||
"STATUS" Status
|
|
||||||
"DESCRIPTION" Text
|
|
||||||
ReferPart
|
|
||||||
|
|
||||||
VALUE NOTATION ::=
|
|
||||||
value(VALUE OBJECT IDENTIFIER)
|
|
||||||
|
|
||||||
NotificationsPart ::=
|
|
||||||
"NOTIFICATIONS" "{" Notifications "}"
|
|
||||||
Notifications ::=
|
|
||||||
Notification
|
|
||||||
| Notifications "," Notification
|
|
||||||
Notification ::=
|
|
||||||
value(NotificationName)
|
|
||||||
|
|
||||||
Status ::=
|
|
||||||
"current"
|
|
||||||
| "deprecated"
|
|
||||||
| "obsolete"
|
|
||||||
|
|
||||||
ReferPart ::=
|
|
||||||
"REFERENCE" Text
|
|
||||||
| empty
|
|
||||||
|
|
||||||
-- a character string as defined in [2]
|
|
||||||
Text ::= value(IA5String)
|
|
||||||
END
|
|
||||||
|
|
||||||
END
|
|
||||||
Loading…
Reference in New Issue