Loading config.go 0 → 100644 +35 −0 Original line number Diff line number Diff line package main import ( "io/ioutil" yaml "gopkg.in/yaml.v2" ) type Config struct { SnmpPort uint16 `yaml:"snmp_port"` SnmpCommunity string `yaml:"snmp_community"` BaseOid string `yaml:"base_oid"` AppPort uint16 `yaml:"app_port"` } func LoadConfig(path string) (Config, error) { yamlstr, err := ioutil.ReadFile(path) // Initialize with default values yamlparsed := Config{ SnmpPort: 161, SnmpCommunity: "public", AppPort: 8080, BaseOid: "1.3.6", } if err != nil { return yamlparsed, err } err = yaml.Unmarshal(yamlstr, &yamlparsed) if err != nil { return yamlparsed, err } return yamlparsed, nil } data_loader.go 0 → 100644 +209 −0 Original line number Diff line number Diff line package main import ( "encoding/csv" "fmt" "io/ioutil" "net" "strconv" "strings" "time" "github.com/posteo/go-agentx/pdu" "github.com/posteo/go-agentx/value" ) func LoadOids(snmp_handler *SNMPHandler, oid_files ...string) error { log.Info("Loading oids...") for _, oid_file := range oid_files { log.Info("Loading oids from file", oid_file) file_data, err := ioutil.ReadFile(oid_file) if err != nil { return err } err = loadOids(snmp_handler, string(file_data)) if err != nil { return err } } return nil } func loadOids(snmp_handler *SNMPHandler, data string) error { r := csv.NewReader(strings.NewReader(data)) r.Comma = ';' records, err := r.ReadAll() if err != nil { return err } for _, oid_data := range records { if len(oid_data) != 3 { return fmt.Errorf("Expected 3 elements in line (oid;type;value). Got: %v", len(oid_data)) } oid, err := value.ParseOID(oid_data[0]) if err != nil { return err } oid_type, err := stringToVariableType(oid_data[1]) if err != nil { return err } value, err := convertVariable(oid_data[2], oid_type) if err != nil { return err } snmp_handler.Add(oid, oid_type, value) } return nil } func stringToVariableType(s string) (pdu.VariableType, error) { switch s { case "Integer": return pdu.VariableTypeInteger, nil case "OctetString": return pdu.VariableTypeOctetString, nil case "Null": return pdu.VariableTypeNull, nil case "ObjectIdentifier": return pdu.VariableTypeObjectIdentifier, nil case "IPAddress": return pdu.VariableTypeIPAddress, nil case "Counter32": return pdu.VariableTypeCounter32, nil case "Gauge32": return pdu.VariableTypeGauge32, nil case "TimeTicks": return pdu.VariableTypeTimeTicks, nil //case "Opaque": // return pdu.VariableTypeOpaque case "Counter64": return pdu.VariableTypeCounter64, nil default: return pdu.VariableTypeNoSuchObject, fmt.Errorf("Unknown type '%v'", s) } } func convertVariable(val string, oid_type pdu.VariableType) (interface{}, error) { switch oid_type { case pdu.VariableTypeInteger: if i, err := strconv.ParseInt(val, 10, 32); err != nil { return nil, err } else { return int32(i), nil } case pdu.VariableTypeOctetString: return val, nil case pdu.VariableTypeObjectIdentifier: _, err := value.ParseOID(val) return val, err case pdu.VariableTypeIPAddress: ip := net.ParseIP(val).To4() if ip == nil { return nil, fmt.Errorf("Wrong IP format (%v)", val) } else { return ip, nil } case pdu.VariableTypeCounter32, pdu.VariableTypeGauge32: if i, err := strconv.ParseUint(val, 10, 32); err != nil { return nil, err } else { return uint32(i), nil } case pdu.VariableTypeTimeTicks: if d, err := strconv.ParseUint(val, 10, 32); err != nil { return nil, err } else { return time.Duration(d) * time.Millisecond * 10, nil } //case VariableTypeOpaque: case pdu.VariableTypeCounter64: if i, err := strconv.ParseUint(val, 10, 64); err != nil { return nil, err } else { return uint64(i), nil } default: return nil, fmt.Errorf("Unknown type %v", oid_type) } } /* func (v *Variable) UnmarshalBinary(data []byte) error { buffer := bytes.NewBuffer(data) if err := binary.Read(buffer, binary.LittleEndian, &v.Type); err != nil { return errgo.Mask(err) } offset := 4 if err := v.Name.UnmarshalBinary(data[offset:]); err != nil { return errgo.Mask(err) } offset += v.Name.ByteSize() switch v.Type { case VariableTypeInteger: value := int32(0) if err := binary.Read(buffer, binary.LittleEndian, &value); err != nil { return errgo.Mask(err) } v.Value = value case VariableTypeOctetString: octetString := &OctetString{} if err := octetString.UnmarshalBinary(data[offset:]); err != nil { return errgo.Mask(err) } v.Value = octetString.Text case VariableTypeNull, VariableTypeNoSuchObject, VariableTypeNoSuchInstance, VariableTypeEndOfMIBView: v.Value = nil case VariableTypeObjectIdentifier: oid := &ObjectIdentifier{} if err := oid.UnmarshalBinary(data[offset:]); err != nil { return errgo.Mask(err) } v.Value = oid.GetIdentifier() case VariableTypeIPAddress: octetString := &OctetString{} if err := octetString.UnmarshalBinary(data[offset:]); err != nil { return errgo.Mask(err) } v.Value = net.IP(octetString.Text) case VariableTypeCounter32, VariableTypeGauge32: value := uint32(0) if err := binary.Read(buffer, binary.LittleEndian, &value); err != nil { return errgo.Mask(err) } v.Value = value case VariableTypeTimeTicks: value := uint32(0) if err := binary.Read(buffer, binary.LittleEndian, &value); err != nil { return errgo.Mask(err) } v.Value = time.Duration(value) * time.Second / 100 case VariableTypeOpaque: octetString := &OctetString{} if err := octetString.UnmarshalBinary(data[offset:]); err != nil { return errgo.Mask(err) } v.Value = []byte(octetString.Text) case VariableTypeCounter64: value := uint64(0) if err := binary.Read(buffer, binary.LittleEndian, &value); err != nil { return errgo.Mask(err) } v.Value = value default: return errgo.Newf("unhandled variable type %s", v.Type) } return nil } */ docker/config.yaml 0 → 100644 +2 −0 Original line number Diff line number Diff line app_port: 8080 base_oid: "1.3.6.100.1.2.3" docker/init.sh 0 → 100755 +27 −0 Original line number Diff line number Diff line #!/bin/sh SNMP_CONF_FILE=/app/snmpd.conf MOCK_CONF_FILE=/app/config.yaml if [ ! -z "$SNMP_PORT" ];then echo "Replacing snmp port with $SNMP_PORT" sed -i "s/agentAddress udp:\([0-9][0-9]*\)/agentAddress udp:$SNMP_PORT/" $SNMP_CONF_FILE fi if [ ! -z "$SNMP_COMMUNITY" ];then echo "Replacing snmp community with $SNMP_COMMUNITY" sed -i "s/rocommunity .*/rocommunity $SNMP_COMMUNITY/" $SNMP_CONF_FILE fi if [ ! -z "$BASE_OID" ];then echo "Replacing base_oid with $BASE_OID" sed -i "s/base_oid:.*/base_oid: $BASE_OID/" $MOCK_CONF_FILE fi if [ ! -z "$APP_PORT" ];then echo "Replacing app_port with $APP_PORT" sed -i "s/app_port:.*/app_port: $APP_PORT/" $MOCK_CONF_FILE fi /usr/sbin/snmpd -Lsd -C -c $SNMP_CONF_FILE /app/snmp_mock `find /app/oids -type f -name "*.csv"` docker/snmpd.conf 0 → 100644 +8 −0 Original line number Diff line number Diff line # Listen for connections on all interfaces (both IPv4 *and* IPv6) agentAddress udp:161 rocommunity public # Run as an AgentX master agent master agentx agentXSocket tcp:localhost:705 Loading
config.go 0 → 100644 +35 −0 Original line number Diff line number Diff line package main import ( "io/ioutil" yaml "gopkg.in/yaml.v2" ) type Config struct { SnmpPort uint16 `yaml:"snmp_port"` SnmpCommunity string `yaml:"snmp_community"` BaseOid string `yaml:"base_oid"` AppPort uint16 `yaml:"app_port"` } func LoadConfig(path string) (Config, error) { yamlstr, err := ioutil.ReadFile(path) // Initialize with default values yamlparsed := Config{ SnmpPort: 161, SnmpCommunity: "public", AppPort: 8080, BaseOid: "1.3.6", } if err != nil { return yamlparsed, err } err = yaml.Unmarshal(yamlstr, &yamlparsed) if err != nil { return yamlparsed, err } return yamlparsed, nil }
data_loader.go 0 → 100644 +209 −0 Original line number Diff line number Diff line package main import ( "encoding/csv" "fmt" "io/ioutil" "net" "strconv" "strings" "time" "github.com/posteo/go-agentx/pdu" "github.com/posteo/go-agentx/value" ) func LoadOids(snmp_handler *SNMPHandler, oid_files ...string) error { log.Info("Loading oids...") for _, oid_file := range oid_files { log.Info("Loading oids from file", oid_file) file_data, err := ioutil.ReadFile(oid_file) if err != nil { return err } err = loadOids(snmp_handler, string(file_data)) if err != nil { return err } } return nil } func loadOids(snmp_handler *SNMPHandler, data string) error { r := csv.NewReader(strings.NewReader(data)) r.Comma = ';' records, err := r.ReadAll() if err != nil { return err } for _, oid_data := range records { if len(oid_data) != 3 { return fmt.Errorf("Expected 3 elements in line (oid;type;value). Got: %v", len(oid_data)) } oid, err := value.ParseOID(oid_data[0]) if err != nil { return err } oid_type, err := stringToVariableType(oid_data[1]) if err != nil { return err } value, err := convertVariable(oid_data[2], oid_type) if err != nil { return err } snmp_handler.Add(oid, oid_type, value) } return nil } func stringToVariableType(s string) (pdu.VariableType, error) { switch s { case "Integer": return pdu.VariableTypeInteger, nil case "OctetString": return pdu.VariableTypeOctetString, nil case "Null": return pdu.VariableTypeNull, nil case "ObjectIdentifier": return pdu.VariableTypeObjectIdentifier, nil case "IPAddress": return pdu.VariableTypeIPAddress, nil case "Counter32": return pdu.VariableTypeCounter32, nil case "Gauge32": return pdu.VariableTypeGauge32, nil case "TimeTicks": return pdu.VariableTypeTimeTicks, nil //case "Opaque": // return pdu.VariableTypeOpaque case "Counter64": return pdu.VariableTypeCounter64, nil default: return pdu.VariableTypeNoSuchObject, fmt.Errorf("Unknown type '%v'", s) } } func convertVariable(val string, oid_type pdu.VariableType) (interface{}, error) { switch oid_type { case pdu.VariableTypeInteger: if i, err := strconv.ParseInt(val, 10, 32); err != nil { return nil, err } else { return int32(i), nil } case pdu.VariableTypeOctetString: return val, nil case pdu.VariableTypeObjectIdentifier: _, err := value.ParseOID(val) return val, err case pdu.VariableTypeIPAddress: ip := net.ParseIP(val).To4() if ip == nil { return nil, fmt.Errorf("Wrong IP format (%v)", val) } else { return ip, nil } case pdu.VariableTypeCounter32, pdu.VariableTypeGauge32: if i, err := strconv.ParseUint(val, 10, 32); err != nil { return nil, err } else { return uint32(i), nil } case pdu.VariableTypeTimeTicks: if d, err := strconv.ParseUint(val, 10, 32); err != nil { return nil, err } else { return time.Duration(d) * time.Millisecond * 10, nil } //case VariableTypeOpaque: case pdu.VariableTypeCounter64: if i, err := strconv.ParseUint(val, 10, 64); err != nil { return nil, err } else { return uint64(i), nil } default: return nil, fmt.Errorf("Unknown type %v", oid_type) } } /* func (v *Variable) UnmarshalBinary(data []byte) error { buffer := bytes.NewBuffer(data) if err := binary.Read(buffer, binary.LittleEndian, &v.Type); err != nil { return errgo.Mask(err) } offset := 4 if err := v.Name.UnmarshalBinary(data[offset:]); err != nil { return errgo.Mask(err) } offset += v.Name.ByteSize() switch v.Type { case VariableTypeInteger: value := int32(0) if err := binary.Read(buffer, binary.LittleEndian, &value); err != nil { return errgo.Mask(err) } v.Value = value case VariableTypeOctetString: octetString := &OctetString{} if err := octetString.UnmarshalBinary(data[offset:]); err != nil { return errgo.Mask(err) } v.Value = octetString.Text case VariableTypeNull, VariableTypeNoSuchObject, VariableTypeNoSuchInstance, VariableTypeEndOfMIBView: v.Value = nil case VariableTypeObjectIdentifier: oid := &ObjectIdentifier{} if err := oid.UnmarshalBinary(data[offset:]); err != nil { return errgo.Mask(err) } v.Value = oid.GetIdentifier() case VariableTypeIPAddress: octetString := &OctetString{} if err := octetString.UnmarshalBinary(data[offset:]); err != nil { return errgo.Mask(err) } v.Value = net.IP(octetString.Text) case VariableTypeCounter32, VariableTypeGauge32: value := uint32(0) if err := binary.Read(buffer, binary.LittleEndian, &value); err != nil { return errgo.Mask(err) } v.Value = value case VariableTypeTimeTicks: value := uint32(0) if err := binary.Read(buffer, binary.LittleEndian, &value); err != nil { return errgo.Mask(err) } v.Value = time.Duration(value) * time.Second / 100 case VariableTypeOpaque: octetString := &OctetString{} if err := octetString.UnmarshalBinary(data[offset:]); err != nil { return errgo.Mask(err) } v.Value = []byte(octetString.Text) case VariableTypeCounter64: value := uint64(0) if err := binary.Read(buffer, binary.LittleEndian, &value); err != nil { return errgo.Mask(err) } v.Value = value default: return errgo.Newf("unhandled variable type %s", v.Type) } return nil } */
docker/config.yaml 0 → 100644 +2 −0 Original line number Diff line number Diff line app_port: 8080 base_oid: "1.3.6.100.1.2.3"
docker/init.sh 0 → 100755 +27 −0 Original line number Diff line number Diff line #!/bin/sh SNMP_CONF_FILE=/app/snmpd.conf MOCK_CONF_FILE=/app/config.yaml if [ ! -z "$SNMP_PORT" ];then echo "Replacing snmp port with $SNMP_PORT" sed -i "s/agentAddress udp:\([0-9][0-9]*\)/agentAddress udp:$SNMP_PORT/" $SNMP_CONF_FILE fi if [ ! -z "$SNMP_COMMUNITY" ];then echo "Replacing snmp community with $SNMP_COMMUNITY" sed -i "s/rocommunity .*/rocommunity $SNMP_COMMUNITY/" $SNMP_CONF_FILE fi if [ ! -z "$BASE_OID" ];then echo "Replacing base_oid with $BASE_OID" sed -i "s/base_oid:.*/base_oid: $BASE_OID/" $MOCK_CONF_FILE fi if [ ! -z "$APP_PORT" ];then echo "Replacing app_port with $APP_PORT" sed -i "s/app_port:.*/app_port: $APP_PORT/" $MOCK_CONF_FILE fi /usr/sbin/snmpd -Lsd -C -c $SNMP_CONF_FILE /app/snmp_mock `find /app/oids -type f -name "*.csv"`
docker/snmpd.conf 0 → 100644 +8 −0 Original line number Diff line number Diff line # Listen for connections on all interfaces (both IPv4 *and* IPv6) agentAddress udp:161 rocommunity public # Run as an AgentX master agent master agentx agentXSocket tcp:localhost:705