@@ -12,23 +12,27 @@ class SNMPSwitch:
12
12
"""SNMPSwitch describes a switch accessible over SNMP. This class
13
13
implements functions to query ports and the forwarding database."""
14
14
hostname = attr .ib (validator = attr .validators .instance_of (str ))
15
+ loop = attr .ib ()
15
16
16
17
def __attrs_post_init__ (self ):
18
+ import pysnmp .hlapi .v3arch .asyncio as hlapi
19
+
17
20
self .logger = logging .getLogger (f"{ self } " )
18
21
self .ports = {}
19
22
self .fdb = {}
20
23
self .macs_by_port = {}
24
+ self .transport = self .loop .run_until_complete (hlapi .UdpTransportTarget .create ((self .hostname , 161 )))
21
25
self ._autodetect ()
22
26
23
27
def _autodetect (self ):
24
- from pysnmp import hlapi
28
+ import pysnmp . hlapi . v3arch . asyncio as hlapi
25
29
26
- for (errorIndication , errorStatus , _ , varBindTable ) in hlapi .getCmd (
30
+ for (errorIndication , errorStatus , _ , varBindTable ) in self . loop . run_until_complete ( hlapi .getCmd (
27
31
hlapi .SnmpEngine (),
28
32
hlapi .CommunityData ('public' ),
29
- hlapi . UdpTransportTarget (( self .hostname , 161 )) ,
33
+ self .transport ,
30
34
hlapi .ContextData (),
31
- hlapi .ObjectType (hlapi .ObjectIdentity ('SNMPv2-MIB' , 'sysDescr' , 0 ))):
35
+ hlapi .ObjectType (hlapi .ObjectIdentity ('SNMPv2-MIB' , 'sysDescr' , 0 )))) :
32
36
if errorIndication :
33
37
raise Exception (f"snmp error { errorIndication } " )
34
38
elif errorStatus :
@@ -51,7 +55,7 @@ def _get_ports(self):
51
55
Returns:
52
56
Dict[Dict[]]: ports and their values
53
57
"""
54
- from pysnmp import hlapi
58
+ import pysnmp . hlapi . v3arch . asyncio as hlapi
55
59
56
60
variables = [
57
61
(hlapi .ObjectType (hlapi .ObjectIdentity ('IF-MIB' , 'ifIndex' )), 'index' ),
@@ -64,14 +68,14 @@ def _get_ports(self):
64
68
]
65
69
ports = {}
66
70
67
- for (errorIndication , errorStatus , _ , varBindTable ) in hlapi .bulkCmd (
71
+ for (errorIndication , errorStatus , _ , varBindTable ) in self . loop . run_until_complete ( hlapi .bulkCmd (
68
72
hlapi .SnmpEngine (),
69
73
hlapi .CommunityData ('public' ),
70
- hlapi . UdpTransportTarget (( self .hostname , 161 )) ,
74
+ self .transport ,
71
75
hlapi .ContextData (),
72
76
0 , 20 ,
73
77
* [x [0 ] for x in variables ],
74
- lexicographicMode = False ):
78
+ lexicographicMode = False )) :
75
79
if errorIndication :
76
80
raise Exception (f"snmp error { errorIndication } " )
77
81
elif errorStatus :
@@ -93,18 +97,18 @@ def _get_fdb_dot1d(self):
93
97
Returns:
94
98
Dict[List[str]]: ports and their values
95
99
"""
96
- from pysnmp import hlapi
100
+ import pysnmp . hlapi . v3arch . asyncio as hlapi
97
101
98
102
ports = {}
99
103
100
- for (errorIndication , errorStatus , _ , varBindTable ) in hlapi .bulkCmd (
104
+ for (errorIndication , errorStatus , _ , varBindTable ) in self . loop . run_until_complete ( hlapi .bulkCmd (
101
105
hlapi .SnmpEngine (),
102
106
hlapi .CommunityData ('public' ),
103
- hlapi . UdpTransportTarget (( self .hostname , 161 )) ,
107
+ self .transport ,
104
108
hlapi .ContextData (),
105
109
0 , 50 ,
106
110
hlapi .ObjectType (hlapi .ObjectIdentity ('BRIDGE-MIB' , 'dot1dTpFdbPort' )),
107
- lexicographicMode = False ):
111
+ lexicographicMode = False )) :
108
112
if errorIndication :
109
113
raise Exception (f"snmp error { errorIndication } " )
110
114
elif errorStatus :
@@ -126,18 +130,18 @@ def _get_fdb_dot1q(self):
126
130
Returns:
127
131
Dict[List[str]]: ports and their values
128
132
"""
129
- from pysnmp import hlapi
133
+ import pysnmp . hlapi . v3arch . asyncio as hlapi
130
134
131
135
ports = {}
132
136
133
- for (errorIndication , errorStatus , _ , varBindTable ) in hlapi .bulkCmd (
137
+ for (errorIndication , errorStatus , _ , varBindTable ) in self . loop . run_until_complete ( hlapi .bulkCmd (
134
138
hlapi .SnmpEngine (),
135
139
hlapi .CommunityData ('public' ),
136
- hlapi . UdpTransportTarget (( self .hostname , 161 )) ,
140
+ self .transport ,
137
141
hlapi .ContextData (),
138
142
0 , 50 ,
139
143
hlapi .ObjectType (hlapi .ObjectIdentity ('Q-BRIDGE-MIB' , 'dot1qTpFdbPort' )),
140
- lexicographicMode = False ):
144
+ lexicographicMode = False )) :
141
145
if errorIndication :
142
146
raise Exception (f"snmp error { errorIndication } " )
143
147
elif errorStatus :
@@ -177,6 +181,9 @@ def update(self):
177
181
self .logger .debug ("updating macs by port" )
178
182
self ._update_macs ()
179
183
184
+ def deactivate (self ):
185
+ self .loop .close ()
186
+
180
187
181
188
@attr .s
182
189
class EthernetPortManager (ResourceManager ):
@@ -223,14 +230,16 @@ async def poll_neighbour(self):
223
230
224
231
await asyncio .sleep (1.0 )
225
232
233
+ self .loop = asyncio .get_event_loop ()
234
+
226
235
async def poll_switches (self ):
227
236
current = set (resource .switch for resource in self .resources )
228
237
removed = set (self .switches ) - current
229
238
new = current - set (self .switches )
230
239
for switch in removed :
231
240
del self .switches [switch ]
232
241
for switch in new :
233
- self .switches [switch ] = SNMPSwitch (switch )
242
+ self .switches [switch ] = SNMPSwitch (switch , self . loop )
234
243
for switch in current :
235
244
self .switches [switch ].update ()
236
245
await asyncio .sleep (1.0 )
@@ -248,7 +257,6 @@ async def poll(self, handler):
248
257
import traceback
249
258
traceback .print_exc (file = sys .stderr )
250
259
251
- self .loop = asyncio .get_event_loop ()
252
260
self .poll_tasks .append (self .loop .create_task (poll (self , poll_neighbour )))
253
261
self .poll_tasks .append (self .loop .create_task (poll (self , poll_switches )))
254
262
@@ -309,7 +317,6 @@ def poll(self):
309
317
resource .extra = extra
310
318
self .logger .debug ("new information for %s: %s" , resource , extra )
311
319
312
-
313
320
@target_factory .reg_resource
314
321
@attr .s
315
322
class SNMPEthernetPort (ManagedResource ):
0 commit comments