예제 #1
0
func snmp_ip_tree(host, community, oid string) (map[string]interface{}, error) {
	rows, err := snmp.Walk(host, community, oid)
	if err != nil {
		return nil, err
	}
	m := make(map[string]interface{})
	for rows.Next() {
		key := ""
		var a interface{}
		id, err := rows.Scan(&a)
		if err != nil {
			return nil, err
		}
		switch t := id.(type) {
		case []int:
			key = snmp_combine_ip_int(t)
		default:
			return nil, fmt.Errorf("Got wrong type from OID check")
		}
		m[key] = a
	}
	if err := rows.Err(); err != nil && err != io.EOF {
		return nil, err
	}
	return m, nil
}
예제 #2
0
func keepalived_vrrp_addresses(md *opentsdb.MultiDataPoint, instances map[int]*VRRPInstanceEntry) error {
	entries := make(map[int]map[int]*VRRPAddressEntry)
	rows, err := snmp.Walk("localhost", KeepalivedCommunity, VRRPAddressTable)
	if err != nil {
		return nil
	}
	for rows.Next() {
		var a interface{}
		i, err := rows.Scan(&a)
		if err != nil {
			return err
		}
		id, ok := i.([]int)
		if !ok || len(id) != 3 {
			return fmt.Errorf("unexpected type for snmp keepalived index")
		}
		if _, ok := entries[id[1]]; !ok {
			entries[id[1]] = make(map[int]*VRRPAddressEntry)
		}
		entry, ok := entries[id[1]][id[2]]
		if !ok {
			entries[id[1]][id[2]] = &VRRPAddressEntry{}
			entry = entries[id[1]][id[2]]
		}
		s := reflect.ValueOf(entry)
		nFields := reflect.ValueOf(*entry).NumField()
		nonPointerType := reflect.ValueOf(*entry).Type()
		if id[0]-1 > nFields {
			return fmt.Errorf("unexpected number of fields for snmp keepalived VRRPAddressTable")
		}
		v := s.Elem().Field(id[0] - 1)
		switch t := a.(type) {
		case int64:
			v.SetInt(t)
		case []uint8:
			if nonPointerType.Kind() == reflect.Struct && nonPointerType.Field(id[0]-1).Tag.Get("snmp") == "octet" {
				var s []string
				for _, runeValue := range t {
					s = append(s, fmt.Sprintf("%v", runeValue))
				}
				v.SetString(strings.Join(s, "."))
			} else {
				v.SetString(string(t))
			}
		}
	}
	for instance_id, instance := range instances {
		for _, entry := range entries[instance_id] {
			ts := opentsdb.TagSet{
				"instance_name": instance.VInstanceName,
				"instance_id":   fmt.Sprint(instance.VInstanceVirtualRouterId),
				"address":       entry.VRRPAddressValue}
			Add(md, "keepalived.vrrp.address_status", entry.VRRPAddressStatus-1, ts, metadata.Gauge, metadata.Bool, descVRRPAddressStatus)
			Add(md, "keepalived.vrrp.address_advertising", entry.VRRPAddressAdvertising-1, ts, metadata.Gauge, metadata.Bool, descVRRPAddressStatus)
		}
	}
	return nil
}
예제 #3
0
func c_snmp_keepalived_vrrp_instances() (opentsdb.MultiDataPoint, error) {
	if KeepalivedCommunity == "" {
		return nil, nil
	}
	var md opentsdb.MultiDataPoint
	entries := make(map[int]*VRRPInstanceEntry)
	rows, err := snmp.Walk("localhost", KeepalivedCommunity, VRRPInstanceTable)
	if err != nil {
		return nil, nil
	}
	for rows.Next() {
		var a interface{}
		i, err := rows.Scan(&a)
		if err != nil {
			return nil, err
		}
		id, ok := i.([]int)
		if !ok || len(id) != 2 {
			return nil, fmt.Errorf("unexpected type for snmp keepalived index")
		}
		entry, ok := entries[id[1]]
		if !ok {
			entries[id[1]] = &VRRPInstanceEntry{}
			entry = entries[id[1]]
		}
		s := reflect.ValueOf(entry)
		nFields := reflect.ValueOf(*entry).NumField()
		if id[0] > nFields {
			return nil, fmt.Errorf("unexpected number of fields for snmp keepalived VRRPInstanceTable")
		}
		v := s.Elem().Field(id[0] - 1)
		switch t := a.(type) {
		case int64:
			v.SetInt(t)
		case []uint8:
			v.SetString(string(t))
		}
	}
	for _, entry := range entries {
		ts := opentsdb.TagSet{"instance_name": entry.VInstanceName, "instance_id": fmt.Sprint(entry.VInstanceVirtualRouterId)}
		Add(&md, "keepalived.vrrp.state", entry.VInstanceState, ts, metadata.Gauge, metadata.StatusCode, descVRRPState)
		Add(&md, "keepalived.vrrp.wanted_state", entry.VInstanceWantedState, ts, metadata.Gauge, metadata.StatusCode, descVRRPState)
		Add(&md, "keepalived.vrrp.vips_status", entry.VInstanceVipsStatus, ts, metadata.Gauge, metadata.StatusCode, descVRRPVipsStatus)
		Add(&md, "keepalived.vrrp.base_priority", entry.VInstanceBasePriority, ts, metadata.Gauge, metadata.Priority, descVRRPBasePriority)
		Add(&md, "keepalived.vrrp.effective_priority", entry.VInstanceEffectivePriority, ts, metadata.Gauge, metadata.Priority, descVRRPEffectivePriority)
	}
	if err := keepalived_vrrp_addresses(&md, entries); err != nil {
		return nil, err
	}
	return md, nil
}
예제 #4
0
파일: snmp.go 프로젝트: eswdd/bosun
// snmp_subtree takes an oid and returns all data exactly one level below it. It
// produces an error if there is more than one level below.
func snmp_subtree(host, community, oid string) (map[string]interface{}, error) {
	rows, err := snmp.Walk(host, community, oid)
	if err != nil {
		return nil, err
	}
	m := make(map[string]interface{})
	for rows.Next() {
		key := ""
		var a interface{}
		switch oid {
		case ifHCInBroadcastPkts:
			a = new(big.Int)
			id, err := rows.Scan(&a)
			if err != nil {
				slog.Errorf("Error scanning oid %v on host %v: %v", oid, host, err)
				continue
			}
			switch t := id.(type) {
			case int:
				key = fmt.Sprint(t)
			default:
				return nil, fmt.Errorf("snmp subtree: only one level allowed")
			}
		default:
			id, err := rows.Scan(&a)
			if err != nil {
				slog.Errorf("Error scanning oid %v on host %v: %v", oid, host, err)
				continue
			}
			switch t := id.(type) {
			case int:
				key = fmt.Sprint(t)
			case []int:
				key = snmpOidArrayToString(t)
			default:
				return nil, fmt.Errorf("Unknown key type: %s", reflect.TypeOf(id).String())
			}
		}
		m[key] = a
	}
	if err := rows.Err(); err != nil && err != io.EOF {
		return nil, err
	}
	return m, nil
}