# Path: wiremaps/collector/icollector.py
# class ICollector(Interface):
#     """Interface for a collector for a given equipment"""
# 
#     def handleEquipment(oid):
#         """Does this instance handle the given equipment
# 
#         @param oid: OID identifying the kind of equipment
#         @return: C{True} if the equipment is handled
#         """
# 
#     def collectData(equipment, proxy):
#         """Collect data from the equipment
# 
#         @param equipment: equipment to complete with data
#         @param proxy: proxy to query the equipment with SNMP
# 
#         @return: an object implementing IEquipment interface and
#             containing all information for the given equipment.
#         """
# 
# Path: wiremaps/collector/datastore.py
# class Port:
#     implements(IPort)
# 
#     def __init__(self, name, state,
#                  alias=None, mac=None, speed=None, duplex=None, autoneg=None):
#         self.name = ascii(name)
#         self.state = state
#         self.alias = ascii(alias)
#         self.mac = mac
#         self.speed = speed
#         self.duplex = duplex
#         self.autoneg = autoneg
#         self.fdb = []
#         self.sonmp = None
#         self.edp = None
#         self.cdp = None
#         self.lldp = None
#         self.vlan = []
#         self.trunk = None
# 
# class Trunk:
#     implements(ITrunk)
# 
#     def __init__(self, parent):
#         self.parent = parent
# 
# class LocalVlan(Vlan):
#     implements(ILocalVlan)
# 
# Path: wiremaps/collector/helpers/arp.py
# class ArpCollector:
#     """Collect data using ARP"""
# 
#     ipNetToMediaPhysAddress = '.1.3.6.1.2.1.4.22.1.2'
# 
#     def __init__(self, equipment, proxy, config):
#         """Create a collector using ARP entries in SNMP.
# 
#         @param proxy: proxy to use to query SNMP
#         @param equipment: equipment to complete with ARP entries
#         @param config: configuration
#         """
#         self.proxy = proxy
#         self.equipment = equipment
#         self.config = config
# 
#     def gotArp(self, results):
#         """Callback handling reception of ARP
# 
#         @param results: result of walking C{IP-MIB::ipNetToMediaPhysAddress}
#         """
#         for oid in results:
#             ip = ".".join([m for m in oid.split(".")[-4:]])
#             mac = ":".join("%02x" % ord(m) for m in results[oid])
#             self.equipment.arp[ip] = mac
# 
#     def collectData(self):
#         """Collect data from SNMP using ipNetToMediaPhysAddress.
#         """
#         print "Collecting ARP for %s" % self.proxy.ip
#         d = self.proxy.walk(self.ipNetToMediaPhysAddress)
#         d.addCallback(self.gotArp)
#         return d


from zope.interface import implements
from twisted.plugin import IPlugin
from twisted.internet import defer
from wiremaps.collector.icollector import ICollector
from wiremaps.collector.datastore import Port, Trunk, LocalVlan
from wiremaps.collector.helpers.arp import ArpCollector
    F5 BigIP are Linux appliance running Net-SNMP. However, network
    interfaces are linked to some switch. Switch ports are not
    displayed in IF-MIB but in some proprietary MIB.

    Here are the revelant parts:

    F5-BIGIP-SYSTEM-MIB::sysInterfaceName."1.1" = STRING: 1.1
    F5-BIGIP-SYSTEM-MIB::sysInterfaceMediaActiveSpeed."1.1" = INTEGER: 1000
    F5-BIGIP-SYSTEM-MIB::sysInterfaceMediaActiveDuplex."1.1" = INTEGER: full(2)
    F5-BIGIP-SYSTEM-MIB::sysInterfaceMacAddr."1.1" = STRING: 0:1:d7:48:a7:94
    F5-BIGIP-SYSTEM-MIB::sysInterfaceEnabled."1.1" = INTEGER: true(1)
    F5-BIGIP-SYSTEM-MIB::sysInterfaceStatus."1.1" = INTEGER: up(0)
    F5-BIGIP-SYSTEM-MIB::sysTrunkName."TrunkIf" = STRING: TrunkIf
    F5-BIGIP-SYSTEM-MIB::sysTrunkStatus."TrunkIf" = INTEGER: up(0)
    F5-BIGIP-SYSTEM-MIB::sysTrunkAggAddr."TrunkIf" = STRING: 0:1:d7:48:a7:a0
    F5-BIGIP-SYSTEM-MIB::sysTrunkOperBw."TrunkIf" = INTEGER: 2000
    F5-BIGIP-SYSTEM-MIB::sysTrunkCfgMemberName."TrunkIf"."1.15" = STRING: 1.15
    F5-BIGIP-SYSTEM-MIB::sysTrunkCfgMemberName."TrunkIf"."1.16" = STRING: 1.16
    F5-BIGIP-SYSTEM-MIB::sysVlanVname."DMZ" = STRING: DMZ
    F5-BIGIP-SYSTEM-MIB::sysVlanId."DMZ" = INTEGER: 99
    F5-BIGIP-SYSTEM-MIB::sysVlanMemberVmname."DMZ"."TrunkIf" = STRING: TrunkIf

    The main problem is that everything is indexed using strings
    instead of numerical index. This does not fit our database scheme
    and does not allow collectors to work independently. Therefore, we
    will have an unique collector.

    We keep ARP collector, though.
    """


# Path: wiremaps/collector/icollector.py
# class ICollector(Interface):
#     """Interface for a collector for a given equipment"""
# 
#     def handleEquipment(oid):
#         """Does this instance handle the given equipment
# 
#         @param oid: OID identifying the kind of equipment
#         @return: C{True} if the equipment is handled
#         """
# 
#     def collectData(equipment, proxy):
#         """Collect data from the equipment
# 
#         @param equipment: equipment to complete with data
#         @param proxy: proxy to query the equipment with SNMP
# 
#         @return: an object implementing IEquipment interface and
#             containing all information for the given equipment.
#         """
# 
# Path: wiremaps/collector/datastore.py
# class Port:
#     implements(IPort)
# 
#     def __init__(self, name, state,
#                  alias=None, mac=None, speed=None, duplex=None, autoneg=None):
#         self.name = ascii(name)
#         self.state = state
#         self.alias = ascii(alias)
#         self.mac = mac
#         self.speed = speed
#         self.duplex = duplex
#         self.autoneg = autoneg
#         self.fdb = []
#         self.sonmp = None
#         self.edp = None
#         self.cdp = None
#         self.lldp = None
#         self.vlan = []
#         self.trunk = None
# 
# class Trunk:
#     implements(ITrunk)
# 
#     def __init__(self, parent):
#         self.parent = parent
# 
# class LocalVlan(Vlan):
#     implements(ILocalVlan)
# 
# Path: wiremaps/collector/helpers/arp.py
# class ArpCollector:
#     """Collect data using ARP"""
# 
#     ipNetToMediaPhysAddress = '.1.3.6.1.2.1.4.22.1.2'
# 
#     def __init__(self, equipment, proxy, config):
#         """Create a collector using ARP entries in SNMP.
# 
#         @param proxy: proxy to use to query SNMP
#         @param equipment: equipment to complete with ARP entries
#         @param config: configuration
#         """
#         self.proxy = proxy
#         self.equipment = equipment
#         self.config = config
# 
#     def gotArp(self, results):
#         """Callback handling reception of ARP
# 
#         @param results: result of walking C{IP-MIB::ipNetToMediaPhysAddress}
#         """
#         for oid in results:
#             ip = ".".join([m for m in oid.split(".")[-4:]])
#             mac = ":".join("%02x" % ord(m) for m in results[oid])
#             self.equipment.arp[ip] = mac
# 
#     def collectData(self):
#         """Collect data from SNMP using ipNetToMediaPhysAddress.
#         """
#         print "Collecting ARP for %s" % self.proxy.ip
#         d = self.proxy.walk(self.ipNetToMediaPhysAddress)
#         d.addCallback(self.gotArp)
#         return d


# Path: wiremaps/collector/equipment/f5.py
from zope.interface import implements
from twisted.plugin import IPlugin
from twisted.internet import defer
from wiremaps.collector.icollector import ICollector
from wiremaps.collector.datastore import Port, Trunk, LocalVlan
from wiremaps.collector.helpers.arp import ArpCollector

    F5 BigIP are Linux appliance running Net-SNMP. However, network
    interfaces are linked to some switch. Switch ports are not
    displayed in IF-MIB but in some proprietary MIB.

    Here are the revelant parts:

    F5-BIGIP-SYSTEM-MIB::sysInterfaceName."1.1" = STRING: 1.1
    F5-BIGIP-SYSTEM-MIB::sysInterfaceMediaActiveSpeed."1.1" = INTEGER: 1000
    F5-BIGIP-SYSTEM-MIB::sysInterfaceMediaActiveDuplex."1.1" = INTEGER: full(2)
    F5-BIGIP-SYSTEM-MIB::sysInterfaceMacAddr."1.1" = STRING: 0:1:d7:48:a7:94
    F5-BIGIP-SYSTEM-MIB::sysInterfaceEnabled."1.1" = INTEGER: true(1)
    F5-BIGIP-SYSTEM-MIB::sysInterfaceStatus."1.1" = INTEGER: up(0)
    F5-BIGIP-SYSTEM-MIB::sysTrunkName."TrunkIf" = STRING: TrunkIf
    F5-BIGIP-SYSTEM-MIB::sysTrunkStatus."TrunkIf" = INTEGER: up(0)
    F5-BIGIP-SYSTEM-MIB::sysTrunkAggAddr."TrunkIf" = STRING: 0:1:d7:48:a7:a0
    F5-BIGIP-SYSTEM-MIB::sysTrunkOperBw."TrunkIf" = INTEGER: 2000
    F5-BIGIP-SYSTEM-MIB::sysTrunkCfgMemberName."TrunkIf"."1.15" = STRING: 1.15
    F5-BIGIP-SYSTEM-MIB::sysTrunkCfgMemberName."TrunkIf"."1.16" = STRING: 1.16
    F5-BIGIP-SYSTEM-MIB::sysVlanVname."DMZ" = STRING: DMZ
    F5-BIGIP-SYSTEM-MIB::sysVlanId."DMZ" = INTEGER: 99
    F5-BIGIP-SYSTEM-MIB::sysVlanMemberVmname."DMZ"."TrunkIf" = STRING: TrunkIf

    The main problem is that everything is indexed using strings
    instead of numerical index. This does not fit our database scheme
    and does not allow collectors to work independently. Therefore, we
    will have an unique collector.

    We keep ARP collector, though.
    """


    implements(ICollector, IPlugin)