From 69bdff48a507956b975c3d831c4af2ada880008f Mon Sep 17 00:00:00 2001 From: Joe Wesch Date: Wed, 14 Jan 2026 10:52:53 -0600 Subject: [PATCH 1/5] Added HP full config parsing --- changes/+class.deprecated | 1 + changes/752.added | 1 + docs/dev/include_parser_list.md | 2 +- netutils/config/compliance.py | 2 +- netutils/config/parser.py | 90 ++++- netutils/config/utils.py | 42 +++ .../hp_comware/hp_comware_full_received.py | 320 ++++++++++++++++++ .../base/hp_comware/hp_comware_full_sent.txt | 287 ++++++++++++++++ .../hp_comware/hp_comware_special_received.py | 65 ++++ .../hp_comware/hp_comware_special_sent.txt | 37 ++ tests/unit/test_deprecation.py | 16 + 11 files changed, 853 insertions(+), 10 deletions(-) create mode 100644 changes/+class.deprecated create mode 100644 changes/752.added create mode 100644 tests/unit/mock/config/parser/base/hp_comware/hp_comware_full_received.py create mode 100644 tests/unit/mock/config/parser/base/hp_comware/hp_comware_full_sent.txt create mode 100644 tests/unit/mock/config/parser/base/hp_comware/hp_comware_special_received.py create mode 100644 tests/unit/mock/config/parser/base/hp_comware/hp_comware_special_sent.txt create mode 100644 tests/unit/test_deprecation.py diff --git a/changes/+class.deprecated b/changes/+class.deprecated new file mode 100644 index 00000000..f54ad14a --- /dev/null +++ b/changes/+class.deprecated @@ -0,0 +1 @@ +Deprecated the redundant HPComwareConfigParser class in lieu of the HPEConfigParser class and updated the compliance parser_map accordingly. \ No newline at end of file diff --git a/changes/752.added b/changes/752.added new file mode 100644 index 00000000..eae143e4 --- /dev/null +++ b/changes/752.added @@ -0,0 +1 @@ +Added custom parsing of HP Network OS devices. \ No newline at end of file diff --git a/docs/dev/include_parser_list.md b/docs/dev/include_parser_list.md index 11a3b4e4..fc74e6c7 100644 --- a/docs/dev/include_parser_list.md +++ b/docs/dev/include_parser_list.md @@ -13,7 +13,7 @@ | citrix_netscaler | netutils.config.parser.NetscalerConfigParser | | extreme_netiron | netutils.config.parser.NetironConfigParser | | fortinet_fortios | netutils.config.parser.FortinetConfigParser | -| hp_comware | netutils.config.parser.HPComwareConfigParser | +| hp_comware | netutils.config.parser.HPEConfigParser | | juniper_junos | netutils.config.parser.JunosConfigParser | | linux | netutils.config.parser.LINUXConfigParser | | mikrotik_routeros | netutils.config.parser.RouterOSConfigParser | diff --git a/netutils/config/compliance.py b/netutils/config/compliance.py index 3990334a..049cfdd7 100644 --- a/netutils/config/compliance.py +++ b/netutils/config/compliance.py @@ -20,7 +20,7 @@ "citrix_netscaler": parser.NetscalerConfigParser, "extreme_netiron": parser.NetironConfigParser, "fortinet_fortios": parser.FortinetConfigParser, - "hp_comware": parser.HPComwareConfigParser, + "hp_comware": parser.HPEConfigParser, "juniper_junos": parser.JunosConfigParser, "linux": parser.LINUXConfigParser, "mikrotik_routeros": parser.RouterOSConfigParser, diff --git a/netutils/config/parser.py b/netutils/config/parser.py index e08dd690..0e732279 100644 --- a/netutils/config/parser.py +++ b/netutils/config/parser.py @@ -8,6 +8,7 @@ from netutils.banner import normalise_delimiter_caret_c from netutils.config.conversion import paloalto_panos_brace_to_set +from netutils.config.utils import _deprecated ConfigLine = namedtuple("ConfigLine", "config_line,parents") @@ -1678,7 +1679,9 @@ def config_lines_only(self) -> str: class HPEConfigParser(BaseSpaceConfigParser): """HPE Implementation of ConfigParser Class.""" - regex_banner = re.compile(r"^header\s(\w+)\s+(?P\^C|\S?)") + regex_banner = re.compile(r"^\s*header\s(\w+)\s+(?P\^C|\S?)") + banner_start: t.List[str] = ["header "] + comment_chars: t.List[str] = ["#"] def __init__(self, config: str): """Initialize the HPEConfigParser object.""" @@ -1686,6 +1689,81 @@ def __init__(self, config: str): self._banner_end: t.Optional[str] = None super(HPEConfigParser, self).__init__(config) + @property + def config_lines_only(self) -> str: + """Remove spaces and unwanted lines from config lines, but leave comments. + + Returns: + The non-space lines from ``config``. + """ + if self._config is None: + config_lines = (line.rstrip() for line in self.config.splitlines() if line and not line.isspace()) + self._config = "\n".join(config_lines) + return self._config + + def build_config_relationship(self) -> t.List[ConfigLine]: + r"""This is a custom build method for HPE Network OS. + + HP config is a bit different from other network operating systems. + It uses comments (#) to demarcate sections of the config. + Each new section that starts without a leading space is a new section. + That new section may or may not have children. + Each config line that has a leading space but not a parent is just a single config line. + Single lines that have leading spaces also sometimes differs between models (e.g., 59XX vs 79XX series). + + Examples: + >>> from netutils.config.parser import HPEConfigParser, ConfigLine + >>> config = '''# + ... version 7.1.045, Release 2418P06 + ... # + ... sysname NTC123456 + ... # + ... vlan 101 + ... name Test-Vlan-101 + ... description Test Vlan 101 + ... #''' + >>> config_tree = HPEConfigParser(config) + >>> config_tree.build_config_relationship() == \ + ... [ + ... ConfigLine(config_line="version 7.1.045, Release 2418P06", parents=()), + ... ConfigLine(config_line=" sysname NTC123456", parents=()), + ... ConfigLine(config_line="vlan 101", parents=()), + ... ConfigLine(config_line=" name Test-Vlan-101", parents=("vlan 101",)), + ... ConfigLine(config_line=" description Test Vlan 101", parents=("vlan 101",)), + ... ] + True + >>> + """ + new_section = True + for line in self.generator_config: + if line.startswith(tuple(self.comment_chars)): + # Closing any previous sections + self._current_parents = () + self.indent_level = 0 + new_section = True + continue + if line.strip().startswith(tuple(self.comment_chars)): + # Just ignore comments inside sections + continue + if self.is_banner_start(line): + # Special case for banners + self._build_banner(line) + continue + + current_spaces = self.get_leading_space_count(line) if line[0].isspace() else 0 + if current_spaces == 0: + new_section = True + if current_spaces > self.indent_level and not new_section: + previous_config = self.config_lines[-1] + self._current_parents += (previous_config.config_line,) + elif current_spaces < self.indent_level: + self._current_parents = self._remove_parents(line, current_spaces) + + new_section = False + self.indent_level = current_spaces + self._update_config_lines(line) + return self.config_lines + def _build_banner(self, config_line: str) -> t.Optional[str]: """ Builds a banner configuration based on the given config_line. @@ -1763,16 +1841,12 @@ def banner_end(self, banner_start_line: str) -> None: self._banner_end = self.delimiter +@_deprecated( + "HPComwareConfigParser is deprecated and will be removed in a future version. Use HPEConfigParser instead." +) class HPComwareConfigParser(HPEConfigParser, BaseSpaceConfigParser): """HP Comware Implementation of ConfigParser Class.""" - banner_start: t.List[str] = ["header "] - comment_chars: t.List[str] = ["#"] - - def _build_banner(self, config_line: str) -> t.Optional[str]: - """Build a banner from the given config line.""" - return super(HPComwareConfigParser, self)._build_banner(config_line) - class NvidiaOnyxConfigParser(BaseConfigParser): # pylint: disable=abstract-method """Nvidia Onyx config parser.""" diff --git a/netutils/config/utils.py b/netutils/config/utils.py index a153d48a..9f959f6e 100644 --- a/netutils/config/utils.py +++ b/netutils/config/utils.py @@ -1,5 +1,9 @@ """Utility functions for working with device configurations.""" +import typing as t +import warnings +from functools import wraps + def _open_file_config(cfg_path: str) -> str: """Open config file from local disk.""" @@ -8,3 +12,41 @@ def _open_file_config(cfg_path: str) -> str: device_cfg = filehandler.read() return device_cfg.strip() + + +def _deprecated(custom_message: t.Optional[str] = None) -> t.Callable[[t.Any], t.Any]: + """Deprecate a function or class. + + Args: + custom_message: Custom deprecation message. If None, uses default message. + + Returns: + Decorator function that issues a deprecation warning when the decorated item is used. + """ + if custom_message is None: + custom_message = "This function or class is deprecated and will be removed in a future version." + + def decorator(obj: t.Any) -> t.Any: + """Decorator that wraps a class or function to issue deprecation warning.""" + if isinstance(obj, type): + # For classes, wrap __init__ to issue warning on instantiation + original_init = getattr(obj, "__init__", None) + if original_init is None: + return obj + + def __init__(self: t.Any, *args: t.Any, **kwargs: t.Any) -> None: + warnings.warn(custom_message, DeprecationWarning, stacklevel=2) + original_init(self, *args, **kwargs) + + setattr(obj, "__init__", __init__) + return obj + + # For functions, wrap the function + @wraps(obj) + def wrapper(*args: t.Any, **kwargs: t.Any) -> t.Any: + warnings.warn(custom_message, DeprecationWarning, stacklevel=2) + return obj(*args, **kwargs) + + return wrapper + + return decorator diff --git a/tests/unit/mock/config/parser/base/hp_comware/hp_comware_full_received.py b/tests/unit/mock/config/parser/base/hp_comware/hp_comware_full_received.py new file mode 100644 index 00000000..eef90547 --- /dev/null +++ b/tests/unit/mock/config/parser/base/hp_comware/hp_comware_full_received.py @@ -0,0 +1,320 @@ +from netutils.config.parser import ConfigLine + +data = [ + ConfigLine(config_line="version 7.1.045, Release 2418P06", parents=()), + ConfigLine(config_line=" sysname NTC123456", parents=()), + ConfigLine(config_line=" clock timezone EST minus 05:00:00", parents=()), + ConfigLine( + config_line=" clock summer-time EDT 02:00:00 03/11 02:00:00 11/04 01:00:00", + parents=(), + ), + ConfigLine(config_line=" clock protocol ntp", parents=()), + ConfigLine(config_line=" undo copyright-info enable", parents=()), + ConfigLine(config_line="ip vpn-instance vpn1", parents=()), + ConfigLine(config_line=" route-distinguisher 65001:1", parents=("ip vpn-instance vpn1",)), + ConfigLine(config_line=" description vpn1", parents=("ip vpn-instance vpn1",)), + ConfigLine(config_line=" vpn-target 65001:1 import-extcommunity", parents=("ip vpn-instance vpn1",)), + ConfigLine(config_line=" vpn-target 65001:1 export-extcommunity", parents=("ip vpn-instance vpn1",)), + ConfigLine(config_line="ip vpn-instance internal", parents=()), + ConfigLine(config_line=" route-distinguisher 1:1", parents=("ip vpn-instance internal",)), + ConfigLine(config_line=" description internal", parents=("ip vpn-instance internal",)), + ConfigLine(config_line=" telnet server enable", parents=()), + ConfigLine(config_line=" telnet server acl 1111", parents=()), + ConfigLine(config_line=" irf domain 123456", parents=()), + ConfigLine(config_line=" irf mac-address persistent timer", parents=()), + ConfigLine(config_line=" irf auto-update enable", parents=()), + ConfigLine(config_line=" undo irf link-delay", parents=()), + ConfigLine(config_line=" irf member 1 priority 32", parents=()), + ConfigLine(config_line=" irf member 2 priority 1", parents=()), + ConfigLine(config_line=" irf mode normal", parents=()), + ConfigLine(config_line="igmp-snooping", parents=()), + ConfigLine(config_line=" dns source-interface M-GigabitEthernet0/0/0 vpn-instance internal", parents=()), + ConfigLine(config_line=" dns domain example.com", parents=()), + ConfigLine(config_line=" dns domain example.com vpn-instance internal", parents=()), + ConfigLine(config_line=" dns server 192.0.2.47 vpn-instance internal", parents=()), + ConfigLine(config_line=" dns server 192.0.2.15 vpn-instance internal", parents=()), + ConfigLine(config_line=" dns server 192.0.2.11 vpn-instance internal", parents=()), + ConfigLine(config_line=" dns server 192.0.2.2 vpn-instance internal", parents=()), + ConfigLine(config_line=" dns server 192.0.2.6 vpn-instance internal", parents=()), + ConfigLine(config_line=" lldp global enable", parents=()), + ConfigLine(config_line=" system-working-mode standard", parents=()), + ConfigLine(config_line=" password-recovery enable", parents=()), + ConfigLine(config_line="vlan 1", parents=()), + ConfigLine(config_line="vlan 101", parents=()), + ConfigLine(config_line=" name Test-Vlan-101", parents=("vlan 101",)), + ConfigLine(config_line=" description Test Vlan 101", parents=("vlan 101",)), + ConfigLine(config_line="irf-port 1/1", parents=()), + ConfigLine(config_line=" port group interface FortyGigE1/0/49", parents=("irf-port 1/1",)), + ConfigLine(config_line=" port group interface FortyGigE1/0/50", parents=("irf-port 1/1",)), + ConfigLine(config_line="irf-port 2/2", parents=()), + ConfigLine(config_line=" port group interface FortyGigE2/0/49", parents=("irf-port 2/2",)), + ConfigLine(config_line=" port group interface FortyGigE2/0/50", parents=("irf-port 2/2",)), + ConfigLine(config_line="qos map-table dot1p-lp", parents=()), + ConfigLine(config_line=" import 0 export 0", parents=("qos map-table dot1p-lp",)), + ConfigLine(config_line=" import 1 export 1", parents=("qos map-table dot1p-lp",)), + ConfigLine(config_line=" import 2 export 2", parents=("qos map-table dot1p-lp",)), + ConfigLine(config_line="traffic classifier NTC-Classifier operator or", parents=()), + ConfigLine(config_line=" if-match dscp ntc", parents=("traffic classifier NTC-Classifier operator or",)), + ConfigLine(config_line=" if-match acl 4000", parents=("traffic classifier NTC-Classifier operator or",)), + ConfigLine(config_line="traffic behavior NTC-Behavior", parents=()), + ConfigLine(config_line=" remark dscp ntc", parents=("traffic behavior NTC-Behavior",)), + ConfigLine(config_line="traffic behavior foo", parents=()), + ConfigLine(config_line="qos policy NTC-Policy", parents=()), + ConfigLine(config_line=" classifier NTC-Classifier behavior NTC-Behavior", parents=("qos policy NTC-Policy",)), + ConfigLine(config_line="stp region-configuration", parents=()), + ConfigLine(config_line=" region-name NTC-Region", parents=("stp region-configuration",)), + ConfigLine(config_line=" revision-level 100", parents=("stp region-configuration",)), + ConfigLine(config_line=" instance 1 vlan 1 to 4094", parents=("stp region-configuration",)), + ConfigLine(config_line=" active region-configuration", parents=("stp region-configuration",)), + ConfigLine(config_line=" stp instance 0 to 1 priority 16384", parents=()), + ConfigLine(config_line=" stp vlan 1 to 4094 priority 16384", parents=()), + ConfigLine(config_line=" stp mode pvst", parents=()), + ConfigLine(config_line=" stp bpdu-protection", parents=()), + ConfigLine(config_line=" stp global enable", parents=()), + ConfigLine(config_line=" l2vpn enable", parents=()), + ConfigLine(config_line="interface NULL0", parents=()), + ConfigLine(config_line="interface LoopBack1", parents=()), + ConfigLine(config_line=" ip binding vpn-instance internal", parents=("interface LoopBack1",)), + ConfigLine(config_line=" ip address 192.0.2.1 255.255.255.255", parents=("interface LoopBack1",)), + ConfigLine(config_line="interface Vlan-interface102", parents=()), + ConfigLine(config_line=" shutdown", parents=("interface Vlan-interface102",)), + ConfigLine(config_line=" ip binding vpn-instance vpn2", parents=("interface Vlan-interface102",)), + ConfigLine(config_line=" ip address 192.0.2.2 255.255.255.255", parents=("interface Vlan-interface102",)), + ConfigLine(config_line="interface Ten-GigabitEthernet1/0/1", parents=()), + ConfigLine(config_line=" port link-mode bridge", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" description Test-Port-1", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" undo enable snmp trap updown", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" undo enable log updown", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" port link-type trunk", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" undo port trunk permit vlan 1", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine( + config_line=" port trunk permit vlan 101 to 102 104 to 105", parents=("interface Ten-GigabitEthernet1/0/1",) + ), + ConfigLine(config_line=" port trunk pvid vlan 103", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" stp edged-port", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine( + config_line=" lldp agent nearest-customer admin-status txrx", parents=("interface Ten-GigabitEthernet1/0/1",) + ), + ConfigLine(config_line=" sflow flow collector 1", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" sflow sampling-rate 1000", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" sflow counter collector 1", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" sflow counter interval 2", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" qos trust dscp", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" qos wfq weight", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" qos wfq af1 group 1 weight 2", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" qos wfq af2 group 1 weight 2", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" qos wfq af3 group 1 weight 4", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" qos wfq ef group sp", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" qos wfq cs6 group sp", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" qos wfq cs7 group sp", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" qos bandwidth queue be min 500000", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" qos bandwidth queue af1 min 500000", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" qos bandwidth queue af2 min 2000000", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" qos bandwidth queue af3 min 6500000", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line=" qos bandwidth queue af4 min 100000", parents=("interface Ten-GigabitEthernet1/0/1",)), + ConfigLine(config_line="bgp 65003", parents=()), + ConfigLine(config_line=" router-id 192.0.2.31", parents=("bgp 65003",)), + ConfigLine(config_line=" timer keepalive 5 hold 15", parents=("bgp 65003",)), + ConfigLine(config_line=" ip vpn-instance vpn2", parents=("bgp 65003",)), + ConfigLine(config_line=" peer 192.0.2.61 as-number 65006", parents=("bgp 65003", " ip vpn-instance vpn2")), + ConfigLine( + config_line=" peer 192.0.2.61 connect-interface LoopBack1", parents=("bgp 65003", " ip vpn-instance vpn2") + ), + ConfigLine(config_line=" peer 192.0.2.61 ebgp-max-hop 3", parents=("bgp 65003", " ip vpn-instance vpn2")), + ConfigLine( + config_line=" peer 192.0.2.61 password cipher $c$3$123456789012345678901234567890", + parents=("bgp 65003", " ip vpn-instance vpn2"), + ), + ConfigLine(config_line=" peer 192.0.2.62 as-number 65006", parents=("bgp 65003", " ip vpn-instance vpn2")), + ConfigLine( + config_line=" peer 192.0.2.62 connect-interface LoopBack1", parents=("bgp 65003", " ip vpn-instance vpn2") + ), + ConfigLine(config_line=" peer 192.0.2.62 ebgp-max-hop 3", parents=("bgp 65003", " ip vpn-instance vpn2")), + ConfigLine(config_line=" address-family ipv4 unicast", parents=("bgp 65003", " ip vpn-instance vpn2")), + ConfigLine( + config_line=" network 192.0.2.31 255.255.255.255", + parents=("bgp 65003", " ip vpn-instance vpn2", " address-family ipv4 unicast"), + ), + ConfigLine( + config_line=" network 192.0.2.8 255.255.255.248", + parents=("bgp 65003", " ip vpn-instance vpn2", " address-family ipv4 unicast"), + ), + ConfigLine( + config_line=" network 192.0.2.0 255.255.255.240", + parents=("bgp 65003", " ip vpn-instance vpn2", " address-family ipv4 unicast"), + ), + ConfigLine( + config_line=" network 192.0.2.16 255.255.255.240", + parents=("bgp 65003", " ip vpn-instance vpn2", " address-family ipv4 unicast"), + ), + ConfigLine( + config_line=" network 192.0.2.32 255.255.255.240", + parents=("bgp 65003", " ip vpn-instance vpn2", " address-family ipv4 unicast"), + ), + ConfigLine( + config_line=" network 192.0.2.48 255.255.255.240", + parents=("bgp 65003", " ip vpn-instance vpn2", " address-family ipv4 unicast"), + ), + ConfigLine( + config_line=" network 192.0.2.64 255.255.255.240", + parents=("bgp 65003", " ip vpn-instance vpn2", " address-family ipv4 unicast"), + ), + ConfigLine( + config_line=" peer 192.0.2.61 enable", + parents=("bgp 65003", " ip vpn-instance vpn2", " address-family ipv4 unicast"), + ), + ConfigLine( + config_line=" peer 192.0.2.61 next-hop-local", + parents=("bgp 65003", " ip vpn-instance vpn2", " address-family ipv4 unicast"), + ), + ConfigLine( + config_line=" peer 192.0.2.62 enable", + parents=("bgp 65003", " ip vpn-instance vpn2", " address-family ipv4 unicast"), + ), + ConfigLine( + config_line=" peer 192.0.2.62 next-hop-local", + parents=("bgp 65003", " ip vpn-instance vpn2", " address-family ipv4 unicast"), + ), + ConfigLine(config_line=" scheduler logfile size 16", parents=()), + ConfigLine(config_line="line class aux", parents=()), + ConfigLine(config_line=" user-role network-admin", parents=("line class aux",)), + ConfigLine(config_line="line class vty", parents=()), + ConfigLine(config_line=" user-role network-operator", parents=("line class vty",)), + ConfigLine(config_line="line aux 0 1", parents=()), + ConfigLine(config_line=" authentication-mode scheme", parents=("line aux 0 1",)), + ConfigLine(config_line=" user-role level-0", parents=("line aux 0 1",)), + ConfigLine(config_line=" idle-timeout 15 0", parents=("line aux 0 1",)), + ConfigLine(config_line=" command authorization", parents=("line aux 0 1",)), + ConfigLine(config_line="line vty 0 4", parents=()), + ConfigLine(config_line=" authentication-mode scheme", parents=("line vty 0 4",)), + ConfigLine(config_line=" user-role level-15", parents=("line vty 0 4",)), + ConfigLine(config_line=" user-role network-operator", parents=("line vty 0 4",)), + ConfigLine(config_line=" protocol inbound ssh", parents=("line vty 0 4",)), + ConfigLine(config_line=" idle-timeout 60 0", parents=("line vty 0 4",)), + ConfigLine(config_line=" command authorization", parents=("line vty 0 4",)), + ConfigLine(config_line=" ip route-static vpn-instance vpn1 0.0.0.0 0 192.0.2.1", parents=()), + ConfigLine( + config_line=" ip route-static vpn-instance vpn2 192.0.2.61 32 192.0.2.68 description Test-Peer-2", + parents=(), + ), + ConfigLine( + config_line=" ip route-static vpn-instance vpn2 192.0.2.62 32 192.0.2.68 description Test-Peer-2", + parents=(), + ), + ConfigLine(config_line=" info-center timestamp loghost no-year-date", parents=()), + ConfigLine(config_line=" undo info-center logfile enable", parents=()), + ConfigLine(config_line=" info-center loghost source M-GigabitEthernet0/0/0", parents=()), + ConfigLine(config_line=" info-center loghost vpn-instance internal 192.0.2.132", parents=()), + ConfigLine(config_line=" info-center loghost vpn-instance internal 192.0.2.227", parents=()), + ConfigLine(config_line=" info-center loghost vpn-instance internal 192.0.2.18", parents=()), + ConfigLine(config_line=" info-center loghost vpn-instance internal 192.0.2.195", parents=()), + ConfigLine(config_line=" snmp-agent", parents=()), + ConfigLine(config_line=" snmp-agent local-engineid 123456789012345678901234567890", parents=()), + ConfigLine(config_line=" snmp-agent community read Test-Community acl 1234", parents=()), + ConfigLine(config_line=" snmp-agent sys-info contact Test-Contact", parents=()), + ConfigLine(config_line=" snmp-agent sys-info location Test-Location", parents=()), + ConfigLine(config_line=" snmp-agent sys-info version v2c v3", parents=()), + ConfigLine(config_line=" snmp-agent trap source M-GigabitEthernet0/0/0", parents=()), + ConfigLine(config_line=" ssh server enable", parents=()), + ConfigLine(config_line=" ssh server acl 1234", parents=()), + ConfigLine(config_line=" ftp client source interface M-GigabitEthernet0/0/0", parents=()), + ConfigLine(config_line=" ssh client source interface M-GigabitEthernet0/0/0", parents=()), + ConfigLine(config_line=" sftp client source interface M-GigabitEthernet0/0/0", parents=()), + ConfigLine(config_line=" qos vlan-policy NTC-VLAN-Policy-101 vlan 101 inbound", parents=()), + ConfigLine(config_line=" qos vlan-policy NTC-VLAN-Policy-102 vlan 102 inbound", parents=()), + ConfigLine(config_line=" ntp-service enable", parents=()), + ConfigLine(config_line=" ntp-service source M-GigabitEthernet0/0/0", parents=()), + ConfigLine(config_line=" ntp-service unicast-server 192.0.2.22 vpn-instance internal", parents=()), + ConfigLine(config_line=" ntp-service unicast-peer 192.0.2.10 vpn-instance internal", parents=()), + ConfigLine(config_line=" ntp-service unicast-peer 192.0.2.10 vpn-instance internal", parents=()), + ConfigLine(config_line=" ntp-service unicast-peer 192.0.2.10 vpn-instance internal", parents=()), + ConfigLine(config_line=" ntp-service unicast-peer 192.0.2.10 vpn-instance internal", parents=()), + ConfigLine(config_line=" ntp-service unicast-peer 192.0.2.10 vpn-instance internal", parents=()), + ConfigLine(config_line=" ntp-service unicast-server ntp.example.com vpn-instance internal", parents=()), + ConfigLine(config_line=" ntp-service unicast-server 192.0.2.27 vpn-instance internal", parents=()), + ConfigLine(config_line=" ntp-service unicast-server 192.0.2.70 vpn-instance internal", parents=()), + ConfigLine(config_line=" ntp-service unicast-server 192.0.2.251 vpn-instance internal", parents=()), + ConfigLine(config_line=" ntp-service unicast-server 192.0.2.182 vpn-instance internal", parents=()), + ConfigLine(config_line="acl number 1234 name NTC-ACL", parents=()), + ConfigLine( + config_line=" rule 0 permit tcp destination 0.0.0.0 255.255.255.0 destination-port range 1000 2000", + parents=("acl number 1234 name NTC-ACL",), + ), + ConfigLine(config_line=" rule 0 comment hello world", parents=("acl number 1234 name NTC-ACL",)), + ConfigLine(config_line=" tftp client source interface M-GigabitEthernet0/0/0", parents=()), + ConfigLine(config_line=" header motd %", parents=()), + ConfigLine( + config_line="*******************************************************************************\nUnauthorized Access to or Use of this System is STRICTLY PROHIBITED.\n ALL Access and Use May be Monitored and Recorded.\n*******************************************************************************\n%", + parents=(" header motd %",), + ), + ConfigLine(config_line="hwtacacs scheme NTC-HWTACACS-Scheme", parents=()), + ConfigLine(config_line=" primary authentication 192.0.2.112", parents=("hwtacacs scheme NTC-HWTACACS-Scheme",)), + ConfigLine(config_line=" primary authorization 192.0.2.112", parents=("hwtacacs scheme NTC-HWTACACS-Scheme",)), + ConfigLine(config_line=" primary accounting 192.0.2.112", parents=("hwtacacs scheme NTC-HWTACACS-Scheme",)), + ConfigLine(config_line=" secondary authentication 192.0.2.11", parents=("hwtacacs scheme NTC-HWTACACS-Scheme",)), + ConfigLine(config_line=" secondary authorization 192.0.2.11", parents=("hwtacacs scheme NTC-HWTACACS-Scheme",)), + ConfigLine(config_line=" secondary accounting 192.0.2.11", parents=("hwtacacs scheme NTC-HWTACACS-Scheme",)), + ConfigLine( + config_line=" key authentication cipher $c$3$123456789012345678901234567890", + parents=("hwtacacs scheme NTC-HWTACACS-Scheme",), + ), + ConfigLine( + config_line=" key authorization cipher $c$3$123456789012345678901234567890", + parents=("hwtacacs scheme NTC-HWTACACS-Scheme",), + ), + ConfigLine( + config_line=" key accounting cipher $c$3$123456789012345678901234567890", + parents=("hwtacacs scheme NTC-HWTACACS-Scheme",), + ), + ConfigLine(config_line=" user-name-format without-domain", parents=("hwtacacs scheme NTC-HWTACACS-Scheme",)), + ConfigLine(config_line=" vpn-instance internal", parents=("hwtacacs scheme NTC-HWTACACS-Scheme",)), + ConfigLine(config_line="radius scheme system", parents=()), + ConfigLine(config_line=" user-name-format without-domain", parents=("radius scheme system",)), + ConfigLine(config_line="domain example.com", parents=()), + ConfigLine( + config_line=" authentication default hwtacacs-scheme NTC-HWTACACS-Scheme local", parents=("domain example.com",) + ), + ConfigLine( + config_line=" authorization default hwtacacs-scheme NTC-HWTACACS-Scheme local", parents=("domain example.com",) + ), + ConfigLine(config_line=" accounting default hwtacacs-scheme NTC-HWTACACS-Scheme", parents=("domain example.com",)), + ConfigLine(config_line="domain system", parents=()), + ConfigLine(config_line=" domain default enable example.com", parents=()), + ConfigLine(config_line="role name level-0", parents=()), + ConfigLine(config_line=" description NTC-Level-0 role", parents=("role name level-0",)), + ConfigLine(config_line="role name level-1", parents=()), + ConfigLine(config_line=" description NTC-Level-1 role", parents=("role name level-1",)), + ConfigLine(config_line="user-group system", parents=()), + ConfigLine(config_line="local-user NTC-Admin class manage", parents=()), + ConfigLine( + config_line=" password hash $h$6$123456789012345678901234567890$12345678901234567890123456789012345678901234567890123456789012345678901234567890", + parents=("local-user NTC-Admin class manage",), + ), + ConfigLine(config_line=" service-type ssh telnet terminal", parents=("local-user NTC-Admin class manage",)), + ConfigLine( + config_line=" authorization-attribute user-role level-15", parents=("local-user NTC-Admin class manage",) + ), + ConfigLine( + config_line=" authorization-attribute user-role network-admin", parents=("local-user NTC-Admin class manage",) + ), + ConfigLine( + config_line=" authorization-attribute user-role network-operator", + parents=("local-user NTC-Admin class manage",), + ), + ConfigLine(config_line="local-user NTC-User class manage", parents=()), + ConfigLine( + config_line=" password hash $h$6$123456789012345678901234567890$12345678901234567890123456789012345678901234567890123456789012345678901234567890", + parents=("local-user NTC-User class manage",), + ), + ConfigLine(config_line=" service-type ssh telnet", parents=("local-user NTC-User class manage",)), + ConfigLine( + config_line=" authorization-attribute user-role level-15", parents=("local-user NTC-User class manage",) + ), + ConfigLine( + config_line=" authorization-attribute user-role network-admin", parents=("local-user NTC-User class manage",) + ), + ConfigLine( + config_line=" authorization-attribute user-role network-operator", parents=("local-user NTC-User class manage",) + ), + ConfigLine(config_line="return", parents=()), +] diff --git a/tests/unit/mock/config/parser/base/hp_comware/hp_comware_full_sent.txt b/tests/unit/mock/config/parser/base/hp_comware/hp_comware_full_sent.txt new file mode 100644 index 00000000..a5ca70ed --- /dev/null +++ b/tests/unit/mock/config/parser/base/hp_comware/hp_comware_full_sent.txt @@ -0,0 +1,287 @@ +# +version 7.1.045, Release 2418P06 +# + sysname NTC123456 +# + clock timezone EST minus 05:00:00 + clock summer-time EDT 02:00:00 03/11 02:00:00 11/04 01:00:00 + clock protocol ntp +# + undo copyright-info enable +# +ip vpn-instance vpn1 + route-distinguisher 65001:1 + description vpn1 + vpn-target 65001:1 import-extcommunity + vpn-target 65001:1 export-extcommunity +# +ip vpn-instance internal + route-distinguisher 1:1 + description internal +# + telnet server enable + telnet server acl 1111 +# + irf domain 123456 + irf mac-address persistent timer + irf auto-update enable + undo irf link-delay + irf member 1 priority 32 + irf member 2 priority 1 + irf mode normal +# +igmp-snooping +# + dns source-interface M-GigabitEthernet0/0/0 vpn-instance internal + dns domain example.com + dns domain example.com vpn-instance internal + dns server 192.0.2.47 vpn-instance internal + dns server 192.0.2.15 vpn-instance internal + dns server 192.0.2.11 vpn-instance internal + dns server 192.0.2.2 vpn-instance internal + dns server 192.0.2.6 vpn-instance internal +# + lldp global enable +# + system-working-mode standard + password-recovery enable +# +vlan 1 +# +vlan 101 + name Test-Vlan-101 + description Test Vlan 101 +# +irf-port 1/1 + port group interface FortyGigE1/0/49 + port group interface FortyGigE1/0/50 +# +irf-port 2/2 + port group interface FortyGigE2/0/49 + port group interface FortyGigE2/0/50 +# +qos map-table dot1p-lp + import 0 export 0 + import 1 export 1 + import 2 export 2 +# +traffic classifier NTC-Classifier operator or + if-match dscp ntc + if-match acl 4000 +# +traffic behavior NTC-Behavior + remark dscp ntc +# +traffic behavior foo +# +qos policy NTC-Policy + classifier NTC-Classifier behavior NTC-Behavior +# +stp region-configuration + region-name NTC-Region + revision-level 100 + instance 1 vlan 1 to 4094 + active region-configuration +# + stp instance 0 to 1 priority 16384 + stp vlan 1 to 4094 priority 16384 + stp mode pvst + stp bpdu-protection + stp global enable +# + l2vpn enable +# +interface NULL0 +# +interface LoopBack1 + ip binding vpn-instance internal + ip address 192.0.2.1 255.255.255.255 +# +interface Vlan-interface102 + shutdown + ip binding vpn-instance vpn2 + ip address 192.0.2.2 255.255.255.255 +# +interface Ten-GigabitEthernet1/0/1 + port link-mode bridge + description Test-Port-1 + undo enable snmp trap updown + undo enable log updown + port link-type trunk + undo port trunk permit vlan 1 + port trunk permit vlan 101 to 102 104 to 105 + port trunk pvid vlan 103 + stp edged-port + lldp agent nearest-customer admin-status txrx + sflow flow collector 1 + sflow sampling-rate 1000 + sflow counter collector 1 + sflow counter interval 2 + qos trust dscp + qos wfq weight + qos wfq af1 group 1 weight 2 + qos wfq af2 group 1 weight 2 + qos wfq af3 group 1 weight 4 + qos wfq ef group sp + qos wfq cs6 group sp + qos wfq cs7 group sp + qos bandwidth queue be min 500000 + qos bandwidth queue af1 min 500000 + qos bandwidth queue af2 min 2000000 + qos bandwidth queue af3 min 6500000 + qos bandwidth queue af4 min 100000 +# +bgp 65003 + router-id 192.0.2.31 + timer keepalive 5 hold 15 + # + ip vpn-instance vpn2 + peer 192.0.2.61 as-number 65006 + peer 192.0.2.61 connect-interface LoopBack1 + peer 192.0.2.61 ebgp-max-hop 3 + peer 192.0.2.61 password cipher $c$3$123456789012345678901234567890 + peer 192.0.2.62 as-number 65006 + peer 192.0.2.62 connect-interface LoopBack1 + peer 192.0.2.62 ebgp-max-hop 3 + # + address-family ipv4 unicast + network 192.0.2.31 255.255.255.255 + network 192.0.2.8 255.255.255.248 + network 192.0.2.0 255.255.255.240 + network 192.0.2.16 255.255.255.240 + network 192.0.2.32 255.255.255.240 + network 192.0.2.48 255.255.255.240 + network 192.0.2.64 255.255.255.240 + peer 192.0.2.61 enable + peer 192.0.2.61 next-hop-local + peer 192.0.2.62 enable + peer 192.0.2.62 next-hop-local +# + scheduler logfile size 16 +# +line class aux + user-role network-admin +# +line class vty + user-role network-operator +# +line aux 0 1 + authentication-mode scheme + user-role level-0 + idle-timeout 15 0 + command authorization +# +line vty 0 4 + authentication-mode scheme + user-role level-15 + user-role network-operator + protocol inbound ssh + idle-timeout 60 0 + command authorization +# + ip route-static vpn-instance vpn1 0.0.0.0 0 192.0.2.1 + ip route-static vpn-instance vpn2 192.0.2.61 32 192.0.2.68 description Test-Peer-2 + ip route-static vpn-instance vpn2 192.0.2.62 32 192.0.2.68 description Test-Peer-2 +# + info-center timestamp loghost no-year-date + undo info-center logfile enable + info-center loghost source M-GigabitEthernet0/0/0 + info-center loghost vpn-instance internal 192.0.2.132 + info-center loghost vpn-instance internal 192.0.2.227 + info-center loghost vpn-instance internal 192.0.2.18 + info-center loghost vpn-instance internal 192.0.2.195 +# + snmp-agent + snmp-agent local-engineid 123456789012345678901234567890 + snmp-agent community read Test-Community acl 1234 + snmp-agent sys-info contact Test-Contact + snmp-agent sys-info location Test-Location + snmp-agent sys-info version v2c v3 + snmp-agent trap source M-GigabitEthernet0/0/0 +# + ssh server enable + ssh server acl 1234 +# + ftp client source interface M-GigabitEthernet0/0/0 +# + ssh client source interface M-GigabitEthernet0/0/0 + sftp client source interface M-GigabitEthernet0/0/0 +# + qos vlan-policy NTC-VLAN-Policy-101 vlan 101 inbound + qos vlan-policy NTC-VLAN-Policy-102 vlan 102 inbound +# + ntp-service enable + ntp-service source M-GigabitEthernet0/0/0 + ntp-service unicast-server 192.0.2.22 vpn-instance internal + ntp-service unicast-peer 192.0.2.10 vpn-instance internal + ntp-service unicast-peer 192.0.2.10 vpn-instance internal + ntp-service unicast-peer 192.0.2.10 vpn-instance internal + ntp-service unicast-peer 192.0.2.10 vpn-instance internal + ntp-service unicast-peer 192.0.2.10 vpn-instance internal + ntp-service unicast-server ntp.example.com vpn-instance internal + ntp-service unicast-server 192.0.2.27 vpn-instance internal + ntp-service unicast-server 192.0.2.70 vpn-instance internal + ntp-service unicast-server 192.0.2.251 vpn-instance internal + ntp-service unicast-server 192.0.2.182 vpn-instance internal +# +acl number 1234 name NTC-ACL + rule 0 permit tcp destination 0.0.0.0 255.255.255.0 destination-port range 1000 2000 + rule 0 comment hello world +# + tftp client source interface M-GigabitEthernet0/0/0 +# + header motd % +******************************************************************************* +Unauthorized Access to or Use of this System is STRICTLY PROHIBITED. + ALL Access and Use May be Monitored and Recorded. +******************************************************************************* +% +# +hwtacacs scheme NTC-HWTACACS-Scheme + primary authentication 192.0.2.112 + primary authorization 192.0.2.112 + primary accounting 192.0.2.112 + secondary authentication 192.0.2.11 + secondary authorization 192.0.2.11 + secondary accounting 192.0.2.11 + key authentication cipher $c$3$123456789012345678901234567890 + key authorization cipher $c$3$123456789012345678901234567890 + key accounting cipher $c$3$123456789012345678901234567890 + user-name-format without-domain + vpn-instance internal +# +radius scheme system + user-name-format without-domain +# +domain example.com + authentication default hwtacacs-scheme NTC-HWTACACS-Scheme local + authorization default hwtacacs-scheme NTC-HWTACACS-Scheme local + accounting default hwtacacs-scheme NTC-HWTACACS-Scheme +# +domain system +# + domain default enable example.com +# +role name level-0 + description NTC-Level-0 role +# +role name level-1 + description NTC-Level-1 role +# +user-group system +# +local-user NTC-Admin class manage + password hash $h$6$123456789012345678901234567890$12345678901234567890123456789012345678901234567890123456789012345678901234567890 + service-type ssh telnet terminal + authorization-attribute user-role level-15 + authorization-attribute user-role network-admin + authorization-attribute user-role network-operator +# +local-user NTC-User class manage + password hash $h$6$123456789012345678901234567890$12345678901234567890123456789012345678901234567890123456789012345678901234567890 + service-type ssh telnet + authorization-attribute user-role level-15 + authorization-attribute user-role network-admin + authorization-attribute user-role network-operator +# +return \ No newline at end of file diff --git a/tests/unit/mock/config/parser/base/hp_comware/hp_comware_special_received.py b/tests/unit/mock/config/parser/base/hp_comware/hp_comware_special_received.py new file mode 100644 index 00000000..399bd8e3 --- /dev/null +++ b/tests/unit/mock/config/parser/base/hp_comware/hp_comware_special_received.py @@ -0,0 +1,65 @@ +from netutils.config.parser import ConfigLine + +data = [ + ConfigLine(config_line="vlan 10", parents=()), + ConfigLine(config_line=" name management", parents=("vlan 10",)), + ConfigLine(config_line=" description management vlan", parents=("vlan 10",)), + ConfigLine(config_line="vlan 15", parents=("vlan 10",)), + ConfigLine(config_line=" name users", parents=("vlan 10", "vlan 15")), + ConfigLine(config_line=" description users vlan", parents=("vlan 10", "vlan 15")), + ConfigLine(config_line="vlan 16", parents=("vlan 10",)), + ConfigLine(config_line=" name phones", parents=("vlan 10", "vlan 16")), + ConfigLine(config_line=" description phones vlan", parents=("vlan 10", "vlan 16")), + ConfigLine(config_line="vlan 20", parents=("vlan 10",)), + ConfigLine(config_line=" name servers vlan", parents=("vlan 10", "vlan 20")), + ConfigLine(config_line=" description servers vlan", parents=("vlan 10", "vlan 20")), + ConfigLine(config_line=" rsa peer-public-key 192.0.2.5", parents=()), + ConfigLine(config_line=" public-key-code begin", parents=(" rsa peer-public-key 192.0.2.5",)), + ConfigLine(config_line=" ABCDEF01", parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin")), + ConfigLine( + config_line=" 12345678", + parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01"), + ), + ConfigLine( + config_line=" A1B2C3D4 E5F6A7B8 C9D0E1F2 1A2B3C4D 5E6F7A8B 9C0D1E2F 3A4B5C6D 7E8F9A0B", + parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), + ), + ConfigLine( + config_line=" C1D2E3F4 A5B6C7D8 E9F0A1B2 3C4D5E6F 7A8B9C0D 1E2F3A4B 5C6D7E8F 9A0B1C2D", + parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), + ), + ConfigLine( + config_line=" 1A2B3C4D 5E6F7A8B 9C0D1E2F 3A4B5C6D 7E8F9A0B C1D2E3F4 A5B6C7D8 E9F0A1B2", + parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), + ), + ConfigLine( + config_line=" 3C4D5E6F 7A8B9C0D 1E2F3A4B 5C6D7E8F 9A0B1C2D 1A2B3C4D 5E6F7A8B 9C0D1E2F", + parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), + ), + ConfigLine( + config_line=" 8A9B0C1D 2E3F4A5B 6C7D8E9F 0A1B2C3D 4E5F6A7B 8C9D0E1F 2A3B4C5D 6E7F8A9B", + parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), + ), + ConfigLine( + config_line=" 0C1D2E3F 4A5B6C7D 8E9F0A1B 2C3D4E5F 6A7B8C9D 0E1F2A3B 4C5D6E7F 8A9B0C1D", + parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), + ), + ConfigLine( + config_line=" 2E3F4A5B 6C7D8E9F 0A1B2C3D 4E5F6A7B 8C9D0E1F 2A3B4C5D 6E7F8A9B 0C1D2E3F", + parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), + ), + ConfigLine( + config_line=" 1B2C3D4E 5F6A7B8C 9D0E1F2A 3B4C5D6E 7F8A9B0C 1D2E3F4A 5B6C7D8E 9F0A1B2C", + parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), + ), + ConfigLine( + config_line=" 8810", parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01") + ), + ConfigLine( + config_line=" FACED", + parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 8810"), + ), + ConfigLine(config_line=" public-key-code end", parents=(" rsa peer-public-key 192.0.2.5",)), + ConfigLine(config_line=" peer-public-key end", parents=(" rsa peer-public-key 192.0.2.5",)), + ConfigLine(config_line="sysname NTC-Router", parents=()), +] diff --git a/tests/unit/mock/config/parser/base/hp_comware/hp_comware_special_sent.txt b/tests/unit/mock/config/parser/base/hp_comware/hp_comware_special_sent.txt new file mode 100644 index 00000000..0ab6910f --- /dev/null +++ b/tests/unit/mock/config/parser/base/hp_comware/hp_comware_special_sent.txt @@ -0,0 +1,37 @@ +# Extra leading spaces +vlan 10 + name management + description management vlan +vlan 15 + name users + description users vlan +vlan 16 + name phones + description phones vlan +vlan 20 + name servers vlan + description servers vlan +# +# Comment lines should be ignored +# +# RSA Public Key + rsa peer-public-key 192.0.2.5 + public-key-code begin + ABCDEF01 + 12345678 + A1B2C3D4 E5F6A7B8 C9D0E1F2 1A2B3C4D 5E6F7A8B 9C0D1E2F 3A4B5C6D 7E8F9A0B + C1D2E3F4 A5B6C7D8 E9F0A1B2 3C4D5E6F 7A8B9C0D 1E2F3A4B 5C6D7E8F 9A0B1C2D + 1A2B3C4D 5E6F7A8B 9C0D1E2F 3A4B5C6D 7E8F9A0B C1D2E3F4 A5B6C7D8 E9F0A1B2 + 3C4D5E6F 7A8B9C0D 1E2F3A4B 5C6D7E8F 9A0B1C2D 1A2B3C4D 5E6F7A8B 9C0D1E2F + 8A9B0C1D 2E3F4A5B 6C7D8E9F 0A1B2C3D 4E5F6A7B 8C9D0E1F 2A3B4C5D 6E7F8A9B + 0C1D2E3F 4A5B6C7D 8E9F0A1B 2C3D4E5F 6A7B8C9D 0E1F2A3B 4C5D6E7F 8A9B0C1D + 2E3F4A5B 6C7D8E9F 0A1B2C3D 4E5F6A7B 8C9D0E1F 2A3B4C5D 6E7F8A9B 0C1D2E3F + 1B2C3D4E 5F6A7B8C 9D0E1F2A 3B4C5D6E 7F8A9B0C 1D2E3F4A 5B6C7D8E 9F0A1B2C + 8810 + FACED + public-key-code end + peer-public-key end +# +# Lines with trailing spaces should be trimmed +sysname NTC-Router +# \ No newline at end of file diff --git a/tests/unit/test_deprecation.py b/tests/unit/test_deprecation.py new file mode 100644 index 00000000..f6bf64e8 --- /dev/null +++ b/tests/unit/test_deprecation.py @@ -0,0 +1,16 @@ +"""Test for deprecation warnings.""" + +import pytest + +from netutils.config.parser import HPComwareConfigParser + + +def test_hp_comware_config_parser_deprecated(): + """Test that HPComwareConfigParser is deprecated and issues a warning.""" + expected_message = ( + "HPComwareConfigParser is deprecated and will be removed in a future version. Use HPEConfigParser instead." + ) + + with pytest.warns(DeprecationWarning, match=expected_message): + # Instantiating the class should trigger the deprecation warning + HPComwareConfigParser("test config") From 6fd7bdf37fabf0e7c693b66eebb31a203b63bd5d Mon Sep 17 00:00:00 2001 From: Joe Wesch Date: Wed, 14 Jan 2026 12:09:34 -0600 Subject: [PATCH 2/5] Added lstrip for all config lines without parents --- netutils/config/parser.py | 7 +- .../hp_comware/hp_comware_full_received.py | 146 +++++++++--------- .../hp_comware/hp_comware_special_received.py | 41 ++--- .../hp_comware/hp_comware_special_sent.txt | 9 -- 4 files changed, 95 insertions(+), 108 deletions(-) diff --git a/netutils/config/parser.py b/netutils/config/parser.py index 0e732279..d2123578 100644 --- a/netutils/config/parser.py +++ b/netutils/config/parser.py @@ -1710,6 +1710,7 @@ def build_config_relationship(self) -> t.List[ConfigLine]: That new section may or may not have children. Each config line that has a leading space but not a parent is just a single config line. Single lines that have leading spaces also sometimes differs between models (e.g., 59XX vs 79XX series). + We strip the leading spaces from config lines without parents for consistency. Examples: >>> from netutils.config.parser import HPEConfigParser, ConfigLine @@ -1726,7 +1727,7 @@ def build_config_relationship(self) -> t.List[ConfigLine]: >>> config_tree.build_config_relationship() == \ ... [ ... ConfigLine(config_line="version 7.1.045, Release 2418P06", parents=()), - ... ConfigLine(config_line=" sysname NTC123456", parents=()), + ... ConfigLine(config_line="sysname NTC123456", parents=()), ... ConfigLine(config_line="vlan 101", parents=()), ... ConfigLine(config_line=" name Test-Vlan-101", parents=("vlan 101",)), ... ConfigLine(config_line=" description Test Vlan 101", parents=("vlan 101",)), @@ -1747,6 +1748,7 @@ def build_config_relationship(self) -> t.List[ConfigLine]: continue if self.is_banner_start(line): # Special case for banners + line = line.lstrip() self._build_banner(line) continue @@ -1759,6 +1761,9 @@ def build_config_relationship(self) -> t.List[ConfigLine]: elif current_spaces < self.indent_level: self._current_parents = self._remove_parents(line, current_spaces) + if not self._current_parents: + # Standardize lines without parents to remove leading spaces + line = line.lstrip() new_section = False self.indent_level = current_spaces self._update_config_lines(line) diff --git a/tests/unit/mock/config/parser/base/hp_comware/hp_comware_full_received.py b/tests/unit/mock/config/parser/base/hp_comware/hp_comware_full_received.py index eef90547..cf8ef5d3 100644 --- a/tests/unit/mock/config/parser/base/hp_comware/hp_comware_full_received.py +++ b/tests/unit/mock/config/parser/base/hp_comware/hp_comware_full_received.py @@ -2,14 +2,14 @@ data = [ ConfigLine(config_line="version 7.1.045, Release 2418P06", parents=()), - ConfigLine(config_line=" sysname NTC123456", parents=()), - ConfigLine(config_line=" clock timezone EST minus 05:00:00", parents=()), + ConfigLine(config_line="sysname NTC123456", parents=()), + ConfigLine(config_line="clock timezone EST minus 05:00:00", parents=()), ConfigLine( - config_line=" clock summer-time EDT 02:00:00 03/11 02:00:00 11/04 01:00:00", + config_line="clock summer-time EDT 02:00:00 03/11 02:00:00 11/04 01:00:00", parents=(), ), - ConfigLine(config_line=" clock protocol ntp", parents=()), - ConfigLine(config_line=" undo copyright-info enable", parents=()), + ConfigLine(config_line="clock protocol ntp", parents=()), + ConfigLine(config_line="undo copyright-info enable", parents=()), ConfigLine(config_line="ip vpn-instance vpn1", parents=()), ConfigLine(config_line=" route-distinguisher 65001:1", parents=("ip vpn-instance vpn1",)), ConfigLine(config_line=" description vpn1", parents=("ip vpn-instance vpn1",)), @@ -18,27 +18,27 @@ ConfigLine(config_line="ip vpn-instance internal", parents=()), ConfigLine(config_line=" route-distinguisher 1:1", parents=("ip vpn-instance internal",)), ConfigLine(config_line=" description internal", parents=("ip vpn-instance internal",)), - ConfigLine(config_line=" telnet server enable", parents=()), - ConfigLine(config_line=" telnet server acl 1111", parents=()), - ConfigLine(config_line=" irf domain 123456", parents=()), - ConfigLine(config_line=" irf mac-address persistent timer", parents=()), - ConfigLine(config_line=" irf auto-update enable", parents=()), - ConfigLine(config_line=" undo irf link-delay", parents=()), - ConfigLine(config_line=" irf member 1 priority 32", parents=()), - ConfigLine(config_line=" irf member 2 priority 1", parents=()), - ConfigLine(config_line=" irf mode normal", parents=()), + ConfigLine(config_line="telnet server enable", parents=()), + ConfigLine(config_line="telnet server acl 1111", parents=()), + ConfigLine(config_line="irf domain 123456", parents=()), + ConfigLine(config_line="irf mac-address persistent timer", parents=()), + ConfigLine(config_line="irf auto-update enable", parents=()), + ConfigLine(config_line="undo irf link-delay", parents=()), + ConfigLine(config_line="irf member 1 priority 32", parents=()), + ConfigLine(config_line="irf member 2 priority 1", parents=()), + ConfigLine(config_line="irf mode normal", parents=()), ConfigLine(config_line="igmp-snooping", parents=()), - ConfigLine(config_line=" dns source-interface M-GigabitEthernet0/0/0 vpn-instance internal", parents=()), - ConfigLine(config_line=" dns domain example.com", parents=()), - ConfigLine(config_line=" dns domain example.com vpn-instance internal", parents=()), - ConfigLine(config_line=" dns server 192.0.2.47 vpn-instance internal", parents=()), - ConfigLine(config_line=" dns server 192.0.2.15 vpn-instance internal", parents=()), - ConfigLine(config_line=" dns server 192.0.2.11 vpn-instance internal", parents=()), - ConfigLine(config_line=" dns server 192.0.2.2 vpn-instance internal", parents=()), - ConfigLine(config_line=" dns server 192.0.2.6 vpn-instance internal", parents=()), - ConfigLine(config_line=" lldp global enable", parents=()), - ConfigLine(config_line=" system-working-mode standard", parents=()), - ConfigLine(config_line=" password-recovery enable", parents=()), + ConfigLine(config_line="dns source-interface M-GigabitEthernet0/0/0 vpn-instance internal", parents=()), + ConfigLine(config_line="dns domain example.com", parents=()), + ConfigLine(config_line="dns domain example.com vpn-instance internal", parents=()), + ConfigLine(config_line="dns server 192.0.2.47 vpn-instance internal", parents=()), + ConfigLine(config_line="dns server 192.0.2.15 vpn-instance internal", parents=()), + ConfigLine(config_line="dns server 192.0.2.11 vpn-instance internal", parents=()), + ConfigLine(config_line="dns server 192.0.2.2 vpn-instance internal", parents=()), + ConfigLine(config_line="dns server 192.0.2.6 vpn-instance internal", parents=()), + ConfigLine(config_line="lldp global enable", parents=()), + ConfigLine(config_line="system-working-mode standard", parents=()), + ConfigLine(config_line="password-recovery enable", parents=()), ConfigLine(config_line="vlan 1", parents=()), ConfigLine(config_line="vlan 101", parents=()), ConfigLine(config_line=" name Test-Vlan-101", parents=("vlan 101",)), @@ -66,12 +66,12 @@ ConfigLine(config_line=" revision-level 100", parents=("stp region-configuration",)), ConfigLine(config_line=" instance 1 vlan 1 to 4094", parents=("stp region-configuration",)), ConfigLine(config_line=" active region-configuration", parents=("stp region-configuration",)), - ConfigLine(config_line=" stp instance 0 to 1 priority 16384", parents=()), - ConfigLine(config_line=" stp vlan 1 to 4094 priority 16384", parents=()), - ConfigLine(config_line=" stp mode pvst", parents=()), - ConfigLine(config_line=" stp bpdu-protection", parents=()), - ConfigLine(config_line=" stp global enable", parents=()), - ConfigLine(config_line=" l2vpn enable", parents=()), + ConfigLine(config_line="stp instance 0 to 1 priority 16384", parents=()), + ConfigLine(config_line="stp vlan 1 to 4094 priority 16384", parents=()), + ConfigLine(config_line="stp mode pvst", parents=()), + ConfigLine(config_line="stp bpdu-protection", parents=()), + ConfigLine(config_line="stp global enable", parents=()), + ConfigLine(config_line="l2vpn enable", parents=()), ConfigLine(config_line="interface NULL0", parents=()), ConfigLine(config_line="interface LoopBack1", parents=()), ConfigLine(config_line=" ip binding vpn-instance internal", parents=("interface LoopBack1",)), @@ -175,7 +175,7 @@ config_line=" peer 192.0.2.62 next-hop-local", parents=("bgp 65003", " ip vpn-instance vpn2", " address-family ipv4 unicast"), ), - ConfigLine(config_line=" scheduler logfile size 16", parents=()), + ConfigLine(config_line="scheduler logfile size 16", parents=()), ConfigLine(config_line="line class aux", parents=()), ConfigLine(config_line=" user-role network-admin", parents=("line class aux",)), ConfigLine(config_line="line class vty", parents=()), @@ -192,60 +192,60 @@ ConfigLine(config_line=" protocol inbound ssh", parents=("line vty 0 4",)), ConfigLine(config_line=" idle-timeout 60 0", parents=("line vty 0 4",)), ConfigLine(config_line=" command authorization", parents=("line vty 0 4",)), - ConfigLine(config_line=" ip route-static vpn-instance vpn1 0.0.0.0 0 192.0.2.1", parents=()), + ConfigLine(config_line="ip route-static vpn-instance vpn1 0.0.0.0 0 192.0.2.1", parents=()), ConfigLine( - config_line=" ip route-static vpn-instance vpn2 192.0.2.61 32 192.0.2.68 description Test-Peer-2", + config_line="ip route-static vpn-instance vpn2 192.0.2.61 32 192.0.2.68 description Test-Peer-2", parents=(), ), ConfigLine( - config_line=" ip route-static vpn-instance vpn2 192.0.2.62 32 192.0.2.68 description Test-Peer-2", + config_line="ip route-static vpn-instance vpn2 192.0.2.62 32 192.0.2.68 description Test-Peer-2", parents=(), ), - ConfigLine(config_line=" info-center timestamp loghost no-year-date", parents=()), - ConfigLine(config_line=" undo info-center logfile enable", parents=()), - ConfigLine(config_line=" info-center loghost source M-GigabitEthernet0/0/0", parents=()), - ConfigLine(config_line=" info-center loghost vpn-instance internal 192.0.2.132", parents=()), - ConfigLine(config_line=" info-center loghost vpn-instance internal 192.0.2.227", parents=()), - ConfigLine(config_line=" info-center loghost vpn-instance internal 192.0.2.18", parents=()), - ConfigLine(config_line=" info-center loghost vpn-instance internal 192.0.2.195", parents=()), - ConfigLine(config_line=" snmp-agent", parents=()), - ConfigLine(config_line=" snmp-agent local-engineid 123456789012345678901234567890", parents=()), - ConfigLine(config_line=" snmp-agent community read Test-Community acl 1234", parents=()), - ConfigLine(config_line=" snmp-agent sys-info contact Test-Contact", parents=()), - ConfigLine(config_line=" snmp-agent sys-info location Test-Location", parents=()), - ConfigLine(config_line=" snmp-agent sys-info version v2c v3", parents=()), - ConfigLine(config_line=" snmp-agent trap source M-GigabitEthernet0/0/0", parents=()), - ConfigLine(config_line=" ssh server enable", parents=()), - ConfigLine(config_line=" ssh server acl 1234", parents=()), - ConfigLine(config_line=" ftp client source interface M-GigabitEthernet0/0/0", parents=()), - ConfigLine(config_line=" ssh client source interface M-GigabitEthernet0/0/0", parents=()), - ConfigLine(config_line=" sftp client source interface M-GigabitEthernet0/0/0", parents=()), - ConfigLine(config_line=" qos vlan-policy NTC-VLAN-Policy-101 vlan 101 inbound", parents=()), - ConfigLine(config_line=" qos vlan-policy NTC-VLAN-Policy-102 vlan 102 inbound", parents=()), - ConfigLine(config_line=" ntp-service enable", parents=()), - ConfigLine(config_line=" ntp-service source M-GigabitEthernet0/0/0", parents=()), - ConfigLine(config_line=" ntp-service unicast-server 192.0.2.22 vpn-instance internal", parents=()), - ConfigLine(config_line=" ntp-service unicast-peer 192.0.2.10 vpn-instance internal", parents=()), - ConfigLine(config_line=" ntp-service unicast-peer 192.0.2.10 vpn-instance internal", parents=()), - ConfigLine(config_line=" ntp-service unicast-peer 192.0.2.10 vpn-instance internal", parents=()), - ConfigLine(config_line=" ntp-service unicast-peer 192.0.2.10 vpn-instance internal", parents=()), - ConfigLine(config_line=" ntp-service unicast-peer 192.0.2.10 vpn-instance internal", parents=()), - ConfigLine(config_line=" ntp-service unicast-server ntp.example.com vpn-instance internal", parents=()), - ConfigLine(config_line=" ntp-service unicast-server 192.0.2.27 vpn-instance internal", parents=()), - ConfigLine(config_line=" ntp-service unicast-server 192.0.2.70 vpn-instance internal", parents=()), - ConfigLine(config_line=" ntp-service unicast-server 192.0.2.251 vpn-instance internal", parents=()), - ConfigLine(config_line=" ntp-service unicast-server 192.0.2.182 vpn-instance internal", parents=()), + ConfigLine(config_line="info-center timestamp loghost no-year-date", parents=()), + ConfigLine(config_line="undo info-center logfile enable", parents=()), + ConfigLine(config_line="info-center loghost source M-GigabitEthernet0/0/0", parents=()), + ConfigLine(config_line="info-center loghost vpn-instance internal 192.0.2.132", parents=()), + ConfigLine(config_line="info-center loghost vpn-instance internal 192.0.2.227", parents=()), + ConfigLine(config_line="info-center loghost vpn-instance internal 192.0.2.18", parents=()), + ConfigLine(config_line="info-center loghost vpn-instance internal 192.0.2.195", parents=()), + ConfigLine(config_line="snmp-agent", parents=()), + ConfigLine(config_line="snmp-agent local-engineid 123456789012345678901234567890", parents=()), + ConfigLine(config_line="snmp-agent community read Test-Community acl 1234", parents=()), + ConfigLine(config_line="snmp-agent sys-info contact Test-Contact", parents=()), + ConfigLine(config_line="snmp-agent sys-info location Test-Location", parents=()), + ConfigLine(config_line="snmp-agent sys-info version v2c v3", parents=()), + ConfigLine(config_line="snmp-agent trap source M-GigabitEthernet0/0/0", parents=()), + ConfigLine(config_line="ssh server enable", parents=()), + ConfigLine(config_line="ssh server acl 1234", parents=()), + ConfigLine(config_line="ftp client source interface M-GigabitEthernet0/0/0", parents=()), + ConfigLine(config_line="ssh client source interface M-GigabitEthernet0/0/0", parents=()), + ConfigLine(config_line="sftp client source interface M-GigabitEthernet0/0/0", parents=()), + ConfigLine(config_line="qos vlan-policy NTC-VLAN-Policy-101 vlan 101 inbound", parents=()), + ConfigLine(config_line="qos vlan-policy NTC-VLAN-Policy-102 vlan 102 inbound", parents=()), + ConfigLine(config_line="ntp-service enable", parents=()), + ConfigLine(config_line="ntp-service source M-GigabitEthernet0/0/0", parents=()), + ConfigLine(config_line="ntp-service unicast-server 192.0.2.22 vpn-instance internal", parents=()), + ConfigLine(config_line="ntp-service unicast-peer 192.0.2.10 vpn-instance internal", parents=()), + ConfigLine(config_line="ntp-service unicast-peer 192.0.2.10 vpn-instance internal", parents=()), + ConfigLine(config_line="ntp-service unicast-peer 192.0.2.10 vpn-instance internal", parents=()), + ConfigLine(config_line="ntp-service unicast-peer 192.0.2.10 vpn-instance internal", parents=()), + ConfigLine(config_line="ntp-service unicast-peer 192.0.2.10 vpn-instance internal", parents=()), + ConfigLine(config_line="ntp-service unicast-server ntp.example.com vpn-instance internal", parents=()), + ConfigLine(config_line="ntp-service unicast-server 192.0.2.27 vpn-instance internal", parents=()), + ConfigLine(config_line="ntp-service unicast-server 192.0.2.70 vpn-instance internal", parents=()), + ConfigLine(config_line="ntp-service unicast-server 192.0.2.251 vpn-instance internal", parents=()), + ConfigLine(config_line="ntp-service unicast-server 192.0.2.182 vpn-instance internal", parents=()), ConfigLine(config_line="acl number 1234 name NTC-ACL", parents=()), ConfigLine( config_line=" rule 0 permit tcp destination 0.0.0.0 255.255.255.0 destination-port range 1000 2000", parents=("acl number 1234 name NTC-ACL",), ), ConfigLine(config_line=" rule 0 comment hello world", parents=("acl number 1234 name NTC-ACL",)), - ConfigLine(config_line=" tftp client source interface M-GigabitEthernet0/0/0", parents=()), - ConfigLine(config_line=" header motd %", parents=()), + ConfigLine(config_line="tftp client source interface M-GigabitEthernet0/0/0", parents=()), + ConfigLine(config_line="header motd %", parents=()), ConfigLine( config_line="*******************************************************************************\nUnauthorized Access to or Use of this System is STRICTLY PROHIBITED.\n ALL Access and Use May be Monitored and Recorded.\n*******************************************************************************\n%", - parents=(" header motd %",), + parents=("header motd %",), ), ConfigLine(config_line="hwtacacs scheme NTC-HWTACACS-Scheme", parents=()), ConfigLine(config_line=" primary authentication 192.0.2.112", parents=("hwtacacs scheme NTC-HWTACACS-Scheme",)), @@ -279,7 +279,7 @@ ), ConfigLine(config_line=" accounting default hwtacacs-scheme NTC-HWTACACS-Scheme", parents=("domain example.com",)), ConfigLine(config_line="domain system", parents=()), - ConfigLine(config_line=" domain default enable example.com", parents=()), + ConfigLine(config_line="domain default enable example.com", parents=()), ConfigLine(config_line="role name level-0", parents=()), ConfigLine(config_line=" description NTC-Level-0 role", parents=("role name level-0",)), ConfigLine(config_line="role name level-1", parents=()), diff --git a/tests/unit/mock/config/parser/base/hp_comware/hp_comware_special_received.py b/tests/unit/mock/config/parser/base/hp_comware/hp_comware_special_received.py index 399bd8e3..a2cc64f6 100644 --- a/tests/unit/mock/config/parser/base/hp_comware/hp_comware_special_received.py +++ b/tests/unit/mock/config/parser/base/hp_comware/hp_comware_special_received.py @@ -4,62 +4,53 @@ ConfigLine(config_line="vlan 10", parents=()), ConfigLine(config_line=" name management", parents=("vlan 10",)), ConfigLine(config_line=" description management vlan", parents=("vlan 10",)), - ConfigLine(config_line="vlan 15", parents=("vlan 10",)), - ConfigLine(config_line=" name users", parents=("vlan 10", "vlan 15")), - ConfigLine(config_line=" description users vlan", parents=("vlan 10", "vlan 15")), - ConfigLine(config_line="vlan 16", parents=("vlan 10",)), - ConfigLine(config_line=" name phones", parents=("vlan 10", "vlan 16")), - ConfigLine(config_line=" description phones vlan", parents=("vlan 10", "vlan 16")), - ConfigLine(config_line="vlan 20", parents=("vlan 10",)), - ConfigLine(config_line=" name servers vlan", parents=("vlan 10", "vlan 20")), - ConfigLine(config_line=" description servers vlan", parents=("vlan 10", "vlan 20")), - ConfigLine(config_line=" rsa peer-public-key 192.0.2.5", parents=()), - ConfigLine(config_line=" public-key-code begin", parents=(" rsa peer-public-key 192.0.2.5",)), - ConfigLine(config_line=" ABCDEF01", parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin")), + ConfigLine(config_line="rsa peer-public-key 192.0.2.5", parents=()), + ConfigLine(config_line=" public-key-code begin", parents=("rsa peer-public-key 192.0.2.5",)), + ConfigLine(config_line=" ABCDEF01", parents=("rsa peer-public-key 192.0.2.5", " public-key-code begin")), ConfigLine( config_line=" 12345678", - parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01"), + parents=("rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01"), ), ConfigLine( config_line=" A1B2C3D4 E5F6A7B8 C9D0E1F2 1A2B3C4D 5E6F7A8B 9C0D1E2F 3A4B5C6D 7E8F9A0B", - parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), + parents=("rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), ), ConfigLine( config_line=" C1D2E3F4 A5B6C7D8 E9F0A1B2 3C4D5E6F 7A8B9C0D 1E2F3A4B 5C6D7E8F 9A0B1C2D", - parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), + parents=("rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), ), ConfigLine( config_line=" 1A2B3C4D 5E6F7A8B 9C0D1E2F 3A4B5C6D 7E8F9A0B C1D2E3F4 A5B6C7D8 E9F0A1B2", - parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), + parents=("rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), ), ConfigLine( config_line=" 3C4D5E6F 7A8B9C0D 1E2F3A4B 5C6D7E8F 9A0B1C2D 1A2B3C4D 5E6F7A8B 9C0D1E2F", - parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), + parents=("rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), ), ConfigLine( config_line=" 8A9B0C1D 2E3F4A5B 6C7D8E9F 0A1B2C3D 4E5F6A7B 8C9D0E1F 2A3B4C5D 6E7F8A9B", - parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), + parents=("rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), ), ConfigLine( config_line=" 0C1D2E3F 4A5B6C7D 8E9F0A1B 2C3D4E5F 6A7B8C9D 0E1F2A3B 4C5D6E7F 8A9B0C1D", - parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), + parents=("rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), ), ConfigLine( config_line=" 2E3F4A5B 6C7D8E9F 0A1B2C3D 4E5F6A7B 8C9D0E1F 2A3B4C5D 6E7F8A9B 0C1D2E3F", - parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), + parents=("rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), ), ConfigLine( config_line=" 1B2C3D4E 5F6A7B8C 9D0E1F2A 3B4C5D6E 7F8A9B0C 1D2E3F4A 5B6C7D8E 9F0A1B2C", - parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), + parents=("rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 12345678"), ), ConfigLine( - config_line=" 8810", parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01") + config_line=" 8810", parents=("rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01") ), ConfigLine( config_line=" FACED", - parents=(" rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 8810"), + parents=("rsa peer-public-key 192.0.2.5", " public-key-code begin", " ABCDEF01", " 8810"), ), - ConfigLine(config_line=" public-key-code end", parents=(" rsa peer-public-key 192.0.2.5",)), - ConfigLine(config_line=" peer-public-key end", parents=(" rsa peer-public-key 192.0.2.5",)), + ConfigLine(config_line=" public-key-code end", parents=("rsa peer-public-key 192.0.2.5",)), + ConfigLine(config_line=" peer-public-key end", parents=("rsa peer-public-key 192.0.2.5",)), ConfigLine(config_line="sysname NTC-Router", parents=()), ] diff --git a/tests/unit/mock/config/parser/base/hp_comware/hp_comware_special_sent.txt b/tests/unit/mock/config/parser/base/hp_comware/hp_comware_special_sent.txt index 0ab6910f..fa169a6d 100644 --- a/tests/unit/mock/config/parser/base/hp_comware/hp_comware_special_sent.txt +++ b/tests/unit/mock/config/parser/base/hp_comware/hp_comware_special_sent.txt @@ -2,15 +2,6 @@ vlan 10 name management description management vlan -vlan 15 - name users - description users vlan -vlan 16 - name phones - description phones vlan -vlan 20 - name servers vlan - description servers vlan # # Comment lines should be ignored # From 12e65b2e06575cb939113c09dd8247071c3ab5b1 Mon Sep 17 00:00:00 2001 From: Joe Wesch Date: Wed, 14 Jan 2026 14:11:16 -0600 Subject: [PATCH 3/5] Removed duplicate lines --- .../config/parser/base/hp_comware/hp_comware_full_received.py | 4 ---- .../config/parser/base/hp_comware/hp_comware_full_sent.txt | 4 ---- 2 files changed, 8 deletions(-) diff --git a/tests/unit/mock/config/parser/base/hp_comware/hp_comware_full_received.py b/tests/unit/mock/config/parser/base/hp_comware/hp_comware_full_received.py index cf8ef5d3..3e1e1e71 100644 --- a/tests/unit/mock/config/parser/base/hp_comware/hp_comware_full_received.py +++ b/tests/unit/mock/config/parser/base/hp_comware/hp_comware_full_received.py @@ -226,10 +226,6 @@ ConfigLine(config_line="ntp-service source M-GigabitEthernet0/0/0", parents=()), ConfigLine(config_line="ntp-service unicast-server 192.0.2.22 vpn-instance internal", parents=()), ConfigLine(config_line="ntp-service unicast-peer 192.0.2.10 vpn-instance internal", parents=()), - ConfigLine(config_line="ntp-service unicast-peer 192.0.2.10 vpn-instance internal", parents=()), - ConfigLine(config_line="ntp-service unicast-peer 192.0.2.10 vpn-instance internal", parents=()), - ConfigLine(config_line="ntp-service unicast-peer 192.0.2.10 vpn-instance internal", parents=()), - ConfigLine(config_line="ntp-service unicast-peer 192.0.2.10 vpn-instance internal", parents=()), ConfigLine(config_line="ntp-service unicast-server ntp.example.com vpn-instance internal", parents=()), ConfigLine(config_line="ntp-service unicast-server 192.0.2.27 vpn-instance internal", parents=()), ConfigLine(config_line="ntp-service unicast-server 192.0.2.70 vpn-instance internal", parents=()), diff --git a/tests/unit/mock/config/parser/base/hp_comware/hp_comware_full_sent.txt b/tests/unit/mock/config/parser/base/hp_comware/hp_comware_full_sent.txt index a5ca70ed..316bdf43 100644 --- a/tests/unit/mock/config/parser/base/hp_comware/hp_comware_full_sent.txt +++ b/tests/unit/mock/config/parser/base/hp_comware/hp_comware_full_sent.txt @@ -214,10 +214,6 @@ line vty 0 4 ntp-service source M-GigabitEthernet0/0/0 ntp-service unicast-server 192.0.2.22 vpn-instance internal ntp-service unicast-peer 192.0.2.10 vpn-instance internal - ntp-service unicast-peer 192.0.2.10 vpn-instance internal - ntp-service unicast-peer 192.0.2.10 vpn-instance internal - ntp-service unicast-peer 192.0.2.10 vpn-instance internal - ntp-service unicast-peer 192.0.2.10 vpn-instance internal ntp-service unicast-server ntp.example.com vpn-instance internal ntp-service unicast-server 192.0.2.27 vpn-instance internal ntp-service unicast-server 192.0.2.70 vpn-instance internal From d157f0f9a6b5a2bd5f84db366c4d8be46efc2f9b Mon Sep 17 00:00:00 2001 From: Joe Wesch Date: Wed, 14 Jan 2026 14:11:49 -0600 Subject: [PATCH 4/5] Changed parser to not require comment for new sections (for intended configs) --- netutils/config/parser.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/netutils/config/parser.py b/netutils/config/parser.py index d2123578..1c53617f 100644 --- a/netutils/config/parser.py +++ b/netutils/config/parser.py @@ -1754,6 +1754,9 @@ def build_config_relationship(self) -> t.List[ConfigLine]: current_spaces = self.get_leading_space_count(line) if line[0].isspace() else 0 if current_spaces == 0: + # Reset current parents and indent level for lines that are not indented. + self._current_parents = () + self.indent_level = 0 new_section = True if current_spaces > self.indent_level and not new_section: previous_config = self.config_lines[-1] From f141bdb5762055cf692e1c42f44e9681783c0ce6 Mon Sep 17 00:00:00 2001 From: Joe Wesch Date: Wed, 14 Jan 2026 14:11:57 -0600 Subject: [PATCH 5/5] Added compliance tests --- .../hp_comware/hp_comware_full_backup.txt | 280 ++++++++++++++ .../hp_comware/hp_comware_full_feature.py | 36 ++ .../hp_comware/hp_comware_full_intended.txt | 208 +++++++++++ .../hp_comware/hp_comware_full_received.json | 342 ++++++++++++++++++ 4 files changed, 866 insertions(+) create mode 100644 tests/unit/mock/config/compliance/compliance/hp_comware/hp_comware_full_backup.txt create mode 100644 tests/unit/mock/config/compliance/compliance/hp_comware/hp_comware_full_feature.py create mode 100644 tests/unit/mock/config/compliance/compliance/hp_comware/hp_comware_full_intended.txt create mode 100644 tests/unit/mock/config/compliance/compliance/hp_comware/hp_comware_full_received.json diff --git a/tests/unit/mock/config/compliance/compliance/hp_comware/hp_comware_full_backup.txt b/tests/unit/mock/config/compliance/compliance/hp_comware/hp_comware_full_backup.txt new file mode 100644 index 00000000..f65c71af --- /dev/null +++ b/tests/unit/mock/config/compliance/compliance/hp_comware/hp_comware_full_backup.txt @@ -0,0 +1,280 @@ +# +version 7.1.045, Release 2418P06 +# + sysname NTC123456 +# + clock timezone EST minus 05:00:00 + clock summer-time EDT 02:00:00 03/11 02:00:00 11/04 01:00:00 + clock protocol ntp +# + undo copyright-info enable +# +ip vpn-instance vpn1 + route-distinguisher 65001:1 + description vpn1 + vpn-target 65001:1 import-extcommunity + vpn-target 65001:1 export-extcommunity +# +ip vpn-instance internal + route-distinguisher 1:1 + description internal +# + telnet server enable + telnet server acl 1111 +# + irf domain 123456 + irf mac-address persistent timer + irf auto-update enable + undo irf link-delay + irf member 1 priority 32 + irf member 2 priority 1 + irf mode normal +# +igmp-snooping +# + dns source-interface M-GigabitEthernet0/0/0 vpn-instance internal + dns domain example.com + dns domain example.com vpn-instance internal + dns server 192.0.2.47 vpn-instance internal + dns server 192.0.2.15 vpn-instance internal + dns server 192.0.2.11 vpn-instance internal + dns server 192.0.2.2 vpn-instance internal + dns server 192.0.2.6 vpn-instance internal +# + lldp global enable +# + system-working-mode standard + password-recovery enable +# +vlan 1 +# +vlan 101 +# +irf-port 1/1 + port group interface FortyGigE1/0/49 + port group interface FortyGigE1/0/50 +# +irf-port 2/2 + port group interface FortyGigE2/0/49 + port group interface FortyGigE2/0/50 +# +qos map-table dot1p-lp + import 0 export 0 + import 1 export 1 + import 2 export 2 +# +traffic classifier NTC-Classifier operator or + if-match dscp ntc + if-match acl 4000 +# +traffic behavior NTC-Behavior + remark dscp ntc +# +traffic behavior foo +# +qos policy NTC-Policy + classifier NTC-Classifier behavior NTC-Behavior +# +stp region-configuration + region-name NTC-Region + revision-level 100 + instance 1 vlan 1 to 4094 + active region-configuration +# + stp instance 0 to 1 priority 16384 + stp vlan 1 to 4094 priority 16384 + stp mode pvst + stp bpdu-protection + stp global enable +# + l2vpn enable +# +interface NULL0 +# +interface LoopBack1 + ip binding vpn-instance internal + ip address 192.0.2.1 255.255.255.255 +# +interface Vlan-interface102 + shutdown + ip binding vpn-instance vpn2 + ip address 192.0.2.2 255.255.255.255 +# +interface Ten-GigabitEthernet1/0/1 + port link-mode bridge + description Test-Port-1 + undo enable snmp trap updown + undo enable log updown + port link-type trunk + undo port trunk permit vlan 1 + port trunk permit vlan 101 to 102 104 to 105 + port trunk pvid vlan 103 + stp edged-port + lldp agent nearest-customer admin-status txrx + sflow flow collector 1 + sflow sampling-rate 1000 + sflow counter collector 1 + sflow counter interval 2 + qos trust dscp + qos wfq weight + qos wfq af1 group 1 weight 2 + qos wfq af2 group 1 weight 2 + qos wfq af3 group 1 weight 4 + qos wfq ef group sp + qos wfq cs6 group sp + qos wfq cs7 group sp + qos bandwidth queue be min 500000 + qos bandwidth queue af1 min 500000 + qos bandwidth queue af2 min 2000000 + qos bandwidth queue af3 min 6500000 + qos bandwidth queue af4 min 100000 +# +bgp 65003 + router-id 192.0.2.31 + timer keepalive 5 hold 15 + # + ip vpn-instance vpn2 + peer 192.0.2.61 as-number 65006 + peer 192.0.2.61 connect-interface LoopBack1 + peer 192.0.2.61 ebgp-max-hop 3 + peer 192.0.2.61 password cipher + peer 192.0.2.62 as-number 65006 + peer 192.0.2.62 connect-interface LoopBack1 + peer 192.0.2.62 ebgp-max-hop 3 + # + address-family ipv4 unicast + network 192.0.2.31 255.255.255.255 + network 192.0.2.8 255.255.255.248 + network 192.0.2.0 255.255.255.240 + network 192.0.2.16 255.255.255.240 + network 192.0.2.32 255.255.255.240 + network 192.0.2.48 255.255.255.240 + network 192.0.2.64 255.255.255.240 + peer 192.0.2.61 enable + peer 192.0.2.61 next-hop-local + peer 192.0.2.62 enable + peer 192.0.2.62 next-hop-local +# + scheduler logfile size 16 +# +line class aux + user-role network-admin +# +line class vty + user-role network-operator +# +line aux 0 1 + authentication-mode scheme + user-role level-0 + idle-timeout 15 0 + command authorization +# +line vty 0 4 + authentication-mode scheme + user-role level-15 + user-role network-operator + protocol inbound ssh + idle-timeout 60 0 + command authorization +# + ip route-static vpn-instance vpn1 0.0.0.0 0 192.0.2.1 + ip route-static vpn-instance vpn2 192.0.2.61 32 192.0.2.68 description Test-Peer-2 + ip route-static vpn-instance vpn2 192.0.2.62 32 192.0.2.68 description Test-Peer-2 +# + info-center timestamp loghost no-year-date + undo info-center logfile enable + info-center loghost source M-GigabitEthernet0/0/0 + info-center loghost vpn-instance internal 192.0.2.132 + info-center loghost vpn-instance internal 192.0.2.227 + info-center loghost vpn-instance internal 192.0.2.18 + info-center loghost vpn-instance internal 192.0.2.195 +# + snmp-agent + snmp-agent local-engineid 123456789012345678901234567890 + snmp-agent community read Test-Community acl 1234 + snmp-agent sys-info contact Test-Contact + snmp-agent sys-info location Test-Location + snmp-agent sys-info version v2c v3 + snmp-agent trap source M-GigabitEthernet0/0/0 +# + ssh server enable + ssh server acl 1234 +# + ftp client source interface M-GigabitEthernet0/0/0 +# + ssh client source interface M-GigabitEthernet0/0/0 + sftp client source interface M-GigabitEthernet0/0/0 +# + qos vlan-policy NTC-VLAN-Policy-101 vlan 101 inbound + qos vlan-policy NTC-VLAN-Policy-102 vlan 102 inbound +# + ntp-service enable + ntp-service source M-GigabitEthernet0/0/0 + ntp-service unicast-server 192.0.2.22 vpn-instance internal + ntp-service unicast-peer 192.0.2.10 vpn-instance internal + ntp-service unicast-server 192.0.2.27 vpn-instance internal + ntp-service unicast-server 192.0.2.70 vpn-instance internal + ntp-service unicast-server 192.0.2.251 vpn-instance internal + ntp-service unicast-server 192.0.2.182 vpn-instance internal +# +acl number 1234 name NTC-ACL + rule 0 permit tcp destination 0.0.0.0 255.255.255.0 destination-port range 1000 2000 + rule 0 comment hello world +# + tftp client source interface M-GigabitEthernet0/0/0 +# + header motd % +******************************************************************************* +Unauthorized Access to or Use of this System is STRICTLY PROHIBITED. + ALL Access and Use May be Monitored and Recorded. +******************************************************************************* +% +# +hwtacacs scheme NTC-HWTACACS-Scheme + primary authentication 192.0.2.112 + primary authorization 192.0.2.112 + primary accounting 192.0.2.112 + secondary authentication 192.0.2.11 + secondary authorization 192.0.2.11 + secondary accounting 192.0.2.11 + key authentication cipher + key authorization cipher + key accounting cipher + user-name-format without-domain + vpn-instance internal +# +radius scheme system + user-name-format without-domain +# +domain example.com + authentication default hwtacacs-scheme NTC-HWTACACS-Scheme local + authorization default hwtacacs-scheme NTC-HWTACACS-Scheme local + accounting default hwtacacs-scheme NTC-HWTACACS-Scheme +# +domain system +# + domain default enable example.com +# +role name level-0 + description NTC-Level-0 role +# +role name level-1 + description NTC-Level-1 role +# +user-group system +# +local-user NTC-Admin class manage + password hash + service-type ssh telnet terminal + authorization-attribute user-role level-15 + authorization-attribute user-role network-admin + authorization-attribute user-role network-operator +# +local-user NTC-User class manage + password hash + service-type ssh telnet + authorization-attribute user-role level-15 + authorization-attribute user-role network-admin + authorization-attribute user-role network-operator +# +return \ No newline at end of file diff --git a/tests/unit/mock/config/compliance/compliance/hp_comware/hp_comware_full_feature.py b/tests/unit/mock/config/compliance/compliance/hp_comware/hp_comware_full_feature.py new file mode 100644 index 00000000..41fb5133 --- /dev/null +++ b/tests/unit/mock/config/compliance/compliance/hp_comware/hp_comware_full_feature.py @@ -0,0 +1,36 @@ +features = [ + {"name": "sysname", "ordered": False, "section": ["sysname"]}, + {"name": "clock", "ordered": False, "section": ["clock"]}, + {"name": "copyright-info", "ordered": False, "section": ["copyright-info", "undo copyright-info"]}, + {"name": "telnet", "ordered": False, "section": ["telnet"]}, + {"name": "irf", "ordered": False, "section": ["irf", "undo irf"]}, + {"name": "igmp", "ordered": False, "section": ["igmp"]}, + {"name": "dns", "ordered": False, "section": ["dns"]}, + {"name": "lldp", "ordered": False, "section": ["lldp"]}, + {"name": "password-recovery", "ordered": False, "section": ["password-recovery"]}, + {"name": "vlan", "ordered": False, "section": ["vlan"]}, + {"name": "irf-port", "ordered": False, "section": ["irf-port"]}, + {"name": "qos map-table", "ordered": False, "section": ["qos map-table"]}, + {"name": "qos policy", "ordered": False, "section": ["qos policy"]}, + {"name": "qos vlan-policy", "ordered": False, "section": ["qos vlan-policy"]}, + {"name": "stp", "ordered": False, "section": ["stp"]}, + {"name": "l2vpn", "ordered": False, "section": ["l2vpn"]}, + {"name": "bgp", "ordered": False, "section": ["bgp"]}, + {"name": "line", "ordered": False, "section": ["line"]}, + {"name": "ip route-static", "ordered": False, "section": ["ip route-static"]}, + {"name": "info-center", "ordered": False, "section": ["info-center", "undo info-center"]}, + {"name": "snmp", "ordered": False, "section": ["snmp"]}, + {"name": "ssh", "ordered": False, "section": ["ssh"]}, + {"name": "ftp", "ordered": False, "section": ["ftp"]}, + {"name": "sftp", "ordered": False, "section": ["sftp"]}, + {"name": "ntp", "ordered": False, "section": ["ntp"]}, + {"name": "acl", "ordered": True, "section": ["acl"]}, + {"name": "tftp", "ordered": False, "section": ["tftp"]}, + {"name": "header", "ordered": False, "section": ["header"]}, + {"name": "hwtacacs", "ordered": False, "section": ["hwtacacs"]}, + {"name": "radius", "ordered": False, "section": ["radius"]}, + {"name": "domain", "ordered": False, "section": ["domain"]}, + {"name": "role", "ordered": False, "section": ["role"]}, + {"name": "user-group", "ordered": False, "section": ["user-group"]}, + {"name": "local-user", "ordered": False, "section": ["local-user"]}, +] diff --git a/tests/unit/mock/config/compliance/compliance/hp_comware/hp_comware_full_intended.txt b/tests/unit/mock/config/compliance/compliance/hp_comware/hp_comware_full_intended.txt new file mode 100644 index 00000000..64c1eb93 --- /dev/null +++ b/tests/unit/mock/config/compliance/compliance/hp_comware/hp_comware_full_intended.txt @@ -0,0 +1,208 @@ +# +sysname NTC-Router +# +clock timezone EST minus 05:00:00 +clock summer-time EDT 02:00:00 03/11 02:00:00 11/04 01:00:00 +clock protocol ntp +# +copyright-info enable +# +telnet server enable +telnet server acl 1111 +# +irf domain 123456 +irf mac-address persistent timer +irf auto-update enable +undo irf link-delay +irf member 1 priority 48 +irf member 3 priority 16 +irf mode normal +# +igmp-snooping +# +dns source-interface M-GigabitEthernet0/0/0 vpn-instance internal +dns domain example.com +dns domain example.com vpn-instance internal +dns server 192.0.2.47 vpn-instance internal +dns server 192.0.2.15 vpn-instance internal +dns server 192.0.2.11 vpn-instance internal +dns server 192.0.2.2 vpn-instance internal +dns server 192.0.2.6 vpn-instance internal +# +lldp global enable +# +password-recovery enable +# +vlan 1 +vlan 101 + name Test-Vlan-101 + description Test Vlan 101 +# +irf-port 1/1 + port group interface FortyGigE1/0/49 + port group interface FortyGigE1/0/50 +irf-port 2/2 + port group interface FortyGigE2/0/49 + port group interface FortyGigE2/0/50 +# +qos map-table dot1p-lp + import 0 export 0 + import 1 export 1 + import 2 export 2 +# +traffic classifier NTC-Classifier operator or + if-match dscp ntc + if-match acl 4000 +# +traffic behavior NTC-Behavior + remark dscp ntc +traffic behavior foo +# +qos policy NTC-Policy + classifier NTC-Classifier behavior NTC-Behavior +# +stp region-configuration + region-name NTC-Region + revision-level 100 + instance 1 vlan 1 to 4094 + active region-configuration +# +stp instance 0 to 1 priority 16384 +stp vlan 1 to 4094 priority 16384 +stp mode pvst +stp bpdu-protection +stp global enable +# +l2vpn enable +# +bgp 65003 + router-id 192.0.2.31 + timer keepalive 5 hold 15 + ip vpn-instance vpn2 + peer 192.0.2.61 as-number 65007 + peer 192.0.2.61 connect-interface LoopBack1 + peer 192.0.2.61 ebgp-max-hop 4 + peer 192.0.2.61 password cipher + peer 192.0.2.62 as-number 65007 + peer 192.0.2.62 connect-interface LoopBack1 + peer 192.0.2.62 ebgp-max-hop 4 + address-family ipv4 unicast + network 192.0.2.31 255.255.255.255 + network 192.0.2.64 255.255.255.240 + peer 192.0.2.61 enable + peer 192.0.2.61 next-hop-local + peer 192.0.2.62 enable + peer 192.0.2.62 next-hop-local +# +line class aux + user-role network-admin +line class vty + user-role network-operator +line aux 0 1 + authentication-mode scheme + user-role level-0 + idle-timeout 15 0 + command authorization +line vty 0 4 + authentication-mode scheme + user-role level-15 + user-role network-operator + protocol inbound ssh + idle-timeout 60 0 + command authorization +# +ip route-static vpn-instance vpn1 0.0.0.0 0 192.0.2.1 +ip route-static vpn-instance vpn2 192.0.2.61 32 192.0.2.68 description Test-Peer-2 +ip route-static vpn-instance vpn2 192.0.2.62 32 192.0.2.68 description Test-Peer-2 +# +info-center timestamp loghost no-year-date +info-center logfile enable +info-center loghost source M-GigabitEthernet0/0/0 +info-center loghost vpn-instance internal 192.0.2.195 +# +snmp-agent +snmp-agent local-engineid 123456789012345678901234567890 +snmp-agent community read Test-Community acl 1234 +snmp-agent sys-info contact Test-Contact +snmp-agent sys-info location Test-Location +snmp-agent sys-info version v2c v3 +snmp-agent trap source M-GigabitEthernet0/0/0 +# +ssh server enable +ssh server acl 1234 +# +ftp client source interface M-GigabitEthernet0/0/0 +# +ssh client source interface M-GigabitEthernet0/0/0 +sftp client source interface M-GigabitEthernet0/0/0 +# +qos vlan-policy NTC-VLAN-Policy-101 vlan 101 inbound +qos vlan-policy NTC-VLAN-Policy-102 vlan 102 inbound +# +ntp-service enable +ntp-service source M-GigabitEthernet0/0/0 +ntp-service unicast-server 192.0.2.22 vpn-instance internal +ntp-service unicast-peer 192.0.2.10 vpn-instance internal +ntp-service unicast-server ntp.example.com vpn-instance internal +ntp-service unicast-server 192.0.2.27 vpn-instance internal +ntp-service unicast-server 192.0.2.70 vpn-instance internal +ntp-service unicast-server 192.0.2.251 vpn-instance internal +ntp-service unicast-server 192.0.2.182 vpn-instance internal +# +acl number 1234 name NTC-ACL + rule 0 permit icmp destination 0.0.0.0 255.255.255.0 + rule 1 permit tcp destination 0.0.0.0 255.255.255.0 destination-port range 1000 2000 + rule 1 comment hello world +# +tftp client source interface M-GigabitEthernet0/0/0 +# +header motd % +******************************************************************************* +Unauthorized Access to or Use of this System is STRICTLY PROHIBITED. + ALL Access and Use May be Monitored and Recorded. +******************************************************************************* +% +# +hwtacacs scheme NTC-HWTACACS-Scheme + primary authentication 192.0.2.112 + primary authorization 192.0.2.112 + primary accounting 192.0.2.112 + secondary authentication 192.0.2.11 + secondary authorization 192.0.2.11 + secondary accounting 192.0.2.11 + key authentication cipher + key authorization cipher + key accounting cipher + user-name-format without-domain + vpn-instance internal +# +radius scheme system + user-name-format without-domain +# +domain example.com + authentication default hwtacacs-scheme NTC-HWTACACS-Scheme local + authorization default hwtacacs-scheme NTC-HWTACACS-Scheme local + accounting default hwtacacs-scheme NTC-HWTACACS-Scheme +domain system +domain default enable example.com +# +role name level-0 + description NTC-Level-0 role +role name level-1 + description NTC-Level-1 role +# +user-group system +# +local-user NTC-Admin class manage + password hash + service-type ssh telnet terminal + authorization-attribute user-role level-15 + authorization-attribute user-role network-admin + authorization-attribute user-role network-operator +local-user NTC-User class manage + password hash + service-type ssh telnet + authorization-attribute user-role level-15 + authorization-attribute user-role network-admin + authorization-attribute user-role network-operator +# \ No newline at end of file diff --git a/tests/unit/mock/config/compliance/compliance/hp_comware/hp_comware_full_received.json b/tests/unit/mock/config/compliance/compliance/hp_comware/hp_comware_full_received.json new file mode 100644 index 00000000..7ae8cd9b --- /dev/null +++ b/tests/unit/mock/config/compliance/compliance/hp_comware/hp_comware_full_received.json @@ -0,0 +1,342 @@ +{ + "sysname": { + "compliant": false, + "missing": "sysname NTC-Router", + "extra": "sysname NTC123456", + "cannot_parse": true, + "unordered_compliant": false, + "ordered_compliant": false, + "actual": "sysname NTC123456", + "intended": "sysname NTC-Router" + }, + "clock": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "clock timezone EST minus 05:00:00\nclock summer-time EDT 02:00:00 03/11 02:00:00 11/04 01:00:00\nclock protocol ntp", + "intended": "clock timezone EST minus 05:00:00\nclock summer-time EDT 02:00:00 03/11 02:00:00 11/04 01:00:00\nclock protocol ntp" + }, + "copyright-info": { + "compliant": false, + "missing": "copyright-info enable", + "extra": "undo copyright-info enable", + "cannot_parse": true, + "unordered_compliant": false, + "ordered_compliant": false, + "actual": "undo copyright-info enable", + "intended": "copyright-info enable" + }, + "telnet": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "telnet server enable\ntelnet server acl 1111", + "intended": "telnet server enable\ntelnet server acl 1111" + }, + "irf": { + "compliant": false, + "missing": "irf member 1 priority 48\nirf member 3 priority 16", + "extra": "irf member 1 priority 32\nirf member 2 priority 1", + "cannot_parse": true, + "unordered_compliant": false, + "ordered_compliant": false, + "actual": "irf domain 123456\nirf mac-address persistent timer\nirf auto-update enable\nundo irf link-delay\nirf member 1 priority 32\nirf member 2 priority 1\nirf mode normal\nirf-port 1/1\n port group interface FortyGigE1/0/49\n port group interface FortyGigE1/0/50\nirf-port 2/2\n port group interface FortyGigE2/0/49\n port group interface FortyGigE2/0/50", + "intended": "irf domain 123456\nirf mac-address persistent timer\nirf auto-update enable\nundo irf link-delay\nirf member 1 priority 48\nirf member 3 priority 16\nirf mode normal\nirf-port 1/1\n port group interface FortyGigE1/0/49\n port group interface FortyGigE1/0/50\nirf-port 2/2\n port group interface FortyGigE2/0/49\n port group interface FortyGigE2/0/50" + }, + "igmp": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "igmp-snooping", + "intended": "igmp-snooping" + }, + "dns": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "dns source-interface M-GigabitEthernet0/0/0 vpn-instance internal\ndns domain example.com\ndns domain example.com vpn-instance internal\ndns server 192.0.2.47 vpn-instance internal\ndns server 192.0.2.15 vpn-instance internal\ndns server 192.0.2.11 vpn-instance internal\ndns server 192.0.2.2 vpn-instance internal\ndns server 192.0.2.6 vpn-instance internal", + "intended": "dns source-interface M-GigabitEthernet0/0/0 vpn-instance internal\ndns domain example.com\ndns domain example.com vpn-instance internal\ndns server 192.0.2.47 vpn-instance internal\ndns server 192.0.2.15 vpn-instance internal\ndns server 192.0.2.11 vpn-instance internal\ndns server 192.0.2.2 vpn-instance internal\ndns server 192.0.2.6 vpn-instance internal" + }, + "lldp": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "lldp global enable", + "intended": "lldp global enable" + }, + "password-recovery": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "password-recovery enable", + "intended": "password-recovery enable" + }, + "vlan": { + "compliant": false, + "missing": "vlan 101\n name Test-Vlan-101\n description Test Vlan 101", + "extra": "", + "cannot_parse": true, + "unordered_compliant": false, + "ordered_compliant": false, + "actual": "vlan 1\nvlan 101", + "intended": "vlan 1\nvlan 101\n name Test-Vlan-101\n description Test Vlan 101" + }, + "irf-port": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "irf-port 1/1\n port group interface FortyGigE1/0/49\n port group interface FortyGigE1/0/50\nirf-port 2/2\n port group interface FortyGigE2/0/49\n port group interface FortyGigE2/0/50", + "intended": "irf-port 1/1\n port group interface FortyGigE1/0/49\n port group interface FortyGigE1/0/50\nirf-port 2/2\n port group interface FortyGigE2/0/49\n port group interface FortyGigE2/0/50" + }, + "qos map-table": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "qos map-table dot1p-lp\n import 0 export 0\n import 1 export 1\n import 2 export 2", + "intended": "qos map-table dot1p-lp\n import 0 export 0\n import 1 export 1\n import 2 export 2" + }, + "qos policy": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "qos policy NTC-Policy\n classifier NTC-Classifier behavior NTC-Behavior", + "intended": "qos policy NTC-Policy\n classifier NTC-Classifier behavior NTC-Behavior" + }, + "qos vlan-policy": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "qos vlan-policy NTC-VLAN-Policy-101 vlan 101 inbound\nqos vlan-policy NTC-VLAN-Policy-102 vlan 102 inbound", + "intended": "qos vlan-policy NTC-VLAN-Policy-101 vlan 101 inbound\nqos vlan-policy NTC-VLAN-Policy-102 vlan 102 inbound" + }, + "stp": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "stp region-configuration\n region-name NTC-Region\n revision-level 100\n instance 1 vlan 1 to 4094\n active region-configuration\nstp instance 0 to 1 priority 16384\nstp vlan 1 to 4094 priority 16384\nstp mode pvst\nstp bpdu-protection\nstp global enable", + "intended": "stp region-configuration\n region-name NTC-Region\n revision-level 100\n instance 1 vlan 1 to 4094\n active region-configuration\nstp instance 0 to 1 priority 16384\nstp vlan 1 to 4094 priority 16384\nstp mode pvst\nstp bpdu-protection\nstp global enable" + }, + "l2vpn": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "l2vpn enable", + "intended": "l2vpn enable" + }, + "bgp": { + "compliant": false, + "missing": "bgp 65003\n ip vpn-instance vpn2\n peer 192.0.2.61 as-number 65007\n peer 192.0.2.61 ebgp-max-hop 4\n peer 192.0.2.62 as-number 65007\n peer 192.0.2.62 ebgp-max-hop 4", + "extra": "bgp 65003\n ip vpn-instance vpn2\n peer 192.0.2.61 as-number 65006\n peer 192.0.2.61 ebgp-max-hop 3\n peer 192.0.2.62 as-number 65006\n peer 192.0.2.62 ebgp-max-hop 3\n address-family ipv4 unicast\n network 192.0.2.8 255.255.255.248\n network 192.0.2.0 255.255.255.240\n network 192.0.2.16 255.255.255.240\n network 192.0.2.32 255.255.255.240\n network 192.0.2.48 255.255.255.240", + "cannot_parse": true, + "unordered_compliant": false, + "ordered_compliant": false, + "actual": "bgp 65003\n router-id 192.0.2.31\n timer keepalive 5 hold 15\n ip vpn-instance vpn2\n peer 192.0.2.61 as-number 65006\n peer 192.0.2.61 connect-interface LoopBack1\n peer 192.0.2.61 ebgp-max-hop 3\n peer 192.0.2.61 password cipher \n peer 192.0.2.62 as-number 65006\n peer 192.0.2.62 connect-interface LoopBack1\n peer 192.0.2.62 ebgp-max-hop 3\n address-family ipv4 unicast\n network 192.0.2.31 255.255.255.255\n network 192.0.2.8 255.255.255.248\n network 192.0.2.0 255.255.255.240\n network 192.0.2.16 255.255.255.240\n network 192.0.2.32 255.255.255.240\n network 192.0.2.48 255.255.255.240\n network 192.0.2.64 255.255.255.240\n peer 192.0.2.61 enable\n peer 192.0.2.61 next-hop-local\n peer 192.0.2.62 enable\n peer 192.0.2.62 next-hop-local", + "intended": "bgp 65003\n router-id 192.0.2.31\n timer keepalive 5 hold 15\n ip vpn-instance vpn2\n peer 192.0.2.61 as-number 65007\n peer 192.0.2.61 connect-interface LoopBack1\n peer 192.0.2.61 ebgp-max-hop 4\n peer 192.0.2.61 password cipher \n peer 192.0.2.62 as-number 65007\n peer 192.0.2.62 connect-interface LoopBack1\n peer 192.0.2.62 ebgp-max-hop 4\n address-family ipv4 unicast\n network 192.0.2.31 255.255.255.255\n network 192.0.2.64 255.255.255.240\n peer 192.0.2.61 enable\n peer 192.0.2.61 next-hop-local\n peer 192.0.2.62 enable\n peer 192.0.2.62 next-hop-local" + }, + "line": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "line class aux\n user-role network-admin\nline class vty\n user-role network-operator\nline aux 0 1\n authentication-mode scheme\n user-role level-0\n idle-timeout 15 0\n command authorization\nline vty 0 4\n authentication-mode scheme\n user-role level-15\n user-role network-operator\n protocol inbound ssh\n idle-timeout 60 0\n command authorization", + "intended": "line class aux\n user-role network-admin\nline class vty\n user-role network-operator\nline aux 0 1\n authentication-mode scheme\n user-role level-0\n idle-timeout 15 0\n command authorization\nline vty 0 4\n authentication-mode scheme\n user-role level-15\n user-role network-operator\n protocol inbound ssh\n idle-timeout 60 0\n command authorization" + }, + "ip route-static": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "ip route-static vpn-instance vpn1 0.0.0.0 0 192.0.2.1\nip route-static vpn-instance vpn2 192.0.2.61 32 192.0.2.68 description Test-Peer-2\nip route-static vpn-instance vpn2 192.0.2.62 32 192.0.2.68 description Test-Peer-2", + "intended": "ip route-static vpn-instance vpn1 0.0.0.0 0 192.0.2.1\nip route-static vpn-instance vpn2 192.0.2.61 32 192.0.2.68 description Test-Peer-2\nip route-static vpn-instance vpn2 192.0.2.62 32 192.0.2.68 description Test-Peer-2" + }, + "info-center": { + "compliant": false, + "missing": "info-center logfile enable", + "extra": "undo info-center logfile enable\ninfo-center loghost vpn-instance internal 192.0.2.132\ninfo-center loghost vpn-instance internal 192.0.2.227\ninfo-center loghost vpn-instance internal 192.0.2.18", + "cannot_parse": true, + "unordered_compliant": false, + "ordered_compliant": false, + "actual": "info-center timestamp loghost no-year-date\nundo info-center logfile enable\ninfo-center loghost source M-GigabitEthernet0/0/0\ninfo-center loghost vpn-instance internal 192.0.2.132\ninfo-center loghost vpn-instance internal 192.0.2.227\ninfo-center loghost vpn-instance internal 192.0.2.18\ninfo-center loghost vpn-instance internal 192.0.2.195", + "intended": "info-center timestamp loghost no-year-date\ninfo-center logfile enable\ninfo-center loghost source M-GigabitEthernet0/0/0\ninfo-center loghost vpn-instance internal 192.0.2.195" + }, + "snmp": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "snmp-agent\nsnmp-agent local-engineid 123456789012345678901234567890\nsnmp-agent community read Test-Community acl 1234\nsnmp-agent sys-info contact Test-Contact\nsnmp-agent sys-info location Test-Location\nsnmp-agent sys-info version v2c v3\nsnmp-agent trap source M-GigabitEthernet0/0/0", + "intended": "snmp-agent\nsnmp-agent local-engineid 123456789012345678901234567890\nsnmp-agent community read Test-Community acl 1234\nsnmp-agent sys-info contact Test-Contact\nsnmp-agent sys-info location Test-Location\nsnmp-agent sys-info version v2c v3\nsnmp-agent trap source M-GigabitEthernet0/0/0" + }, + "ssh": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "ssh server enable\nssh server acl 1234\nssh client source interface M-GigabitEthernet0/0/0", + "intended": "ssh server enable\nssh server acl 1234\nssh client source interface M-GigabitEthernet0/0/0" + }, + "ftp": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "ftp client source interface M-GigabitEthernet0/0/0", + "intended": "ftp client source interface M-GigabitEthernet0/0/0" + }, + "sftp": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "sftp client source interface M-GigabitEthernet0/0/0", + "intended": "sftp client source interface M-GigabitEthernet0/0/0" + }, + "ntp": { + "compliant": false, + "missing": "ntp-service unicast-server ntp.example.com vpn-instance internal", + "extra": "", + "cannot_parse": true, + "unordered_compliant": false, + "ordered_compliant": false, + "actual": "ntp-service enable\nntp-service source M-GigabitEthernet0/0/0\nntp-service unicast-server 192.0.2.22 vpn-instance internal\nntp-service unicast-peer 192.0.2.10 vpn-instance internal\nntp-service unicast-server 192.0.2.27 vpn-instance internal\nntp-service unicast-server 192.0.2.70 vpn-instance internal\nntp-service unicast-server 192.0.2.251 vpn-instance internal\nntp-service unicast-server 192.0.2.182 vpn-instance internal", + "intended": "ntp-service enable\nntp-service source M-GigabitEthernet0/0/0\nntp-service unicast-server 192.0.2.22 vpn-instance internal\nntp-service unicast-peer 192.0.2.10 vpn-instance internal\nntp-service unicast-server ntp.example.com vpn-instance internal\nntp-service unicast-server 192.0.2.27 vpn-instance internal\nntp-service unicast-server 192.0.2.70 vpn-instance internal\nntp-service unicast-server 192.0.2.251 vpn-instance internal\nntp-service unicast-server 192.0.2.182 vpn-instance internal" + }, + "acl": { + "compliant": false, + "missing": "acl number 1234 name NTC-ACL\n rule 0 permit icmp destination 0.0.0.0 255.255.255.0\n rule 1 permit tcp destination 0.0.0.0 255.255.255.0 destination-port range 1000 2000\n rule 1 comment hello world", + "extra": "acl number 1234 name NTC-ACL\n rule 0 permit tcp destination 0.0.0.0 255.255.255.0 destination-port range 1000 2000\n rule 0 comment hello world", + "cannot_parse": true, + "unordered_compliant": false, + "ordered_compliant": false, + "actual": "acl number 1234 name NTC-ACL\n rule 0 permit tcp destination 0.0.0.0 255.255.255.0 destination-port range 1000 2000\n rule 0 comment hello world", + "intended": "acl number 1234 name NTC-ACL\n rule 0 permit icmp destination 0.0.0.0 255.255.255.0\n rule 1 permit tcp destination 0.0.0.0 255.255.255.0 destination-port range 1000 2000\n rule 1 comment hello world" + }, + "tftp": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "tftp client source interface M-GigabitEthernet0/0/0", + "intended": "tftp client source interface M-GigabitEthernet0/0/0" + }, + "header": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "header motd %\n*******************************************************************************\nUnauthorized Access to or Use of this System is STRICTLY PROHIBITED.\n ALL Access and Use May be Monitored and Recorded.\n*******************************************************************************\n%", + "intended": "header motd %\n*******************************************************************************\nUnauthorized Access to or Use of this System is STRICTLY PROHIBITED.\n ALL Access and Use May be Monitored and Recorded.\n*******************************************************************************\n%" + }, + "hwtacacs": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "hwtacacs scheme NTC-HWTACACS-Scheme\n primary authentication 192.0.2.112\n primary authorization 192.0.2.112\n primary accounting 192.0.2.112\n secondary authentication 192.0.2.11\n secondary authorization 192.0.2.11\n secondary accounting 192.0.2.11\n key authentication cipher \n key authorization cipher \n key accounting cipher \n user-name-format without-domain\n vpn-instance internal", + "intended": "hwtacacs scheme NTC-HWTACACS-Scheme\n primary authentication 192.0.2.112\n primary authorization 192.0.2.112\n primary accounting 192.0.2.112\n secondary authentication 192.0.2.11\n secondary authorization 192.0.2.11\n secondary accounting 192.0.2.11\n key authentication cipher \n key authorization cipher \n key accounting cipher \n user-name-format without-domain\n vpn-instance internal" + }, + "radius": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "radius scheme system\n user-name-format without-domain", + "intended": "radius scheme system\n user-name-format without-domain" + }, + "domain": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "domain example.com\n authentication default hwtacacs-scheme NTC-HWTACACS-Scheme local\n authorization default hwtacacs-scheme NTC-HWTACACS-Scheme local\n accounting default hwtacacs-scheme NTC-HWTACACS-Scheme\ndomain system\ndomain default enable example.com", + "intended": "domain example.com\n authentication default hwtacacs-scheme NTC-HWTACACS-Scheme local\n authorization default hwtacacs-scheme NTC-HWTACACS-Scheme local\n accounting default hwtacacs-scheme NTC-HWTACACS-Scheme\ndomain system\ndomain default enable example.com" + }, + "role": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "role name level-0\n description NTC-Level-0 role\nrole name level-1\n description NTC-Level-1 role", + "intended": "role name level-0\n description NTC-Level-0 role\nrole name level-1\n description NTC-Level-1 role" + }, + "user-group": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "user-group system", + "intended": "user-group system" + }, + "local-user": { + "compliant": true, + "missing": "", + "extra": "", + "cannot_parse": true, + "unordered_compliant": true, + "ordered_compliant": true, + "actual": "local-user NTC-Admin class manage\n password hash \n service-type ssh telnet terminal\n authorization-attribute user-role level-15\n authorization-attribute user-role network-admin\n authorization-attribute user-role network-operator\nlocal-user NTC-User class manage\n password hash \n service-type ssh telnet\n authorization-attribute user-role level-15\n authorization-attribute user-role network-admin\n authorization-attribute user-role network-operator", + "intended": "local-user NTC-Admin class manage\n password hash \n service-type ssh telnet terminal\n authorization-attribute user-role level-15\n authorization-attribute user-role network-admin\n authorization-attribute user-role network-operator\nlocal-user NTC-User class manage\n password hash \n service-type ssh telnet\n authorization-attribute user-role level-15\n authorization-attribute user-role network-admin\n authorization-attribute user-role network-operator" + } +} \ No newline at end of file