Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aruba AOS-CX Parser #172

Merged
merged 9 commits into from
Dec 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/dev/include_parser_list.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
| OS Name | Parser Class |
| ---------- | ------ |
| arista_eos | netutils.config.parser.EOSConfigParser |
| aruba_aoscx | netutils.config.parser.ArubaConfigParser |
lukebates123 marked this conversation as resolved.
Show resolved Hide resolved
| bigip_f5 | netutils.config.parser.F5ConfigParser |
| cisco_aireos | netutils.config.parser.AIREOSConfigParser |
| cisco_asa | netutils.config.parser.ASAConfigParser |
Expand Down
1 change: 1 addition & 0 deletions docs/user/lib_mapper/ansible.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
| NORMALIZED | | ANSIBLE |
| ---------- | -- | ------ |
| arista.eos.eos | → | arista_eos |
| arubanetworks.aoscx | → | aruba_aoscx |
| ciena.saos6.saos6 | → | ciena_saos |
| cisco.asa.asa | → | cisco_asa |
| cisco.ios.ios | → | cisco_ios |
Expand Down
1 change: 1 addition & 0 deletions docs/user/lib_mapper/ansible_reverse.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
| ANSIBLE | | NORMALIZED |
| ---------- | -- | ------ |
| arista_eos | → | arista.eos.eos |
| aruba_aoscx | → | arubanetworks.aoscx |
| ciena_saos | → | ciena.saos6.saos6 |
| cisco_asa | → | cisco.asa.asa |
| cisco_ios | → | cisco.ios.ios |
Expand Down
1 change: 1 addition & 0 deletions docs/user/lib_mapper/napalm.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
| NORMALIZED | | NAPALM |
| ---------- | -- | ------ |
| aoscx | → | aruba_aoscx |
| asa | → | cisco_asa |
| cisco_wlc_ssh | → | cisco_wlc |
| eos | → | arista_eos |
Expand Down
1 change: 1 addition & 0 deletions docs/user/lib_mapper/napalm_reverse.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
| NAPALM | | NORMALIZED |
| ---------- | -- | ------ |
| arista_eos | → | eos |
| aruba_aoscx | → | aoscx |
| brocade_vyos | → | vyos |
| cisco_asa | → | asa |
| cisco_ios | → | ios |
Expand Down
1 change: 1 addition & 0 deletions docs/user/lib_mapper/ntctemplates.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
| allied_telesis_awplus | → | allied_telesis_awplus |
| apresia_aeos | → | apresia_aeos |
| arista_eos | → | arista_eos |
| aruba_aoscx | → | aruba_aoscx |
| aruba_os | → | aruba_os |
| aruba_osswitch | → | aruba_osswitch |
| aruba_procurve | → | aruba_procurve |
Expand Down
1 change: 1 addition & 0 deletions docs/user/lib_mapper/ntctemplates_reverse.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
| allied_telesis_awplus | → | allied_telesis_awplus |
| apresia_aeos | → | apresia_aeos |
| arista_eos | → | arista_eos |
| aruba_aoscx | → | aruba_aoscx |
| aruba_os | → | aruba_os |
| aruba_osswitch | → | aruba_osswitch |
| aruba_procurve | → | aruba_procurve |
Expand Down
1 change: 1 addition & 0 deletions docs/user/lib_mapper/scrapli.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
| NORMALIZED | | SCRAPLI |
| ---------- | -- | ------ |
| arista_eos | → | arista_eos |
| aruba_aoscx | → | aruba_aoscx |
| cisco_iosxe | → | cisco_ios |
| cisco_iosxr | → | cisco_xr |
| cisco_nxos | → | cisco_nxos |
Expand Down
1 change: 1 addition & 0 deletions docs/user/lib_mapper/scrapli_reverse.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
| SCRAPLI | | NORMALIZED |
| ---------- | -- | ------ |
| arista_eos | → | arista_eos |
| aruba_aoscx | → | aruba_aoscx |
| cisco_ios | → | cisco_iosxe |
| cisco_nxos | → | cisco_nxos |
| cisco_xr | → | cisco_iosxr |
Expand Down
5 changes: 3 additions & 2 deletions netutils/config/compliance.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"fortinet_fortios": parser.FortinetConfigParser,
"nokia_sros": parser.NokiaConfigParser,
"citrix_netscaler": parser.NetscalerConfigParser,
"aruba_aoscx": parser.ArubaConfigParser,
}

# TODO: Once support for 3.7 is dropped, there should be a typing.TypedDict for this which should then also be used
Expand Down Expand Up @@ -277,8 +278,8 @@ def diff_network_config(compare_config: str, base_config: str, network_os: str)
for parent in line.parents:
if parent not in needed_lines:
needed_lines.append(parent)
needed_lines.append(line.config_line)

if line.config_line:
itdependsnetworks marked this conversation as resolved.
Show resolved Hide resolved
needed_lines.append(line.config_line)
return "\n".join(needed_lines)


Expand Down
90 changes: 90 additions & 0 deletions netutils/config/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -1184,3 +1184,93 @@ class NetscalerConfigParser(BaseSpaceConfigParser):
def banner_end(self) -> str:
"""Demarcate End of Banner char(s)."""
raise NotImplementedError("Netscaler platform doesn't have a banner.")


class ArubaConfigParser(BaseSpaceConfigParser):
"""Aruba AOS-CX implementation fo ConfigParser Class."""

banner_end = "!"
comment_chars = ["!"]

def __init__(self, config: str):
"""Create ConfigParser Object.

Args:
config (str): The config text to parse.
"""
super(ArubaConfigParser, self).__init__(config)

def _build_banner(self, config_line: str) -> t.Optional[str]:
"""Handle banner config lines.

Args:
config_line: The start of the banner config.

Returns:
The next configuration line in the configuration text or None when banner end is the end of the config text.

Raises:
ValueError: When the parser is unable to identify the End of the Banner.
"""
self._update_config_lines(config_line)
self._current_parents += (config_line,)
banner_config = []
for line in self.generator_config:
if not self.is_banner_end(line):
banner_config.append(line)
else:
banner_config.append(line)
line = "\n".join(banner_config)
self._update_config_lines(line)
self._current_parents = self._current_parents[:-1]
try:
return next(self.generator_config)
except StopIteration:
return None
raise ValueError("Unable to parse banner end.")

def _parse_out_comments(self, config: str) -> str:
"""Remove comments while retaining the banner end.

Args:
config (str): full config as a string.

Returns:
The non-comment lines from ``config``.
"""
# Aruba AOS-CX uses "!" as both comments and the banner delimiter.
lukebates123 marked this conversation as resolved.
Show resolved Hide resolved
# Even if another delimiter is used while creating the banner, show run changes the delimiter to use "!".
# We need to remove comments while retaining the banner delimiter.

config_lines = []
banner_started = False
banner_ended = False
for line in config.splitlines():
if self.is_banner_start(line):
banner_started = True
banner_ended = False
if line and banner_started and not banner_ended:
config_lines.append(line.rstrip())
if line.lstrip().startswith(self.banner_end):
banner_ended = True
banner_started = False
else:
if line and not self.is_comment(line):
config_lines.append(line.rstrip())
full_config = "\n".join(config_lines)
return full_config

@property
def config_lines_only(self) -> str:
jeffkala marked this conversation as resolved.
Show resolved Hide resolved
"""Remove spaces and unwanted lines from config lines.

Returns:
The non-space and non-comment lines from ``config``.
"""
if self._config is None:
config_lines = []
for line in self.config.splitlines():
if line and not line.isspace():
config_lines.append(line.rstrip())
self._config = self._parse_out_comments("\n".join(config_lines))
return self._config
8 changes: 8 additions & 0 deletions netutils/lib_mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
NTCTEMPLATES_LIB_MAPPER["watchguard_firebox"] = "watchguard_firebox"
NTCTEMPLATES_LIB_MAPPER["huawei_vrp"] = "huawei_vrp"
NTCTEMPLATES_LIB_MAPPER["vmware_nsxv"] = "vmware_nsxv"
NTCTEMPLATES_LIB_MAPPER["aruba_aoscx"] = "aruba_aoscx"

NAPALM_LIB_MAPPER = {
"asa": "cisco_asa",
Expand All @@ -138,6 +139,7 @@
"panos": "paloalto_panos",
"sros": "nokia_sros",
"vyos": "brocade_vyos",
"aoscx": "aruba_aoscx",
}

PYNTC_LIB_MAPPER = {
Expand Down Expand Up @@ -174,6 +176,7 @@
"community.network.icx": "ruckus_icx",
"community.network.sros": "nokia_sros",
"vyos.vyos.vyos": "vyos",
"arubanetworks.aoscx": "aruba_aoscx",
}

PYATS_LIB_MAPPER = {
Expand All @@ -196,6 +199,7 @@
"cisco_nxos": "cisco_nxos",
"arista_eos": "arista_eos",
"juniper_junos": "juniper_junos",
"aruba_aoscx": "aruba_aoscx",
}

NAPALM_LIB_MAPPER_REVERSE = {
Expand All @@ -211,6 +215,7 @@
"juniper_junos": "junos",
"paloalto_panos": "panos",
"nokia_sros": "sros",
"aruba_aoscx": "aoscx",
}

PYNTC_LIB_MAPPER_REVERSE = {
Expand Down Expand Up @@ -247,6 +252,7 @@
"pluribus": "community.network.netvisor",
"ruckus_icx": "community.network.icx",
"vyos": "vyos.vyos.vyos",
"aruba_aoscx": "arubanetworks.aoscx",
itdependsnetworks marked this conversation as resolved.
Show resolved Hide resolved
}

PYATS_LIB_MAPPER_REVERSE = {
Expand All @@ -268,6 +274,7 @@
"cisco_nxos": "cisco_nxos",
"arista_eos": "arista_eos",
"juniper_junos": "juniper_junos",
"aruba_aoscx": "aruba_aoscx",
}

# Deep copy the reverse, where there is no actual translation happening.
Expand All @@ -285,3 +292,4 @@
MAIN_LIB_MAPPER["ruckus_icx"] = "ruckus_icx"
MAIN_LIB_MAPPER["vmware_nsxv"] = "vmware_nsxv"
MAIN_LIB_MAPPER["watchguard_firebox"] = "watchguard_firebox"
MAIN_LIB_MAPPER["aruba_aoscx"] = "aruba_aoscx"
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
hostname spine-01
banner motd !
test motd banner
!
ntp server 10.20.1.9
ntp server 10.20.1.8
ntp server 10.20.1.7
!
access-list ip test
10 deny any 10.10.0.128/255.255.255.128 10.10.0.128/255.255.255.192
20 deny any 10.10.0.0/255.255.255.192 10.10.0.0/255.255.255.128
30 permit any any any
!
router bgp 65533
bgp router-id 10.22.0.2
maximum-paths 8
timers bgp 1 3
distance bgp 20 70
neighbor 10.20.1.10 remote-as 65533
neighbor 10.20.1.10 passive
address-family ipv4 unicast
neighbor 10.20.1.10 activate
neighbor 10.20.1.10 route-map test-01 in
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
features = [
{"name": "bgp", "ordered": True, "section": ["router bgp "]},
{"name": "ntp", "ordered": False, "section": ["ntp server "]},
{"name": "banner", "ordered": True, "section": ["banner "]},
{"name": "acl", "ordered": True, "section": ["access-list "]},
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
hostname spine-01
banner motd !
###############################################################################
This is a test banner
###############################################################################
!
banner exec !
###############################################################################
This is a test banner
###############################################################################
!
ntp server 10.20.1.7
ntp server 10.20.1.8
ntp server 10.20.1.9
!
access-list ip test
10 deny any 10.10.0.0/255.255.255.128 10.10.0.128/255.255.255.192
20 deny any 10.10.0.128/255.255.255.192 10.10.0.0/255.255.255.128
30 permit any any any
!
router bgp 65533
bgp router-id 10.22.0.2
maximum-paths 8
timers bgp 1 3
distance bgp 20 70
neighbor 10.20.1.9 remote-as 65533
neighbor 10.20.1.9 passive
address-family ipv4 unicast
neighbor 10.20.1.9 activate
neighbor 10.20.1.9 route-map test-01 in
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"bgp": {
"compliant": false,
"missing": "router bgp 65533\n neighbor 10.20.1.9 remote-as 65533\n neighbor 10.20.1.9 passive\n address-family ipv4 unicast\n neighbor 10.20.1.9 activate\n neighbor 10.20.1.9 route-map test-01 in",
"extra": "router bgp 65533\n neighbor 10.20.1.10 remote-as 65533\n neighbor 10.20.1.10 passive\n address-family ipv4 unicast\n neighbor 10.20.1.10 activate\n neighbor 10.20.1.10 route-map test-01 in",
"cannot_parse": true,
"unordered_compliant": false,
"ordered_compliant": false,
"actual": "router bgp 65533\n bgp router-id 10.22.0.2\n maximum-paths 8\n timers bgp 1 3\n distance bgp 20 70\n neighbor 10.20.1.10 remote-as 65533\n neighbor 10.20.1.10 passive\n address-family ipv4 unicast\n neighbor 10.20.1.10 activate\n neighbor 10.20.1.10 route-map test-01 in",
"intended": "router bgp 65533\n bgp router-id 10.22.0.2\n maximum-paths 8\n timers bgp 1 3\n distance bgp 20 70\n neighbor 10.20.1.9 remote-as 65533\n neighbor 10.20.1.9 passive\n address-family ipv4 unicast\n neighbor 10.20.1.9 activate\n neighbor 10.20.1.9 route-map test-01 in"
},
"ntp": {
"compliant": true,
"missing": "",
"extra": "",
"cannot_parse": true,
"unordered_compliant": true,
"ordered_compliant": false,
"actual": "ntp server 10.20.1.9\nntp server 10.20.1.8\nntp server 10.20.1.7",
"intended": "ntp server 10.20.1.7\nntp server 10.20.1.8\nntp server 10.20.1.9"
},
"banner": {
"compliant": false,
"missing": "banner motd !\n###############################################################################\nThis is a test banner\n###############################################################################\n!\nbanner exec !\n###############################################################################\nThis is a test banner\n###############################################################################\n!",
"extra": "banner motd !\ntest motd banner\n!",
"cannot_parse": true,
"unordered_compliant": false,
"ordered_compliant": false,
"actual": "banner motd !\ntest motd banner\n!",
"intended": "banner motd !\n###############################################################################\nThis is a test banner\n###############################################################################\n!\nbanner exec !\n###############################################################################\nThis is a test banner\n###############################################################################\n!"
},
"acl": {
"compliant": false,
"missing": "access-list ip test\n 10 deny any 10.10.0.0/255.255.255.128 10.10.0.128/255.255.255.192\n 20 deny any 10.10.0.128/255.255.255.192 10.10.0.0/255.255.255.128",
"extra": "access-list ip test\n 10 deny any 10.10.0.128/255.255.255.128 10.10.0.128/255.255.255.192\n 20 deny any 10.10.0.0/255.255.255.192 10.10.0.0/255.255.255.128",
"cannot_parse": true,
"unordered_compliant": false,
"ordered_compliant": false,
"actual": "access-list ip test\n 10 deny any 10.10.0.128/255.255.255.128 10.10.0.128/255.255.255.192\n 20 deny any 10.10.0.0/255.255.255.192 10.10.0.0/255.255.255.128\n 30 permit any any any",
"intended": "access-list ip test\n 10 deny any 10.10.0.0/255.255.255.128 10.10.0.128/255.255.255.192\n 20 deny any 10.10.0.128/255.255.255.192 10.10.0.0/255.255.255.128\n 30 permit any any any"
}
}
Loading