66
77from ..factory import target_factory
88from .common import ManagedResource , ResourceManager
9+ from ..util .loop import ensure_event_loop
910
1011@attr .s
1112class SNMPSwitch :
1213 """SNMPSwitch describes a switch accessible over SNMP. This class
1314 implements functions to query ports and the forwarding database."""
1415 hostname = attr .ib (validator = attr .validators .instance_of (str ))
16+ loop = attr .ib ()
1517
1618 def __attrs_post_init__ (self ):
19+ import pysnmp .hlapi .v3arch .asyncio as hlapi
20+
1721 self .logger = logging .getLogger (f"{ self } " )
1822 self .ports = {}
1923 self .fdb = {}
2024 self .macs_by_port = {}
25+ self .transport = self .loop .run_until_complete (hlapi .UdpTransportTarget .create ((self .hostname , 161 )))
2126 self ._autodetect ()
2227
2328 def _autodetect (self ):
24- from pysnmp import hlapi
29+ import pysnmp . hlapi . v3arch . asyncio as hlapi
2530
26- for (errorIndication , errorStatus , _ , varBindTable ) in hlapi .getCmd (
31+ for (errorIndication , errorStatus , _ , varBindTable ) in self . loop . run_until_complete ( hlapi .getCmd (
2732 hlapi .SnmpEngine (),
2833 hlapi .CommunityData ('public' ),
29- hlapi . UdpTransportTarget (( self .hostname , 161 )) ,
34+ self .transport ,
3035 hlapi .ContextData (),
31- hlapi .ObjectType (hlapi .ObjectIdentity ('SNMPv2-MIB' , 'sysDescr' , 0 ))):
36+ hlapi .ObjectType (hlapi .ObjectIdentity ('SNMPv2-MIB' , 'sysDescr' , 0 )))) :
3237 if errorIndication :
3338 raise Exception (f"snmp error { errorIndication } " )
3439 elif errorStatus :
@@ -51,7 +56,7 @@ def _get_ports(self):
5156 Returns:
5257 Dict[Dict[]]: ports and their values
5358 """
54- from pysnmp import hlapi
59+ import pysnmp . hlapi . v3arch . asyncio as hlapi
5560
5661 variables = [
5762 (hlapi .ObjectType (hlapi .ObjectIdentity ('IF-MIB' , 'ifIndex' )), 'index' ),
@@ -64,14 +69,14 @@ def _get_ports(self):
6469 ]
6570 ports = {}
6671
67- for (errorIndication , errorStatus , _ , varBindTable ) in hlapi .bulkCmd (
72+ for (errorIndication , errorStatus , _ , varBindTable ) in self . loop . run_until_complete ( hlapi .bulkCmd (
6873 hlapi .SnmpEngine (),
6974 hlapi .CommunityData ('public' ),
70- hlapi . UdpTransportTarget (( self .hostname , 161 )) ,
75+ self .transport ,
7176 hlapi .ContextData (),
7277 0 , 20 ,
7378 * [x [0 ] for x in variables ],
74- lexicographicMode = False ):
79+ lexicographicMode = False )) :
7580 if errorIndication :
7681 raise Exception (f"snmp error { errorIndication } " )
7782 elif errorStatus :
@@ -93,18 +98,18 @@ def _get_fdb_dot1d(self):
9398 Returns:
9499 Dict[List[str]]: ports and their values
95100 """
96- from pysnmp import hlapi
101+ import pysnmp . hlapi . v3arch . asyncio as hlapi
97102
98103 ports = {}
99104
100- for (errorIndication , errorStatus , _ , varBindTable ) in hlapi .bulkCmd (
105+ for (errorIndication , errorStatus , _ , varBindTable ) in self . loop . run_until_complete ( hlapi .bulkCmd (
101106 hlapi .SnmpEngine (),
102107 hlapi .CommunityData ('public' ),
103- hlapi . UdpTransportTarget (( self .hostname , 161 )) ,
108+ self .transport ,
104109 hlapi .ContextData (),
105110 0 , 50 ,
106111 hlapi .ObjectType (hlapi .ObjectIdentity ('BRIDGE-MIB' , 'dot1dTpFdbPort' )),
107- lexicographicMode = False ):
112+ lexicographicMode = False )) :
108113 if errorIndication :
109114 raise Exception (f"snmp error { errorIndication } " )
110115 elif errorStatus :
@@ -126,18 +131,18 @@ def _get_fdb_dot1q(self):
126131 Returns:
127132 Dict[List[str]]: ports and their values
128133 """
129- from pysnmp import hlapi
134+ import pysnmp . hlapi . v3arch . asyncio as hlapi
130135
131136 ports = {}
132137
133- for (errorIndication , errorStatus , _ , varBindTable ) in hlapi .bulkCmd (
138+ for (errorIndication , errorStatus , _ , varBindTable ) in self . loop . run_until_complete ( hlapi .bulkCmd (
134139 hlapi .SnmpEngine (),
135140 hlapi .CommunityData ('public' ),
136- hlapi . UdpTransportTarget (( self .hostname , 161 )) ,
141+ self .transport ,
137142 hlapi .ContextData (),
138143 0 , 50 ,
139144 hlapi .ObjectType (hlapi .ObjectIdentity ('Q-BRIDGE-MIB' , 'dot1qTpFdbPort' )),
140- lexicographicMode = False ):
145+ lexicographicMode = False )) :
141146 if errorIndication :
142147 raise Exception (f"snmp error { errorIndication } " )
143148 elif errorStatus :
@@ -223,14 +228,16 @@ async def poll_neighbour(self):
223228
224229 await asyncio .sleep (1.0 )
225230
231+ self .loop = ensure_event_loop ()
232+
226233 async def poll_switches (self ):
227234 current = set (resource .switch for resource in self .resources )
228235 removed = set (self .switches ) - current
229236 new = current - set (self .switches )
230237 for switch in removed :
231238 del self .switches [switch ]
232239 for switch in new :
233- self .switches [switch ] = SNMPSwitch (switch )
240+ self .switches [switch ] = SNMPSwitch (switch , self . loop )
234241 for switch in current :
235242 self .switches [switch ].update ()
236243 await asyncio .sleep (1.0 )
@@ -248,7 +255,6 @@ async def poll(self, handler):
248255 import traceback
249256 traceback .print_exc (file = sys .stderr )
250257
251- self .loop = asyncio .get_event_loop ()
252258 self .poll_tasks .append (self .loop .create_task (poll (self , poll_neighbour )))
253259 self .poll_tasks .append (self .loop .create_task (poll (self , poll_switches )))
254260
@@ -309,7 +315,6 @@ def poll(self):
309315 resource .extra = extra
310316 self .logger .debug ("new information for %s: %s" , resource , extra )
311317
312-
313318@target_factory .reg_resource
314319@attr .s
315320class SNMPEthernetPort (ManagedResource ):
0 commit comments