From fe916a0846c211c0fb8d6790e6f9f9141ac0f862 Mon Sep 17 00:00:00 2001 From: julmanglano Date: Fri, 16 May 2025 15:40:01 +0200 Subject: [PATCH 1/4] Catching leading spaces at config start --- netutils/config/parser.py | 21 ++++++++++++++++----- tests/unit/test_parser.py | 17 +++++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/netutils/config/parser.py b/netutils/config/parser.py index 4876672f..a0a05acc 100644 --- a/netutils/config/parser.py +++ b/netutils/config/parser.py @@ -311,8 +311,11 @@ def build_config_relationship(self) -> t.List[ConfigLine]: ... ] True """ - for line in self.generator_config: - if not line[0].isspace(): + for index, line in enumerate(self.generator_config): + current_spaces = self.get_leading_space_count(line) if line[0].isspace() else 0 + if index == 0 and line[0].isspace(): + line = self._remove_parents(line, current_spaces) + elif not line[0].isspace(): self._current_parents = () if self.is_banner_start(line): line = self._build_banner(line) # type: ignore @@ -985,8 +988,11 @@ def build_config_relationship(self) -> t.List[ConfigLine]: ... ] True """ - for line in self.generator_config: - if not line[0].isspace(): + for index, line in enumerate(self.generator_config): + current_spaces = self.get_leading_space_count(line) if line[0].isspace() else 0 + if index == 0 and line[0].isspace(): + line = self._remove_parents(line, current_spaces) + elif not line[0].isspace(): self._current_parents = () else: previous_config = self.config_lines[-1] @@ -1383,7 +1389,12 @@ def build_config_relationship(self) -> t.List[ConfigLine]: ... ] True """ - for line in self.generator_config: + + for index, line in enumerate(self.generator_config): + current_spaces = self.get_leading_space_count(line) if line[0].isspace() else 0 + + if index == 0 and line[0].isspace(): + line = self._remove_parents(line, current_spaces) if not line[0].isspace(): self._current_parents = () if self.is_banner_start(line): diff --git a/tests/unit/test_parser.py b/tests/unit/test_parser.py index 26a50963..395b9c16 100644 --- a/tests/unit/test_parser.py +++ b/tests/unit/test_parser.py @@ -80,3 +80,20 @@ def test_duplicate_line(): ) with pytest.raises(IndexError, match=r".*This error is likely from a duplicate line detected.*"): compliance.parser_map["cisco_ios"](logging).config_lines # pylint: disable=expression-not-assigned +def test_leading_spaces_config_start(): + logging = ( + "! Command: show running-config\n" + " 24.1.4\n" + "!\n" + "no aaa root\n" + "!\n" + "management api http-commands\n" + " no shutdown\n" + "no service interface inactive port-id allocation disabled\n" + "transceiver qsfp default-mode 4x10G\n" + ) + with pytest.raises(IndexError, match=r".*Validate the first line does not begin with a space.*"): + compliance.parser_map["cisco_ios"](logging).config_lines # pylint: disable=expression-not-assigned + compliance.parser_map["arista_eos"](logging).config_lines # pylint: disable=expression-not-assigned + compliance.parser_map["cisco_xr"](logging).config_lines # pylint: disable=expression-not-assigned + \ No newline at end of file From 5f335270d49bb6464cdcf1b3129da8acb6f8114e Mon Sep 17 00:00:00 2001 From: julmanglano Date: Fri, 16 May 2025 16:31:31 +0200 Subject: [PATCH 2/4] spacing tests --- tests/unit/test_parser.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/unit/test_parser.py b/tests/unit/test_parser.py index 395b9c16..5a0450c5 100644 --- a/tests/unit/test_parser.py +++ b/tests/unit/test_parser.py @@ -80,6 +80,8 @@ def test_duplicate_line(): ) with pytest.raises(IndexError, match=r".*This error is likely from a duplicate line detected.*"): compliance.parser_map["cisco_ios"](logging).config_lines # pylint: disable=expression-not-assigned + + def test_leading_spaces_config_start(): logging = ( "! Command: show running-config\n" From 894bec20a506158c50ed447c8013675671312c6e Mon Sep 17 00:00:00 2001 From: julmanglano Date: Fri, 16 May 2025 16:38:26 +0200 Subject: [PATCH 3/4] after black --- netutils/config/parser.py | 6 +++--- tests/unit/test_parser.py | 9 ++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/netutils/config/parser.py b/netutils/config/parser.py index a0a05acc..e897ae66 100644 --- a/netutils/config/parser.py +++ b/netutils/config/parser.py @@ -1389,12 +1389,12 @@ def build_config_relationship(self) -> t.List[ConfigLine]: ... ] True """ - + for index, line in enumerate(self.generator_config): current_spaces = self.get_leading_space_count(line) if line[0].isspace() else 0 - + if index == 0 and line[0].isspace(): - line = self._remove_parents(line, current_spaces) + line = self._remove_parents(line, current_spaces) if not line[0].isspace(): self._current_parents = () if self.is_banner_start(line): diff --git a/tests/unit/test_parser.py b/tests/unit/test_parser.py index 5a0450c5..208cfbb0 100644 --- a/tests/unit/test_parser.py +++ b/tests/unit/test_parser.py @@ -80,10 +80,10 @@ def test_duplicate_line(): ) with pytest.raises(IndexError, match=r".*This error is likely from a duplicate line detected.*"): compliance.parser_map["cisco_ios"](logging).config_lines # pylint: disable=expression-not-assigned - - + + def test_leading_spaces_config_start(): - logging = ( + logging = ( "! Command: show running-config\n" " 24.1.4\n" "!\n" @@ -93,9 +93,8 @@ def test_leading_spaces_config_start(): " no shutdown\n" "no service interface inactive port-id allocation disabled\n" "transceiver qsfp default-mode 4x10G\n" - ) + ) with pytest.raises(IndexError, match=r".*Validate the first line does not begin with a space.*"): compliance.parser_map["cisco_ios"](logging).config_lines # pylint: disable=expression-not-assigned compliance.parser_map["arista_eos"](logging).config_lines # pylint: disable=expression-not-assigned compliance.parser_map["cisco_xr"](logging).config_lines # pylint: disable=expression-not-assigned - \ No newline at end of file From 904eadbe5c9f36cf6566a33adbc2ea4fc8dd1d53 Mon Sep 17 00:00:00 2001 From: julmanglano Date: Mon, 19 May 2025 17:29:03 +0200 Subject: [PATCH 4/4] remoing wrong variable assigment --- netutils/config/parser.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/netutils/config/parser.py b/netutils/config/parser.py index e897ae66..cc7b6e16 100644 --- a/netutils/config/parser.py +++ b/netutils/config/parser.py @@ -314,7 +314,7 @@ def build_config_relationship(self) -> t.List[ConfigLine]: for index, line in enumerate(self.generator_config): current_spaces = self.get_leading_space_count(line) if line[0].isspace() else 0 if index == 0 and line[0].isspace(): - line = self._remove_parents(line, current_spaces) + self._current_parents = self._remove_parents(line, current_spaces) elif not line[0].isspace(): self._current_parents = () if self.is_banner_start(line): @@ -991,7 +991,7 @@ def build_config_relationship(self) -> t.List[ConfigLine]: for index, line in enumerate(self.generator_config): current_spaces = self.get_leading_space_count(line) if line[0].isspace() else 0 if index == 0 and line[0].isspace(): - line = self._remove_parents(line, current_spaces) + self._current_parents = self._remove_parents(line, current_spaces) elif not line[0].isspace(): self._current_parents = () else: @@ -1389,12 +1389,11 @@ def build_config_relationship(self) -> t.List[ConfigLine]: ... ] True """ - for index, line in enumerate(self.generator_config): current_spaces = self.get_leading_space_count(line) if line[0].isspace() else 0 if index == 0 and line[0].isspace(): - line = self._remove_parents(line, current_spaces) + self._current_parents = self._remove_parents(line, current_spaces) if not line[0].isspace(): self._current_parents = () if self.is_banner_start(line):