diff --git a/napalm_eos/eos.py b/napalm_eos/eos.py index e7accf0..011c58b 100644 --- a/napalm_eos/eos.py +++ b/napalm_eos/eos.py @@ -59,6 +59,9 @@ class EOSDriver(NetworkDriver): _RE_BGP_DESC = re.compile('\s+Description: (?P.*?)') _RE_BGP_LOCAL = re.compile('Local AS is (?P.*?),.*') _RE_BGP_PREFIX = re.compile('(\s*?)(?PIPv[46]) Unicast:\s*(?P\d+)\s*(?P\d+)') # noqa + _RE_SNMP_COMM = re.compile(r"""^snmp-server\s+community\s+(?P\S+) + (\s+view\s+(?P\S+))?(\s+(?Pro|rw)?) + (\s+ipv6\s+(?P\S+))?(\s+(?P\S+))?$""", re.VERBOSE) def __init__(self, hostname, username, password, timeout=60, optional_args=None): """Constructor.""" @@ -1090,35 +1093,42 @@ def get_route_to(self, destination='', protocol=''): return routes def get_snmp_information(self): + """get_snmp_information() for EOS. Re-written to not use TextFSM""" - snmp_information = dict() - - commands = list() - commands.append('show running-config | section snmp-server') - raw_snmp_config = self.device.run_commands(commands, encoding='text')[0].get('output', '') - - snmp_config = napalm_base.helpers.textfsm_extractor(self, 'snmp_config', raw_snmp_config) - - if not snmp_config: - return snmp_information - - snmp_information = { - 'contact': py23_compat.text_type(snmp_config[0].get('contact', '')), - 'location': py23_compat.text_type(snmp_config[0].get('location', '')), - 'chassis_id': py23_compat.text_type(snmp_config[0].get('chassis_id', '')), + # Default values + snmp_dict = { + 'chassis_id': '', + 'location': '', + 'contact': '', 'community': {} } - for snmp_entry in snmp_config: - community_name = py23_compat.text_type(snmp_entry.get('community', '')) - if not community_name: - continue - snmp_information['community'][community_name] = { - 'acl': py23_compat.text_type(snmp_entry.get('acl', '')), - 'mode': py23_compat.text_type(snmp_entry.get('mode', 'ro').lower()) - } + commands = [ + 'show snmp chassis', + 'show snmp location', + 'show snmp contact' + ] + snmp_config = self.device.run_commands(commands, encoding='json') + for line in snmp_config: + for k, v in line.items(): + if k == 'chassisId': + snmp_dict['chassis_id'] = v + else: + # Some EOS versions add extra quotes + snmp_dict[k] = v.strip('"') + + commands = ['show running-config | section snmp-server community'] + raw_snmp_config = self.device.run_commands(commands, encoding='text')[0].get('output', '') + for line in raw_snmp_config.splitlines(): + match = self._RE_SNMP_COMM.search(line) + if match: + matches = match.groupdict('') + snmp_dict['community'][match.group('community')] = { + 'acl': py23_compat.text_type(matches['v4_acl']), + 'mode': py23_compat.text_type(matches['access']) + } - return snmp_information + return snmp_dict def get_users(self): diff --git a/napalm_eos/templates/delete_snmp_config.j2 b/napalm_eos/templates/delete_snmp_config.j2 index 0543dfe..615f1aa 100644 --- a/napalm_eos/templates/delete_snmp_config.j2 +++ b/napalm_eos/templates/delete_snmp_config.j2 @@ -8,7 +8,11 @@ no snmp-server contact "{{contact}}" no snmp-server chassis-id "{{chassis_id}}" {% endif %} {% if (community is defined) and community %} +{%- if community is mapping -%} {% for comm_name, comm_details in community.iteritems() %} -no community {{comm_name}} +no snmp-server community {{comm_name}} {% endfor %} +{%- elif community is string -%} +no snmp-server community {{community}} +{%- endif -%} {% endif %} diff --git a/napalm_eos/templates/delete_users.j2 b/napalm_eos/templates/delete_users.j2 new file mode 100644 index 0000000..772033f --- /dev/null +++ b/napalm_eos/templates/delete_users.j2 @@ -0,0 +1,16 @@ +{%- for user_name, user_details in users.items() %} +{%- if user_details %} +{%- if user_details.get('password') %} +username {{user_name}} nopassword +{%- if user_details.get('level') %} +no username {{user_name}} privilege {{user_details.level}} +{%- endif %} +{%- if user_details.get('sshkeys') %} +{%- for sshkey in user_details.sshkeys %} +no username {{user_name}} sshkey {{ sshkey }} +{%- endfor %} +{%- endif %} +{%- else %} +no username {{user_name}} +{%- endif %} +{%- endfor %} diff --git a/napalm_eos/templates/set_users.j2 b/napalm_eos/templates/set_users.j2 new file mode 100644 index 0000000..bb57ca8 --- /dev/null +++ b/napalm_eos/templates/set_users.j2 @@ -0,0 +1,15 @@ +{%- for user_name, user_details in users.items() %} +{%- if user_details.get('password') %} +username {{ user_name }} secret {{ user_details.password }} +{%- else %} +username {{ user_name }} nopassword +{%- endif %} +{%- if user_details.get('level') %} +username {{ user_name }} privilege {{ user_details.level }} +{%- endif %} +{%- if user_details.get('sshkeys') %} +{%- for sshkey in user_details.sshkeys %} +username {{ user_name }} sshkey {{ sshkey }} +{%- endfor %} +{%- endif %} +{%- endfor %} diff --git a/setup.py b/setup.py index b14324a..b7223b4 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ setup( name="napalm-eos", - version="0.5.1", + version="0.5.2", packages=find_packages(), author="David Barroso, Mircea Ulinic", author_email="dbarrosop@dravetech.com, mircea@cloudflare.com", diff --git a/test/unit/mocked_data/test_get_snmp_information/normal/expected_result.json b/test/unit/mocked_data/test_get_snmp_information/normal/expected_result.json index 6a7a651..4cb766c 100644 --- a/test/unit/mocked_data/test_get_snmp_information/normal/expected_result.json +++ b/test/unit/mocked_data/test_get_snmp_information/normal/expected_result.json @@ -1 +1 @@ -{"community": {"tryagain": {"mode": "", "acl": ""}, "hackme": {"mode": "ro", "acl": "ifyoucan"}}, "contact": "noc@cloudflare.com", "location": "Marseille, France", "chassis_id": "edge02.mrs01"} \ No newline at end of file +{"community": {"basic": {"mode": "ro", "acl": ""}, "private": {"mode": "rw", "acl": ""}, "test-view": {"mode": "ro", "acl": ""}, "test-ipv4-acl": {"mode": "ro", "acl": "ipv4-ext-acl"}, "test-num-acl": {"mode": "ro", "acl": "11"}, "complex": {"mode": "ro", "acl": "ipv4-std-acl"}}, "contact": "noc@cloudflare.com", "location": "Marseille, France", "chassis_id": "edge02.mrs01"} diff --git a/test/unit/mocked_data/test_get_snmp_information/normal/show_running_config___section_snmp_server.text b/test/unit/mocked_data/test_get_snmp_information/normal/show_running_config___section_snmp_server.text deleted file mode 100644 index a00d690..0000000 --- a/test/unit/mocked_data/test_get_snmp_information/normal/show_running_config___section_snmp_server.text +++ /dev/null @@ -1,5 +0,0 @@ -snmp-server contact noc@cloudflare.com -snmp-server location Marseille, France -snmp-server chassis-id edge02.mrs01 -snmp-server community hackme ro ifyoucan -snmp-server community tryagain group not-enough diff --git a/test/unit/mocked_data/test_get_snmp_information/normal/show_running_config___section_snmp_server_community.text b/test/unit/mocked_data/test_get_snmp_information/normal/show_running_config___section_snmp_server_community.text new file mode 100644 index 0000000..13babf0 --- /dev/null +++ b/test/unit/mocked_data/test_get_snmp_information/normal/show_running_config___section_snmp_server_community.text @@ -0,0 +1,6 @@ +snmp-server community basic ro +snmp-server community private rw +snmp-server community test-view view view-name ro +snmp-server community test-ipv4-acl ro ipv4-ext-acl +snmp-server community test-num-acl ro 11 +snmp-server community complex ro ipv6 ipv6-acl ipv4-std-acl diff --git a/test/unit/mocked_data/test_get_snmp_information/normal/show_snmp_chassis.json b/test/unit/mocked_data/test_get_snmp_information/normal/show_snmp_chassis.json new file mode 100644 index 0000000..1c06292 --- /dev/null +++ b/test/unit/mocked_data/test_get_snmp_information/normal/show_snmp_chassis.json @@ -0,0 +1,3 @@ +{ + "chassisId": "edge02.mrs01" +} diff --git a/test/unit/mocked_data/test_get_snmp_information/normal/show_snmp_contact.json b/test/unit/mocked_data/test_get_snmp_information/normal/show_snmp_contact.json new file mode 100644 index 0000000..bbbaf01 --- /dev/null +++ b/test/unit/mocked_data/test_get_snmp_information/normal/show_snmp_contact.json @@ -0,0 +1,3 @@ +{ + "contact": "noc@cloudflare.com" +} diff --git a/test/unit/mocked_data/test_get_snmp_information/normal/show_snmp_location.json b/test/unit/mocked_data/test_get_snmp_information/normal/show_snmp_location.json new file mode 100644 index 0000000..c61dffd --- /dev/null +++ b/test/unit/mocked_data/test_get_snmp_information/normal/show_snmp_location.json @@ -0,0 +1,3 @@ +{ + "location": "Marseille, France" +}