Skip to content

Instantly share code, notes, and snippets.

@kaorimatz
Created December 19, 2014 04:50
Show Gist options
  • Save kaorimatz/0332fdf95f5f5f6e72df to your computer and use it in GitHub Desktop.
Save kaorimatz/0332fdf95f5f5f6e72df to your computer and use it in GitHub Desktop.
package main
import (
"encoding/asn1"
"encoding/json"
"flag"
"fmt"
"os"
"github.com/k-sone/snmpgo"
)
const (
jnxOperatingContentsIndex = "1.3.6.1.4.1.2636.3.1.13.1.1"
jnxOperatingDescr = "1.3.6.1.4.1.2636.3.1.13.1.5"
jnxOperatingCPU = "1.3.6.1.4.1.2636.3.1.13.1.8"
)
type options struct {
community string
maxRepetitions int
}
func parseCommandLine() *options {
var options options
flag.Usage = usage
flag.StringVar(&options.community, "community", "public", "the community string")
flag.IntVar(&options.maxRepetitions, "max-repetitions", 10, "max-repetitions field in the GETBULK PDU")
flag.Parse()
return &options
}
func usage() {
fmt.Fprintf(os.Stderr, "Usage: juniper_cpu [options] <address>\n")
flag.PrintDefaults()
}
func index(o, parent *snmpgo.Oid) (asn1.ObjectIdentifier, error) {
if !o.Contains(parent) {
return nil, fmt.Errorf("%v is not a subtree of %v", o, parent)
}
if o.Equal(parent) {
return nil, fmt.Errorf("OIDs are the same")
}
return o.Value[len(parent.Value):], nil
}
func main() {
options := parseCommandLine()
if flag.NArg() != 1 {
flag.Usage()
return
}
address := flag.Arg(0)
snmp, err := snmpgo.NewSNMP(snmpgo.SNMPArguments{
Version: snmpgo.V2c,
Address: address,
Community: options.community,
})
if err != nil {
fmt.Println(err)
return
}
if err = snmp.Open(); err != nil {
fmt.Println(err)
return
}
defer snmp.Close()
jnxOperatingContentsIndexOid, err := snmpgo.NewOid(jnxOperatingContentsIndex)
if err != nil {
fmt.Println(err)
return
}
oids := snmpgo.Oids{
jnxOperatingContentsIndexOid,
}
pdu, err := snmp.GetBulkWalk(oids, 0, options.maxRepetitions)
if err != nil {
fmt.Println(err)
return
}
if pdu.ErrorStatus() != snmpgo.NoError {
fmt.Println(pdu.ErrorStatus(), pdu.ErrorIndex())
return
}
jnxOperatingEntryIndices := make([]asn1.ObjectIdentifier, len(pdu.VarBinds()))
for i, varBind := range pdu.VarBinds() {
index, err := index(varBind.Oid, jnxOperatingContentsIndexOid)
if err != nil {
fmt.Println(err)
return
}
jnxOperatingEntryIndices[i] = index
}
jnxOperatingCPUOids := make(snmpgo.Oids, len(jnxOperatingEntryIndices))
for i, index := range jnxOperatingEntryIndices {
oid, err := snmpgo.NewOid(fmt.Sprintf("%s.%s", jnxOperatingCPU, index))
if err != nil {
fmt.Println(err)
return
}
jnxOperatingCPUOids[i] = oid
}
pdu, err = snmp.GetRequest(jnxOperatingCPUOids)
if err != nil {
fmt.Println(err)
return
}
if pdu.ErrorStatus() != snmpgo.NoError {
fmt.Println(pdu.ErrorStatus(), pdu.ErrorIndex())
return
}
jnxOperatingEntryCPUIndices := []asn1.ObjectIdentifier{}
for i, varBind := range pdu.VarBinds() {
if varBind.Variable.Type() != "Gauge32" {
fmt.Printf("Response variable type is not Gauge32: %v\n", varBind)
return
}
if varBind.Variable.(*snmpgo.Gauge32).Value != 0 {
jnxOperatingEntryCPUIndices = append(jnxOperatingEntryCPUIndices, jnxOperatingEntryIndices[i])
}
}
jnxOperatingDescrOids := make(snmpgo.Oids, len(jnxOperatingEntryCPUIndices))
for i, index := range jnxOperatingEntryCPUIndices {
oid, err := snmpgo.NewOid(fmt.Sprintf("%s.%s", jnxOperatingDescr, index))
if err != nil {
fmt.Println(err)
return
}
jnxOperatingDescrOids[i] = oid
}
pdu, err = snmp.GetRequest(jnxOperatingDescrOids)
if err != nil {
fmt.Println(err)
return
}
if pdu.ErrorStatus() != snmpgo.NoError {
fmt.Println(pdu.ErrorStatus(), pdu.ErrorIndex())
return
}
juniperCPUs := make([]map[string]string, len(pdu.VarBinds()))
for i, varBind := range pdu.VarBinds() {
juniperCPUs[i] = map[string]string{
"index": jnxOperatingEntryCPUIndices[i].String(),
"description": varBind.Variable.String(),
}
}
json, err := json.Marshal(juniperCPUs)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%s\n", json)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment