67 lines
1.7 KiB
Go
67 lines
1.7 KiB
Go
package snmp
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/soniah/gosnmp"
|
|
)
|
|
|
|
// snmpConnection is an interface which wraps a *gosnmp.GoSNMP object.
|
|
// We interact through an interface so we can mock it out in tests.
|
|
type snmpConnection interface {
|
|
Host() string
|
|
//BulkWalkAll(string) ([]gosnmp.SnmpPDU, error)
|
|
Walk(string, gosnmp.WalkFunc) error
|
|
Get(oids []string) (*gosnmp.SnmpPacket, error)
|
|
}
|
|
|
|
// gosnmpWrapper wraps a *gosnmp.GoSNMP object so we can use it as a snmpConnection.
|
|
type gosnmpWrapper struct {
|
|
*gosnmp.GoSNMP
|
|
}
|
|
|
|
// Host returns the value of GoSNMP.Target.
|
|
func (gsw gosnmpWrapper) Host() string {
|
|
return gsw.Target
|
|
}
|
|
|
|
// Walk wraps GoSNMP.Walk() or GoSNMP.BulkWalk(), depending on whether the
|
|
// connection is using SNMPv1 or newer.
|
|
// Also, if any error is encountered, it will just once reconnect and try again.
|
|
func (gsw gosnmpWrapper) Walk(oid string, fn gosnmp.WalkFunc) error {
|
|
var err error
|
|
// On error, retry once.
|
|
// Unfortunately we can't distinguish between an error returned by gosnmp, and one returned by the walk function.
|
|
for i := 0; i < 2; i++ {
|
|
if gsw.Version == gosnmp.Version1 {
|
|
err = gsw.GoSNMP.Walk(oid, fn)
|
|
} else {
|
|
err = gsw.GoSNMP.BulkWalk(oid, fn)
|
|
}
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
if err := gsw.GoSNMP.Connect(); err != nil {
|
|
return fmt.Errorf("reconnecting %s", err)
|
|
}
|
|
}
|
|
return err
|
|
}
|
|
|
|
// Get wraps GoSNMP.GET().
|
|
// If any error is encountered, it will just once reconnect and try again.
|
|
func (gsw gosnmpWrapper) Get(oids []string) (*gosnmp.SnmpPacket, error) {
|
|
var err error
|
|
var pkt *gosnmp.SnmpPacket
|
|
for i := 0; i < 2; i++ {
|
|
pkt, err = gsw.GoSNMP.Get(oids)
|
|
if err == nil {
|
|
return pkt, nil
|
|
}
|
|
if err := gsw.GoSNMP.Connect(); err != nil {
|
|
return nil, fmt.Errorf("reconnecting %s", err)
|
|
}
|
|
}
|
|
return nil, err
|
|
}
|