From 64570b63a1de7b25f08cf564d547e0600b05f581 Mon Sep 17 00:00:00 2001 From: Logan McNaughton Date: Tue, 25 May 2021 20:33:34 -0600 Subject: [PATCH] Use gosmi --- go.mod | 3 +- go.sum | 13 +++ plugins/inputs/snmp_trap/snmp_trap.go | 95 +++++++--------------- plugins/inputs/snmp_trap/snmp_trap_test.go | 68 ++-------------- 4 files changed, 51 insertions(+), 128 deletions(-) diff --git a/go.mod b/go.mod index f64f609968daa..e725b00e18839 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/Shopify/sarama v1.27.2 github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 // indirect github.com/aerospike/aerospike-client-go v1.27.0 - github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d + github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15 github.com/aliyun/alibaba-cloud-sdk-go v1.61.1004 github.com/amir/raidman v0.0.0-20170415203553-1ccc43bfb9c9 github.com/antchfx/xmlquery v1.3.5 @@ -112,6 +112,7 @@ require ( github.com/shopspring/decimal v0.0.0-20200105231215-408a2507e114 // indirect github.com/signalfx/golib/v3 v3.3.0 github.com/sirupsen/logrus v1.6.0 + github.com/sleepinggenius2/gosmi v0.4.2 github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271 github.com/stretchr/testify v1.7.0 github.com/tbrandon/mbserver v0.0.0-20170611213546-993e1772cc62 diff --git a/go.sum b/go.sum index 7e7835870e08a..9ba7a64356ff3 100644 --- a/go.sum +++ b/go.sum @@ -126,6 +126,12 @@ github.com/aerospike/aerospike-client-go v1.27.0/go.mod h1:zj8LBEnWBDOVEIJt8LvaR github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/alecthomas/go-thrift v0.0.0-20170109061633-7914173639b2/go.mod h1:CxCgO+NdpMdi9SsTlGbc0W+/UNxO3I0AabOEJZ3w61w= +github.com/alecthomas/kong v0.2.1/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI= +github.com/alecthomas/participle v0.4.1 h1:P2PJWzwrSpuCWXKnzqvw0b0phSfH1kJo4p2HvLynVsI= +github.com/alecthomas/participle v0.4.1/go.mod h1:T8u4bQOSMwrkTWOSyt8/jSFPEnRtd0FKFMjVfYBlqPs= +github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ= +github.com/alecthomas/repr v0.0.0-20210301060118-828286944d6a/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -134,6 +140,9 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2c github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/aliyun/alibaba-cloud-sdk-go v1.61.1004 h1:YtaYjXmemIMyySUbs0VGFPqsLpsNHf4TW/L6yqpJQ9s= github.com/aliyun/alibaba-cloud-sdk-go v1.61.1004/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15 h1:AUNCr9CiJuwrRYS3XieqF+Z9B9gNxo/eANAJCF2eiN4= +github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/amir/raidman v0.0.0-20170415203553-1ccc43bfb9c9 h1:FXrPTd8Rdlc94dKccl7KPmdmIbVh/OjelJ8/vgMRzcQ= github.com/amir/raidman v0.0.0-20170415203553-1ccc43bfb9c9/go.mod h1:eliMa/PW+RDr2QLWRmLH1R1ZA4RInpmvOzDDXtaIZkc= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= @@ -1005,6 +1014,10 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sleepinggenius2/gosmi v0.4.2 h1:XNK6vNuiODDiDa4MXVdWBHLnyeqorM4ov92WgkBjO7w= +github.com/sleepinggenius2/gosmi v0.4.2/go.mod h1:l8OniPmd3bJzw0MXP2/qh7AhP/e+bTY2CNivIhsnDT0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= diff --git a/plugins/inputs/snmp_trap/snmp_trap.go b/plugins/inputs/snmp_trap/snmp_trap.go index 32107eb5ffe71..8a155c26f4a0d 100644 --- a/plugins/inputs/snmp_trap/snmp_trap.go +++ b/plugins/inputs/snmp_trap/snmp_trap.go @@ -1,28 +1,26 @@ package snmp_trap import ( - "bufio" - "bytes" "fmt" "net" - "os/exec" + "os" + "path/filepath" "strconv" "strings" - "sync" "time" "github.com/influxdata/telegraf" "github.com/influxdata/telegraf/config" "github.com/influxdata/telegraf/internal" "github.com/influxdata/telegraf/plugins/inputs" + "github.com/sleepinggenius2/gosmi" + "github.com/sleepinggenius2/gosmi/types" "github.com/gosnmp/gosnmp" ) var defaultTimeout = config.Duration(time.Second * 5) -type execer func(config.Duration, string, ...string) ([]byte, error) - type mibEntry struct { mibName string oidText string @@ -52,11 +50,6 @@ type SnmpTrap struct { makeHandlerWrapper func(gosnmp.TrapHandlerFunc) gosnmp.TrapHandlerFunc Log telegraf.Logger `toml:"-"` - - cacheLock sync.Mutex - cache map[string]mibEntry - - execCmd execer } var sampleConfig = ` @@ -101,6 +94,29 @@ func (s *SnmpTrap) Gather(_ telegraf.Accumulator) error { } func init() { + gosmi.Init() + gosmi.AppendPath("/usr/share/snmp/mibs") + root := "/usr/share/snmp/mibs" + var folders []string + folders = append(folders, root) + filepath.Walk(root, func(path string, info os.FileInfo, err error) error { + if info.Mode()&os.ModeSymlink != 0 { + s, _ := os.Readlink(path) + folders = append(folders, s) + } + return nil + }) + for _, folder := range folders { + filepath.Walk(folder, func(path string, info os.FileInfo, err error) error { + if info.IsDir() { + gosmi.AppendPath(path) + } else if info.Mode()&os.ModeSymlink == 0 { + gosmi.LoadModule(info.Name()) + } + return nil + }) + } + inputs.Add("snmp_trap", func() telegraf.Input { return &SnmpTrap{ timeFunc: time.Now, @@ -111,23 +127,6 @@ func init() { }) } -func realExecCmd(timeout config.Duration, arg0 string, args ...string) ([]byte, error) { - cmd := exec.Command(arg0, args...) - var out bytes.Buffer - cmd.Stdout = &out - err := internal.RunTimeout(cmd, time.Duration(timeout)) - if err != nil { - return nil, err - } - return out.Bytes(), nil -} - -func (s *SnmpTrap) Init() error { - s.cache = map[string]mibEntry{} - s.execCmd = realExecCmd - return nil -} - func (s *SnmpTrap) Start(acc telegraf.Accumulator) error { s.acc = acc s.listener = gosnmp.NewTrapListener() @@ -367,47 +366,13 @@ func makeTrapHandler(s *SnmpTrap) gosnmp.TrapHandlerFunc { } func (s *SnmpTrap) lookup(oid string) (e mibEntry, err error) { - s.cacheLock.Lock() - defer s.cacheLock.Unlock() - var ok bool - if e, ok = s.cache[oid]; !ok { - // cache miss. exec snmptranslate - e, err = s.snmptranslate(oid) - if err == nil { - s.cache[oid] = e - } - return e, err - } - return e, nil -} - -func (s *SnmpTrap) clear() { - s.cacheLock.Lock() - defer s.cacheLock.Unlock() - s.cache = map[string]mibEntry{} -} - -func (s *SnmpTrap) load(oid string, e mibEntry) { - s.cacheLock.Lock() - defer s.cacheLock.Unlock() - s.cache[oid] = e -} - -func (s *SnmpTrap) snmptranslate(oid string) (e mibEntry, err error) { - var out []byte - out, err = s.execCmd(s.Timeout, "snmptranslate", "-Td", "-Ob", "-m", "all", oid) - + var node gosmi.SmiNode + node, err = gosmi.GetNodeByOID(types.OidMustFromString(oid)) if err != nil { return e, err } - scanner := bufio.NewScanner(bytes.NewBuffer(out)) - ok := scanner.Scan() - if err = scanner.Err(); !ok && err != nil { - return e, err - } - - e.oidText = scanner.Text() + e.oidText = node.RenderQualified() i := strings.Index(e.oidText, "::") if i == -1 { diff --git a/plugins/inputs/snmp_trap/snmp_trap_test.go b/plugins/inputs/snmp_trap/snmp_trap_test.go index 98e3d7f09b2e5..faf61a4092bec 100644 --- a/plugins/inputs/snmp_trap/snmp_trap_test.go +++ b/plugins/inputs/snmp_trap/snmp_trap_test.go @@ -1,7 +1,6 @@ package snmp_trap import ( - "fmt" "net" "strconv" "strings" @@ -17,29 +16,6 @@ import ( "github.com/stretchr/testify/require" ) -func TestLoad(t *testing.T) { - s := &SnmpTrap{} - require.Nil(t, s.Init()) - - defer s.clear() - s.load( - ".1.3.6.1.6.3.1.1.5.1", - mibEntry{ - "SNMPv2-MIB", - "coldStart", - }, - ) - - e, err := s.lookup(".1.3.6.1.6.3.1.1.5.1") - require.NoError(t, err) - require.Equal(t, "SNMPv2-MIB", e.mibName) - require.Equal(t, "coldStart", e.oidText) -} - -func fakeExecCmd(_ config.Duration, x string, y ...string) ([]byte, error) { - return nil, fmt.Errorf("mock " + x + " " + strings.Join(y, " ")) -} - func newMsgFlagsV3(secLevel string) gosnmp.SnmpV3MsgFlags { var msgFlags gosnmp.SnmpV3MsgFlags switch strings.ToLower(secLevel) { @@ -242,30 +218,6 @@ func TestReceiveTrap(t *testing.T) { ), }, }, - //Check that we're not running snmptranslate to look up oids - //when we shouldn't be. This sends and receives a valid trap - //but metric production should fail because the oids aren't in - //the cache and oid lookup is intentionally mocked to fail. - { - name: "missing oid", - version: gosnmp.Version2c, - 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 - }, - }, - }, - entries: []entry{}, //nothing in cache - metrics: []telegraf.Metric{}, - }, //v1 enterprise specific trap { name: "v1 trap enterprise", @@ -305,8 +257,8 @@ func TestReceiveTrap(t *testing.T) { "snmp_trap", // name map[string]string{ // tags "oid": ".1.2.3.0.55", - "name": "enterpriseOID", - "mib": "enterpriseMIB", + "name": "iso", + "mib": "", "version": "1", "source": "127.0.0.1", "agent_address": "10.20.30.40", @@ -314,7 +266,7 @@ func TestReceiveTrap(t *testing.T) { }, map[string]interface{}{ // fields "sysUpTimeInstance": uint(now), - "valueOID": "payload", + "iso": "payload", }, fakeTime, ), @@ -359,8 +311,8 @@ func TestReceiveTrap(t *testing.T) { "snmp_trap", // name map[string]string{ // tags "oid": ".1.3.6.1.6.3.1.1.5.1", - "name": "coldStartOID", - "mib": "coldStartMIB", + "name": "coldStart", + "mib": "SNMPv2-MIB", "version": "1", "source": "127.0.0.1", "agent_address": "10.20.30.40", @@ -368,7 +320,7 @@ func TestReceiveTrap(t *testing.T) { }, map[string]interface{}{ // fields "sysUpTimeInstance": uint(now), - "valueOID": "payload", + "iso": "payload", }, fakeTime, ), @@ -1293,19 +1245,11 @@ func TestReceiveTrap(t *testing.T) { PrivProtocol: tt.privProto, PrivPassword: tt.privPass, } - require.Nil(t, s.Init()) // Don't look up oid with snmptranslate. - s.execCmd = fakeExecCmd var acc testutil.Accumulator require.Nil(t, s.Start(&acc)) defer s.Stop() - // Preload the cache with the oids we'll use in this test - // so snmptranslate and mibs don't need to be installed. - for _, entry := range tt.entries { - s.load(entry.oid, entry.e) - } - var goSNMP gosnmp.GoSNMP if tt.version == gosnmp.Version3 { msgFlags := newMsgFlagsV3(tt.secLevel)