From 0d09787837ae58edc2f27a1c57c6817a79c5df07 Mon Sep 17 00:00:00 2001 From: hetangmodi-crest Date: Tue, 6 Aug 2024 16:17:45 +0530 Subject: [PATCH 1/3] fix: handle default stanza for Splunk conf files --- addonfactory_splunk_conf_parser_lib.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/addonfactory_splunk_conf_parser_lib.py b/addonfactory_splunk_conf_parser_lib.py index 50fa895..27110b0 100644 --- a/addonfactory_splunk_conf_parser_lib.py +++ b/addonfactory_splunk_conf_parser_lib.py @@ -16,8 +16,9 @@ import configparser from os import SEEK_SET from typing import Any, Dict +from re import compile, VERBOSE -COMMENT_PREFIX = ";#*" +COMMENT_PREFIX = [";", "#", "*"] COMMENT_KEY = "__COMMENTS__" @@ -33,6 +34,8 @@ class TABConfigParser(configparser.RawConfigParser): _defaults: Dict[Any, Any] _sections: Dict[Any, Any] _optcre: Dict[Any, Any] + # overriding the section regex for Splunk as blank '[]' stanza is valid in case for default.meta + SECTCRE = compile(pattern=r"\[(?P
.*)\]", flags=VERBOSE) def _read(self, fp, fpname): """ @@ -43,7 +46,8 @@ def _read(self, fp, fpname): cursect = None # None, or a dictionary optname = None lineno = 0 - e = None # None, or an exception + line: str + exc = None # None, or an exception comment_index = 0 self.top_comments = [] @@ -109,7 +113,7 @@ def _read(self, fp, fpname): # no section header in the file? elif cursect is None: - # disable the exception since splunk allows the field outside stanzas + # disable the exception since Splunk allows the field outside stanzas # raise MissingSectionHeaderError(fpname, lineno, line) self.fields_outside_stanza.append(line) # an option line? @@ -140,13 +144,12 @@ def _read(self, fp, fpname): # exception but keep going. the exception will be # raised at the end of the file and will contain a # list of all bogus lines - if not e: - e = ParsingError(fpname) - e.append(lineno, repr(line)) + if not exc: + exc = ParsingError(fpname) + exc.append(lineno, repr(line)) # if any parsing errors occurred, raise an exception - if e: - raise e - + if exc: + raise exc # join the multi-line values collected while reading all_sections = [self._defaults] all_sections.extend(list(self._sections.values())) From 931dfb3a6ae91c6df5fd58c1ec8b3bc39fec0f20 Mon Sep 17 00:00:00 2001 From: hetangmodi-crest Date: Tue, 6 Aug 2024 16:18:09 +0530 Subject: [PATCH 2/3] test(unit): add different conf file formats as seen in Splunk --- test_addonfactory_splunk_conf_parser_lib.py | 62 +++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/test_addonfactory_splunk_conf_parser_lib.py b/test_addonfactory_splunk_conf_parser_lib.py index 938c339..88bb800 100644 --- a/test_addonfactory_splunk_conf_parser_lib.py +++ b/test_addonfactory_splunk_conf_parser_lib.py @@ -85,6 +85,68 @@ def test_write(self): parser.write(output) self.assertEqual(conf, output.getvalue()) + def test_write_default_meta(self): + """ + Parsing of default stanza as '[]' as it is valid for default.meta in Splunk + """ + conf = """ +# Application-level permissions + +[] +owner = admin +access = read : [ * ], write : [ admin, sc_admin ] +export = system + +[props] +owner = admin +access = read : [ * ], write : [ admin, sc_admin ] +export = system +""" + parser = conf_parser.TABConfigParser() + parser.read_string(conf) + output = io.StringIO() + parser.write(output) + self.assertEqual(conf, output.getvalue()) + + def test_write_extra_lines_between_stanza(self): + """ + In case of a conf file with extra 'n' new lines between stanzas, + there would one empty new line between the end and start + """ + conf = """ +[stanza_0] +k = v + + +[stanza_1] +key = value +""" + parser = conf_parser.TABConfigParser() + parser.read_string(conf) + output = io.StringIO() + parser.write(output) + self.assertEqual(conf.replace("\n\n\n", "\n\n"), output.getvalue()) + + def test_write_extra_lines_at_end(self): + """ + In case of a conf file with extra 'n' new lines at the end, + we remove all and keep just one. + """ + conf = """ +[stanza_0] +k = v + +[stanza_1] +key = value + + +""" + parser = conf_parser.TABConfigParser() + parser.read_string(conf) + output = io.StringIO() + parser.write(output) + self.assertEqual(conf.rstrip() + "\n", output.getvalue()) + def test_items(self): conf = """ # From 62e30a2f546d94cd8d013c7c66bbc595d15135dd Mon Sep 17 00:00:00 2001 From: hetangmodi-crest Date: Tue, 6 Aug 2024 17:01:09 +0530 Subject: [PATCH 3/3] chore: resolved linting error --- test_addonfactory_splunk_conf_parser_lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_addonfactory_splunk_conf_parser_lib.py b/test_addonfactory_splunk_conf_parser_lib.py index 88bb800..d6cc12c 100644 --- a/test_addonfactory_splunk_conf_parser_lib.py +++ b/test_addonfactory_splunk_conf_parser_lib.py @@ -126,7 +126,7 @@ def test_write_extra_lines_between_stanza(self): output = io.StringIO() parser.write(output) self.assertEqual(conf.replace("\n\n\n", "\n\n"), output.getvalue()) - + def test_write_extra_lines_at_end(self): """ In case of a conf file with extra 'n' new lines at the end,