Skip to content

Commit b265e75

Browse files
committed
Merge pull request #219 from mirceaulinic/CF-SNMP
Add get_snmp_information() to JunOS, IOS-XR, NXOS & EOS
2 parents 1f8ec92 + 692b998 commit b265e75

File tree

16 files changed

+297
-2
lines changed

16 files changed

+297
-2
lines changed

.travis.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ script:
2424
- nosetests -v TestJunOSDriver:TestGetterJunOSDriver.test_get_interfaces_ip
2525
- nosetests -v TestJunOSDriver:TestGetterJunOSDriver.test_get_mac_address_table
2626
- nosetests -v TestJunOSDriver:TestGetterJunOSDriver.test_get_route_to
27+
- nosetests -v TestJunOSDriver:TestGetterJunOSDriver.test_get_snmp_information
2728
# testing eos getters
2829
- nosetests -v TestEOSDriver:TestGetterEOSDriver.test_get_bgp_config
2930
- nosetests -v TestEOSDriver:TestGetterEOSDriver.test_get_bgp_neighbors
@@ -40,6 +41,7 @@ script:
4041
- nosetests -v TestEOSDriver:TestGetterEOSDriver.test_get_interfaces_ip
4142
- nosetests -v TestEOSDriver:TestGetterEOSDriver.test_get_mac_address_table
4243
- nosetests -v TestEOSDriver:TestGetterEOSDriver.test_get_route_to
44+
- nosetests -v TestEOSDriver:TestGetterEOSDriver.test_get_snmp_information
4345
# testing iosxr getters
4446
- nosetests -v TestIOSXRDriver:TestGetterIOSXRDriver.test_get_bgp_config
4547
- nosetests -v TestIOSXRDriver:TestGetterIOSXRDriver.test_get_bgp_neighbors
@@ -55,6 +57,7 @@ script:
5557
- nosetests -v TestIOSXRDriver:TestGetterIOSXRDriver.test_get_interfaces_ip
5658
- nosetests -v TestIOSXRDriver:TestGetterIOSXRDriver.test_get_mac_address_table
5759
- nosetests -v TestIOSXRDriver:TestGetterIOSXRDriver.test_get_route_to
60+
- nosetests -v TestIOSXRDriver:TestGetterIOSXRDriver.test_get_snmp_information
5861
# testing nxos getters
5962
- nosetests -v TestNXOSDriver:TestGetterNXOSDriver.test_get_facts
6063
- nosetests -v TestNXOSDriver:TestGetterNXOSDriver.test_get_interfaces
@@ -64,13 +67,15 @@ script:
6467
- nosetests -v TestNXOSDriver:TestGetterNXOSDriver.test_get_ntp_peers
6568
- nosetests -v TestNXOSDriver:TestGetterNXOSDriver.test_get_interfaces_ip
6669
- nosetests -v TestNXOSDriver:TestGetterNXOSDriver.test_get_mac_address_table
70+
- nosetests -v TestNXOSDriver:TestGetterNXOSDriver.test_get_snmp_information
6771
# testing pluribus getters
6872
- nosetests -v TestPluribusDriver:TestGetterPluribusDriver.test_get_facts
6973
- nosetests -v TestPluribusDriver:TestGetterPluribusDriver.test_get_interfaces
7074
- nosetests -v TestPluribusDriver:TestGetterPluribusDriver.test_get_lldp_neighbors
7175
- nosetests -v TestPluribusDriver:TestGetterPluribusDriver.test_get_lldp_neighbors_detail
7276
- nosetests -v TestPluribusDriver:TestGetterPluribusDriver.test_get_ntp_peers
7377
- nosetests -v TestPluribusDriver:TestGetterPluribusDriver.test_get_mac_address_table
78+
- nosetests -v TestPluribusDriver:TestGetterPluribusDriver.test_get_snmp_information
7479
# testing ios getters
7580
- nosetests -v TestIOSDriver:TestGetterIOSDriver.test_get_bgp_neighbors
7681
- nosetests -v TestIOSDriver:TestGetterIOSDriver.test_get_environment

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
include requirements.txt
22
include napalm/utils/*.yml
33
include napalm/templates/*/*.j2
4+
include napalm/utils/textfsm_templates/*/*.tpl

docs/support/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ _ EOS JunOS IOS-XR FortiOS IBM NXOS I
7171
**get_environment** |yes| |yes| |yes| |yes| |no| |no| |yes| |no|
7272
**get_mac_address_table** |yes| |yes| |yes| |no| |no| |yes| |yes| |yes|
7373
**get_arp_table** |yes| |yes| |yes| |no| |no| |yes| |yes| |no|
74-
**get_snmp_information** |no| |no| |no| |no| |no| |no| |yes| |yes|
74+
**get_snmp_information** |yes| |yes| |yes| |no| |no| |yes| |yes| |yes|
7575
**get_ntp_peers** |yes| |yes| |yes| |no| |no| |yes| |yes| |yes|
7676
**get_interfaces_ip** |yes| |yes| |yes| |no| |no| |yes| |yes| |no|
7777
============================== ===== ===== ====== ======= ====== ====== ===== =========

napalm/base.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
import sys
1717
import jinja2
1818

19+
import textfsm
20+
1921
import napalm.exceptions
2022

2123

@@ -178,6 +180,54 @@ def load_template(self, template_name, template_vars):
178180

179181
self.load_merge_candidate(config=configuration)
180182

183+
def _textfsm_extractor(self, template_name, raw_text):
184+
185+
"""
186+
Will apply a TextFSM template over a raw text and return the matching table.
187+
Main usage of this method will be to extract data form a non-structured output
188+
from a network device and return the values in a table format.
189+
190+
:param template_name: Specifies the name of the template to be used
191+
:param raw_text: Text output as the devices prompts on the CLI
192+
"""
193+
194+
textfsm_data = list()
195+
196+
driver_name = self.__class__.__name__.replace('Driver', '')
197+
current_dir = os.path.dirname(os.path.abspath(__file__))
198+
template_path = '{current_dir}/utils/textfsm_templates/{driver_name}/{template_name}.tpl'.format(
199+
current_dir=current_dir,
200+
driver_name=driver_name.lower(),
201+
template_name=template_name
202+
)
203+
204+
try:
205+
fsm_handler = textfsm.TextFSM(open(template_path))
206+
except IOError:
207+
raise napalm.exceptions.TemplateNotImplemented(
208+
"TextFSM template {template_name} not defined!".format(
209+
template_name=template_name
210+
)
211+
)
212+
except textfsm.textfsm.TextFSMTemplateError:
213+
raise napalm.exceptions.TemplateRenderException(
214+
"Wrong format of template {template_name}".format(
215+
template_name=template_name
216+
)
217+
)
218+
219+
objects = fsm_handler.ParseText(raw_text)
220+
221+
for obj in objects:
222+
index = 0
223+
entry = {}
224+
for entry_value in obj:
225+
entry[fsm_handler.header[index].lower()] = str(entry_value)
226+
index += 1
227+
textfsm_data.append(entry)
228+
229+
return textfsm_data
230+
181231
def get_facts(self):
182232
"""
183233
Returns a dictionary containing the following information:

napalm/eos.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,3 +1008,34 @@ def get_route_to(self, destination = '', protocol = ''):
10081008
routes[prefix].append(route_next_hop)
10091009

10101010
return routes
1011+
1012+
def get_snmp_information(self):
1013+
1014+
snmp_information = dict()
1015+
1016+
commands = list()
1017+
commands.append('show running-config | section snmp-server')
1018+
raw_snmp_config = self.device.run_commands(commands, encoding = 'text')[0].get('output', '')
1019+
1020+
snmp_config = self._textfsm_extractor('snmp_config', raw_snmp_config)
1021+
1022+
if not snmp_config:
1023+
return snmp_information
1024+
1025+
snmp_information = {
1026+
'contact' : unicode(snmp_config[0].get('contact', '')),
1027+
'location' : unicode(snmp_config[0].get('location', '')),
1028+
'chassis_id': unicode(snmp_config[0].get('chassis_id', '')),
1029+
'community' : {}
1030+
}
1031+
1032+
for snmp_entry in snmp_config:
1033+
community_name = unicode(snmp_entry.get('community', ''))
1034+
if not community_name:
1035+
continue
1036+
snmp_information['community'][community_name] = {
1037+
'acl': unicode(snmp_entry.get('acl', '')),
1038+
'mode': unicode(snmp_entry.get('mode', 'ro').lower())
1039+
}
1040+
1041+
return snmp_information

napalm/iosxr.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,3 +1297,34 @@ def get_route_to(self, destination = '', protocol = ''):
12971297
first_route = False
12981298

12991299
return routes
1300+
1301+
def get_snmp_information(self):
1302+
1303+
snmp_information = dict()
1304+
1305+
snmp_rpc_command = '<Get><Configuration><SNMP></SNMP></Configuration></Get>'
1306+
1307+
snmp_result_tree = ET.fromstring(self.device.make_rpc_call(snmp_rpc_command))
1308+
1309+
_PRIVILEGE_MODE_MAP_ = {
1310+
'ReadOnly': u'ro',
1311+
'ReadWrite': u'rw'
1312+
}
1313+
1314+
snmp_information = {
1315+
'chassis_id': unicode(self._find_txt(snmp_result_tree, './/ChassisID')),
1316+
'contact': unicode(self._find_txt(snmp_result_tree, './/Contact')),
1317+
'location': unicode(self._find_txt(snmp_result_tree, './/Location')),
1318+
'community': {}
1319+
}
1320+
1321+
for community in snmp_result_tree.iter('DefaultCommunity'):
1322+
name = unicode(self._find_txt(community, 'Naming/CommunityName'))
1323+
privilege = self._find_txt(community, 'Priviledge')
1324+
acl = unicode(self._find_txt(community, 'AccessList'))
1325+
snmp_information['community'][name] = {
1326+
'mode': _PRIVILEGE_MODE_MAP_.get(privilege, u''),
1327+
'acl' : acl
1328+
}
1329+
1330+
return snmp_information

napalm/junos.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,8 @@ def cli(self, commands = None):
404404

405405
@staticmethod
406406
def _convert(to, who, default = u''):
407+
if who is None:
408+
return default
407409
try:
408410
return to(who)
409411
except:
@@ -923,3 +925,44 @@ def get_route_to(self, destination = '', protocol = ''):
923925
routes[destination].append(d)
924926

925927
return routes
928+
929+
def get_snmp_information(self):
930+
931+
snmp_information = dict()
932+
933+
_AUTHORIZATION_MODE_MAP_ = {
934+
'read-only': u'ro',
935+
'read-write': u'rw'
936+
}
937+
938+
snmp_config = junos_views.junos_snmp_config_table(self.device)
939+
snmp_config.get()
940+
snmp_items = snmp_config.items()
941+
942+
if not snmp_items:
943+
return snmp_information
944+
945+
communities = list()
946+
for snmp_config_out in snmp_items:
947+
community_name = snmp_config_out[0]
948+
community_details = snmp_config_out[1]
949+
communities.append({
950+
c[0]: c[1] for c in community_details
951+
})
952+
953+
snmp_information = {
954+
'contact': self._convert(unicode, communities[0].get('contact')),
955+
'location': self._convert(unicode, communities[0].get('location')),
956+
'chassis_id': self._convert(unicode, communities[0].get('chassis')),
957+
'community': {}
958+
}
959+
960+
for snmp_entry in communities:
961+
name = self._convert(unicode, snmp_entry.get('name'))
962+
authorization = self._convert(unicode, snmp_entry.get('authorization'))
963+
snmp_information['community'][name] = {
964+
'mode': _AUTHORIZATION_MODE_MAP_.get(authorization, u''),
965+
'acl': u''
966+
}
967+
968+
return snmp_information

napalm/nxos.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,3 +514,34 @@ def get_mac_address_table(self):
514514
)
515515

516516
return mac_table
517+
518+
def get_snmp_information(self):
519+
520+
snmp_information = dict()
521+
522+
snmp_command = 'show running-config | section snmp-server'
523+
524+
snmp_raw_output = self.cli([snmp_command]).get(snmp_command, '')
525+
526+
snmp_config = self._textfsm_extractor('snmp_config', snmp_raw_output)
527+
528+
if not snmp_config:
529+
return snmp_information
530+
531+
snmp_information = {
532+
'contact' : unicode(snmp_config[0].get('contact', '')),
533+
'location' : unicode(snmp_config[0].get('location', '')),
534+
'chassis_id': unicode(snmp_config[0].get('chassis_id', '')),
535+
'community' : {}
536+
}
537+
538+
for snmp_entry in snmp_config:
539+
community_name = unicode(snmp_entry.get('community', ''))
540+
if not community_name:
541+
continue
542+
snmp_information['community'][community_name] = {
543+
'acl': unicode(snmp_entry.get('acl', '')),
544+
'mode': unicode(snmp_entry.get('mode', '').lower())
545+
}
546+
547+
return snmp_information

napalm/pluribus.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ def get_snmp_information(self):
260260
for snmp_line in snmp_lines:
261261
snmp_line_details = snmp_line.split(';')
262262
snmp_community = unicode(snmp_line_details[1])
263-
snmp_mode = _SNMP_MODE_MAP_.get(snmp_line_details[1])
263+
snmp_mode = _SNMP_MODE_MAP_.get(snmp_line_details[2], u'ro')
264264
snmp_acl = u''
265265
snmp_information['community'][snmp_community] = {
266266
'acl' : snmp_acl,

napalm/utils/junos_views.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,3 +458,19 @@ junos_route_table_view:
458458
### ISIS Specific fields
459459
###
460460
level: {../rt-isis-level: int}
461+
462+
###
463+
### SNMP Config
464+
###
465+
466+
junos_snmp_config_table:
467+
get: snmp/community
468+
view: junos_snmp_config_view
469+
470+
junos_snmp_config_view:
471+
fields:
472+
name: name
473+
authorization: authorization
474+
location: ../location
475+
contact: ../contact
476+
chassis: ../system-name

0 commit comments

Comments
 (0)