From c667430bfd373d4be9b19143b4abcb238364c6ed Mon Sep 17 00:00:00 2001 From: Artem Rys Date: Fri, 17 Feb 2023 21:56:40 +0100 Subject: [PATCH] refactor: minor changes across the codebase (#656) * refactor: move getting add-on version to a separate function * refactor: get rid of admin_match * refactor: move GlobalConfigPostProcessor to its own file * refactor: remove unused method from GlobalConfigPostProcessor * refactor: rename global_config to global_config_builder_schema * refactor: no neeed to pass static import_declare_test variable * chore: get rid of isort --- .pre-commit-config.yaml | 4 - example/globalConfig.json | 2 +- pyproject.toml | 3 - splunk_add_on_ucc_framework/commands/build.py | 54 ++++---- .../commands/rest_builder/builder.py | 11 +- ...fig.py => global_config_builder_schema.py} | 122 ------------------ .../global_config_post_processor.py | 106 +++++++++++++++ splunk_add_on_ucc_framework/rest_map_conf.py | 8 +- .../globalConfig.json | 2 +- .../globalConfig.json | 2 +- tests/unit/test_restmap_conf.py | 2 +- 11 files changed, 149 insertions(+), 167 deletions(-) rename splunk_add_on_ucc_framework/commands/rest_builder/{global_config.py => global_config_builder_schema.py} (73%) create mode 100644 splunk_add_on_ucc_framework/commands/rest_builder/global_config_post_processor.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 06c8473f9..c9ec1ecbe 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -30,10 +30,6 @@ repos: rev: 22.12.0 hooks: - id: black -- repo: https://github.com/PyCQA/isort - rev: 5.11.1 - hooks: - - id: isort - repo: https://github.com/pre-commit/mirrors-mypy rev: v0.991 hooks: diff --git a/example/globalConfig.json b/example/globalConfig.json index a4a327646..8f8c107c2 100644 --- a/example/globalConfig.json +++ b/example/globalConfig.json @@ -161,7 +161,7 @@ "meta": { "name": "Splunk_TA_dummy_data", "restRoot": "Splunk_TA_dummy_data", - "version": "5.18.0R05a4667a", + "version": "5.20.0Rc5bf18ae", "displayName": "Splunk_TA_dummy_data", "schemaVersion": "0.0.3" } diff --git a/pyproject.toml b/pyproject.toml index 55ef70e20..63e2e0fba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,9 +54,6 @@ importlib-metadata = {version="*", python="<3.8"} [tool.poetry.scripts] ucc-gen="splunk_add_on_ucc_framework.main:main" -[tool.isort] -profile = "black" - [build-system] requires = ["poetry>=1.0.2"] build-backend = "poetry.masonry.api" diff --git a/splunk_add_on_ucc_framework/commands/build.py b/splunk_add_on_ucc_framework/commands/build.py index a753626ed..0b1fe8637 100644 --- a/splunk_add_on_ucc_framework/commands/build.py +++ b/splunk_add_on_ucc_framework/commands/build.py @@ -20,6 +20,7 @@ import os import shutil import sys +from typing import Optional import yaml from jinja2 import Environment, FileSystemLoader @@ -34,11 +35,11 @@ meta_conf, utils, ) -from splunk_add_on_ucc_framework.commands.rest_builder import global_config -from splunk_add_on_ucc_framework.commands.rest_builder.builder import RestBuilder -from splunk_add_on_ucc_framework.commands.rest_builder.global_config import ( - GlobalConfigBuilderSchema, +from splunk_add_on_ucc_framework.commands.rest_builder import ( + global_config_builder_schema, + global_config_post_processor, ) +from splunk_add_on_ucc_framework.commands.rest_builder.builder import RestBuilder from splunk_add_on_ucc_framework.install_python_libraries import ( SplunktaucclibNotFound, install_python_libraries, @@ -132,7 +133,9 @@ def _replace_token(ta_name, outputdir): def _generate_rest( - ta_name, scheme: GlobalConfigBuilderSchema, import_declare_name, outputdir + ta_name, + scheme: global_config_builder_schema.GlobalConfigBuilderSchema, + outputdir, ): """ Build REST for Add-on. @@ -140,13 +143,12 @@ def _generate_rest( Args: ta_name (str): Name of TA. scheme (GlobalConfigBuilderSchema): REST schema. - import_declare_name (str): Name of import_declare_* file. outputdir (str): output directory. """ builder_obj = RestBuilder(scheme, os.path.join(outputdir, ta_name)) builder_obj.build() - post_process = global_config.GlobalConfigPostProcessor() - post_process(builder_obj, scheme, import_declare_name=import_declare_name) + post_process = global_config_post_processor.GlobalConfigPostProcessor() + post_process(builder_obj, scheme) return builder_obj @@ -252,7 +254,7 @@ def _modify_and_replace_token_for_oauth_templates( os.remove(redirect_js_src) -def _add_modular_input(ta_name, schema_content, import_declare_name, outputdir): +def _add_modular_input(ta_name, schema_content, outputdir): """ Generate Modular input for addon. @@ -276,7 +278,7 @@ def _add_modular_input(ta_name, schema_content, import_declare_name, outputdir): # filter fields in allow list entity = [x for x in entity if x.get("field") not in field_allow_list] - import_declare = "import " + import_declare_name + import_declare = "import import_declare_test" content = j2_env.get_template(template).render( import_declare=import_declare, @@ -423,16 +425,10 @@ def _get_os_path(path): return path.strip(os.sep) -def generate( - source, config_path, addon_version, outputdir=None, python_binary_name="python3" -): - logger.info(f"ucc-gen version {__version__} is used") - logger.info(f"Python binary name to use: {python_binary_name}") - if outputdir is None: - outputdir = os.path.join(os.getcwd(), "output") +def _get_addon_version(addon_version: Optional[str]) -> str: if not addon_version: try: - addon_version = utils.get_version_from_git() + return utils.get_version_from_git() except exceptions.CouldNotVersionFromGitException: logger.error( "Could not find the proper version from git tags. " @@ -440,8 +436,17 @@ def generate( "https://github.com/splunk/addonfactory-ucc-generator/issues/404" ) exit(1) - else: - addon_version = addon_version.strip() + return addon_version.strip() + + +def generate( + source, config_path, addon_version, outputdir=None, python_binary_name="python3" +): + logger.info(f"ucc-gen version {__version__} is used") + logger.info(f"Python binary name to use: {python_binary_name}") + if outputdir is None: + outputdir = os.path.join(os.getcwd(), "output") + addon_version = _get_addon_version(addon_version) if not os.path.exists(source): raise NotADirectoryError(f"{os.path.abspath(source)} not found.") @@ -506,13 +511,14 @@ def generate( config_path, is_global_config_yaml ) - scheme = global_config.GlobalConfigBuilderSchema(schema_content, j2_env) + scheme = global_config_builder_schema.GlobalConfigBuilderSchema( + schema_content, j2_env + ) addon_version = schema_content.get("meta").get("version") logger.info("Addon Version : " + addon_version) ta_tabs = schema_content.get("pages").get("configuration").get("tabs") ta_namespace = schema_content.get("meta").get("restRoot") - import_declare_name = "import_declare_test" is_inputs = "inputs" in schema_content.get("pages") logger.info("Package ID is " + ta_name) @@ -550,7 +556,7 @@ def generate( _replace_token(ta_name, outputdir) - _generate_rest(ta_name, scheme, import_declare_name, outputdir) + _generate_rest(ta_name, scheme, outputdir) _modify_and_replace_token_for_oauth_templates( ta_name, ta_tabs, schema_content.get("meta").get("version"), outputdir @@ -566,7 +572,7 @@ def generate( "default_no_input.xml", ) os.remove(default_no_input_xml_file) - _add_modular_input(ta_name, schema_content, import_declare_name, outputdir) + _add_modular_input(ta_name, schema_content, outputdir) else: _handle_no_inputs(ta_name, outputdir) diff --git a/splunk_add_on_ucc_framework/commands/rest_builder/builder.py b/splunk_add_on_ucc_framework/commands/rest_builder/builder.py index 028675242..e5dc0cb4a 100644 --- a/splunk_add_on_ucc_framework/commands/rest_builder/builder.py +++ b/splunk_add_on_ucc_framework/commands/rest_builder/builder.py @@ -16,8 +16,8 @@ import os import os.path as op -from splunk_add_on_ucc_framework.commands.rest_builder.global_config import ( - GlobalConfigBuilderSchema, +from splunk_add_on_ucc_framework.commands.rest_builder import ( + global_config_builder_schema, ) from splunk_add_on_ucc_framework.rest_map_conf import RestmapConf from splunk_add_on_ucc_framework.web_conf import WebConf @@ -57,7 +57,11 @@ def save(self): class RestBuilder: def __init__( - self, schema: GlobalConfigBuilderSchema, output_path: str, *args, **kwargs + self, + schema: global_config_builder_schema.GlobalConfigBuilderSchema, + output_path: str, + *args, + **kwargs ): """ @@ -123,7 +127,6 @@ def build(self): RestmapConf.build( self._schema.endpoints, self._schema.namespace, - self._schema.admin_match, ), ) self.output.put( diff --git a/splunk_add_on_ucc_framework/commands/rest_builder/global_config.py b/splunk_add_on_ucc_framework/commands/rest_builder/global_config_builder_schema.py similarity index 73% rename from splunk_add_on_ucc_framework/commands/rest_builder/global_config.py rename to splunk_add_on_ucc_framework/commands/rest_builder/global_config_builder_schema.py index adf44c499..ed0850afc 100644 --- a/splunk_add_on_ucc_framework/commands/rest_builder/global_config.py +++ b/splunk_add_on_ucc_framework/commands/rest_builder/global_config_builder_schema.py @@ -20,9 +20,6 @@ import json -import os -import os.path as op -import shutil from typing import Any, Dict, List, Type from splunk_add_on_ucc_framework.commands.rest_builder.endpoint.base import ( @@ -77,10 +74,6 @@ def product(self) -> str: def namespace(self) -> str: return self._meta["restRoot"] - @property - def admin_match(self): - return "" - @property def inputs(self): return self._inputs @@ -277,118 +270,3 @@ def _get_oauth_enitities(self, content): content.remove(entity_element) break return content - - -class GlobalConfigPostProcessor: - """ - Post process for REST builder. - """ - - output_local = "local" - _import_declare_template = """ -import {import_declare_name} -""" - - _import_declare_content = """ -import os -import sys -import re -from os.path import dirname - -ta_name = '{ta_name}' -pattern = re.compile(r'[\\\\/]etc[\\\\/]apps[\\\\/][^\\\\/]+[\\\\/]bin[\\\\/]?$') -new_paths = [path for path in sys.path if not pattern.search(path) or ta_name in path] -new_paths.append(os.path.join(dirname(dirname(__file__)), "lib")) -new_paths.insert(0, os.path.sep.join([os.path.dirname(__file__), ta_name])) -sys.path = new_paths -""" - - def __init__(self): - self.builder = None - self.schema = None - self.import_declare_name = None - - @property - def root_path(self): - return getattr(self.builder.output, "_path") - - def third_path(self): - return self.schema.namespace - - def default_to_local(self): - default_dir = op.join( - self.root_path, - self.builder.output.default, - ) - local_dir = op.join( - self.root_path, - self.output_local, - ) - if not op.isdir(local_dir): - os.makedirs(local_dir) - for i in os.listdir(default_dir): - child = op.join(default_dir, i) - if op.isdir(child): - shutil.copytree(child, local_dir) - else: - shutil.copy(child, op.join(local_dir, i)) - - # remove the default folder - shutil.rmtree(default_dir, ignore_errors=True) - - def import_declare_py_name(self): - if self.import_declare_name: - return self.import_declare_name - return f"{self.schema.namespace}_import_declare" - - def import_declare_py_content(self): - import_declare_file = op.join( - self.root_path, - self.builder.output.bin, - self.import_declare_py_name() + ".py", - ) - content = self._import_declare_content.format( - ta_name=self.schema.product, - ) - with open(import_declare_file, "w") as f: - f.write(content) - - def import_declare(self, rh_file): - with open(rh_file) as f: - cont = f.readlines() - import_declare = self._import_declare_template.format( - import_declare_name=self.import_declare_py_name() - ) - cont.insert(0, import_declare) - with open(rh_file, "w") as f: - f.write("".join(cont)) - - def __call__(self, builder, schema, import_declare_name=None): - """ - :param builder: REST builder - :param schema: Global Config Schema - :return: - """ - self.builder = builder - self.schema = schema - self.import_declare_name = import_declare_name - - self.import_declare_py_content() - for endpoint in schema.endpoints: - rh_file = op.join( - getattr(builder.output, "_path"), - builder.output.bin, - endpoint.rh_name + ".py", - ) - self.import_declare(rh_file) - # self.default_to_local() - - # add executable permission to files under bin folder - def add_executable_attribute(file_path): - if op.isfile(file_path): - st = os.stat(file_path) - os.chmod(file_path, st.st_mode | 0o111) - - bin_path = op.join(getattr(builder.output, "_path"), builder.output.bin) - items = os.listdir(bin_path) - list(map(add_executable_attribute, items)) diff --git a/splunk_add_on_ucc_framework/commands/rest_builder/global_config_post_processor.py b/splunk_add_on_ucc_framework/commands/rest_builder/global_config_post_processor.py new file mode 100644 index 000000000..60f352a2a --- /dev/null +++ b/splunk_add_on_ucc_framework/commands/rest_builder/global_config_post_processor.py @@ -0,0 +1,106 @@ +# +# Copyright 2021 Splunk Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os +import os.path as op + + +class GlobalConfigPostProcessor: + """ + Post process for REST builder. + """ + + output_local = "local" + _import_declare_template = """ +import {import_declare_name} +""" + + _import_declare_content = """ +import os +import sys +import re +from os.path import dirname + +ta_name = '{ta_name}' +pattern = re.compile(r'[\\\\/]etc[\\\\/]apps[\\\\/][^\\\\/]+[\\\\/]bin[\\\\/]?$') +new_paths = [path for path in sys.path if not pattern.search(path) or ta_name in path] +new_paths.append(os.path.join(dirname(dirname(__file__)), "lib")) +new_paths.insert(0, os.path.sep.join([os.path.dirname(__file__), ta_name])) +sys.path = new_paths +""" + + def __init__(self): + self.builder = None + self.schema = None + self.import_declare_name = "import_declare_test" + + @property + def root_path(self): + return getattr(self.builder.output, "_path") + + def import_declare_py_name(self): + if self.import_declare_name: + return self.import_declare_name + return f"{self.schema.namespace}_import_declare" + + def import_declare_py_content(self): + import_declare_file = op.join( + self.root_path, + self.builder.output.bin, + self.import_declare_py_name() + ".py", + ) + content = self._import_declare_content.format( + ta_name=self.schema.product, + ) + with open(import_declare_file, "w") as f: + f.write(content) + + def import_declare(self, rh_file): + with open(rh_file) as f: + cont = f.readlines() + import_declare = self._import_declare_template.format( + import_declare_name=self.import_declare_py_name() + ) + cont.insert(0, import_declare) + with open(rh_file, "w") as f: + f.write("".join(cont)) + + def __call__(self, builder, schema): + """ + :param builder: REST builder + :param schema: Global Config Schema + :return: + """ + self.builder = builder + self.schema = schema + + self.import_declare_py_content() + for endpoint in schema.endpoints: + rh_file = op.join( + getattr(builder.output, "_path"), + builder.output.bin, + endpoint.rh_name + ".py", + ) + self.import_declare(rh_file) + + # add executable permission to files under bin folder + def add_executable_attribute(file_path): + if op.isfile(file_path): + st = os.stat(file_path) + os.chmod(file_path, st.st_mode | 0o111) + + bin_path = op.join(getattr(builder.output, "_path"), builder.output.bin) + items = os.listdir(bin_path) + list(map(add_executable_attribute, items)) diff --git a/splunk_add_on_ucc_framework/rest_map_conf.py b/splunk_add_on_ucc_framework/rest_map_conf.py index d94dc550f..f078e2505 100644 --- a/splunk_add_on_ucc_framework/rest_map_conf.py +++ b/splunk_add_on_ucc_framework/rest_map_conf.py @@ -24,7 +24,7 @@ class RestmapConf: _admin_template = """ [admin:{namespace}] -match = /{admin_match} +match = / members = {endpoints} """ @@ -38,16 +38,12 @@ class RestmapConf: """ @classmethod - def build( - cls, endpoints: Sequence[RestEndpointBuilder], namespace: str, admin_match: str - ) -> str: - # admin_match is always an empty string, so it will be probably removed in the future releases. + def build(cls, endpoints: Sequence[RestEndpointBuilder], namespace: str) -> str: if not endpoints: return "" externals = [ cls._admin_template.format( namespace=namespace, - admin_match=admin_match, endpoints=", ".join([ep.name for ep in endpoints]), ) ] diff --git a/tests/testdata/test_addons/package_global_config_configuration/globalConfig.json b/tests/testdata/test_addons/package_global_config_configuration/globalConfig.json index 89575b822..c0bcb97a1 100644 --- a/tests/testdata/test_addons/package_global_config_configuration/globalConfig.json +++ b/tests/testdata/test_addons/package_global_config_configuration/globalConfig.json @@ -421,7 +421,7 @@ "meta": { "name": "Splunk_TA_UCCExample", "restRoot": "splunk_ta_uccexample", - "version": "5.18.0R05a4667a", + "version": "5.20.0Rc5bf18ae", "displayName": "Splunk UCC test Add-on", "schemaVersion": "0.0.3" } diff --git a/tests/testdata/test_addons/package_global_config_inputs_configuration_alerts/globalConfig.json b/tests/testdata/test_addons/package_global_config_inputs_configuration_alerts/globalConfig.json index 26efd81de..c70fc689e 100644 --- a/tests/testdata/test_addons/package_global_config_inputs_configuration_alerts/globalConfig.json +++ b/tests/testdata/test_addons/package_global_config_inputs_configuration_alerts/globalConfig.json @@ -1108,7 +1108,7 @@ "meta": { "name": "Splunk_TA_UCCExample", "restRoot": "splunk_ta_uccexample", - "version": "5.18.0R05a4667a", + "version": "5.20.0Rc5bf18ae", "displayName": "Splunk UCC test Add-on", "schemaVersion": "0.0.3" } diff --git a/tests/unit/test_restmap_conf.py b/tests/unit/test_restmap_conf.py index 65fd5392a..2238651aa 100644 --- a/tests/unit/test_restmap_conf.py +++ b/tests/unit/test_restmap_conf.py @@ -59,6 +59,6 @@ def test_rest_conf_build(): handlerpersistentmode = true """ - result = RestmapConf.build(endpoints, "addon_name", "") + result = RestmapConf.build(endpoints, "addon_name") assert expected_result == result