Skip to content

Commit

Permalink
feat(generate): generation of XML files
Browse files Browse the repository at this point in the history
  • Loading branch information
hetangmodi-crest committed Jul 31, 2024
1 parent 6fef598 commit fd0e8b1
Show file tree
Hide file tree
Showing 11 changed files with 426 additions and 142 deletions.
82 changes: 0 additions & 82 deletions splunk_add_on_ucc_framework/commands/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
from splunk_add_on_ucc_framework import meta_conf as meta_conf_lib
from splunk_add_on_ucc_framework import app_manifest as app_manifest_lib
from splunk_add_on_ucc_framework import global_config as global_config_lib
from splunk_add_on_ucc_framework import data_ui_generator
from splunk_add_on_ucc_framework.commands.modular_alert_builder import (
builder as alert_builder,
)
Expand Down Expand Up @@ -102,22 +101,6 @@ def _modify_and_replace_token_for_oauth_templates(
"templates",
ta_name.lower() + "_redirect.html",
)
with open(
os.path.join(
outputdir,
ta_name,
"default",
"data",
"ui",
"views",
f"{ta_name.lower()}_redirect.xml",
),
"w",
) as addon_redirect_xml_file:
addon_redirect_xml_content = data_ui_generator.generate_views_redirect_xml(
ta_name,
)
addon_redirect_xml_file.write(addon_redirect_xml_content)
os.rename(redirect_js_src, redirect_js_dest)
os.rename(redirect_html_src, redirect_html_dest)
else:
Expand Down Expand Up @@ -241,63 +224,6 @@ def _remove_listed_files(ignore_list: List[str]) -> List[str]:
return removed_list


def generate_data_ui(
output_directory: str,
addon_name: str,
include_inputs: bool,
include_dashboard: bool,
default_view: str,
) -> None:
# Create directories in the output folder for add-on's UI nav and views.
os.makedirs(
os.path.join(output_directory, addon_name, "default", "data", "ui", "nav"),
exist_ok=True,
)
os.makedirs(
os.path.join(output_directory, addon_name, "default", "data", "ui", "views"),
exist_ok=True,
)
default_ui_path = os.path.join(
output_directory, addon_name, "default", "data", "ui"
)
default_xml_path = os.path.join(default_ui_path, "nav", "default.xml")
if os.path.exists(default_xml_path):
logger.info(
"Skipping generating data/ui/nav/default.xml because file already exists."
)
else:
with open(default_xml_path, "w") as default_xml_file:
default_xml_content = data_ui_generator.generate_nav_default_xml(
include_inputs=include_inputs,
include_dashboard=include_dashboard,
default_view=default_view,
)
default_xml_file.write(default_xml_content)
with open(
os.path.join(default_ui_path, "views", "configuration.xml"), "w"
) as configuration_xml_file:
configuration_xml_content = data_ui_generator.generate_views_configuration_xml(
addon_name,
)
configuration_xml_file.write(configuration_xml_content)
if include_inputs:
with open(
os.path.join(default_ui_path, "views", "inputs.xml"), "w"
) as input_xml_file:
inputs_xml_content = data_ui_generator.generate_views_inputs_xml(
addon_name,
)
input_xml_file.write(inputs_xml_content)
if include_dashboard:
with open(
os.path.join(default_ui_path, "views", "dashboard.xml"), "w"
) as dashboard_xml_file:
dashboard_xml_content = data_ui_generator.generate_views_dashboard_xml(
addon_name
)
dashboard_xml_file.write(dashboard_xml_content)


def _get_addon_version(addon_version: Optional[str]) -> str:
if not addon_version:
try:
Expand Down Expand Up @@ -553,14 +479,6 @@ def generate(
os.path.join(output_directory, ta_name),
ui_source_map,
)
generate_data_ui(
output_directory,
ta_name,
global_config.has_inputs(),
global_config.has_dashboard(),
global_config.meta.get("default_view", data_ui_generator.DEFAULT_VIEW),
)
logger.info("Copied UCC template directory")
global_config_file = (
"globalConfig.yaml" if gc_path.endswith(".yaml") else "globalConfig.json"
)
Expand Down
44 changes: 21 additions & 23 deletions splunk_add_on_ucc_framework/data_ui_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# The autofix suggestion mentioned in the pipeline does not work actually.
# It proposed to replace `xml` with `defusedxml` and it does not have such
# import.
# nosemgrep: splunk.use-defused-xml
from xml.etree import ElementTree as ET
from defusedxml import minidom
from lxml import etree as ET

DEFAULT_VIEW = "configuration"


def _pretty_print_xml(string: str) -> str:
"""
Returns a pretty-printed XML as a string.
"""
return minidom.parseString(string).toprettyxml(indent=" ")


def generate_nav_default_xml(
include_inputs: bool, include_dashboard: bool, default_view: str
) -> str:
Expand Down Expand Up @@ -57,8 +45,10 @@ def generate_nav_default_xml(
ET.SubElement(nav, "view", attrib={"name": "search", "default": "true"})
else:
ET.SubElement(nav, "view", attrib={"name": "search"})
nav_as_string = ET.tostring(nav, encoding="unicode")
return _pretty_print_xml(nav_as_string)
nav_as_string = ET.tostring(
nav, pretty_print=True, encoding="utf-8", xml_declaration=True
).decode("utf-8")
return nav_as_string


def generate_views_inputs_xml(addon_name: str) -> str:
Expand All @@ -75,8 +65,10 @@ def generate_views_inputs_xml(addon_name: str) -> str:
)
label = ET.SubElement(view, "label")
label.text = "Inputs"
view_as_string = ET.tostring(view, encoding="unicode")
return _pretty_print_xml(view_as_string)
view_as_string = ET.tostring(
view, pretty_print=True, encoding="utf-8", xml_declaration=True
).decode("utf-8")
return view_as_string


def generate_views_configuration_xml(addon_name: str) -> str:
Expand All @@ -93,8 +85,10 @@ def generate_views_configuration_xml(addon_name: str) -> str:
)
label = ET.SubElement(view, "label")
label.text = "Configuration"
view_as_string = ET.tostring(view, encoding="unicode")
return _pretty_print_xml(view_as_string)
view_as_string = ET.tostring(
view, pretty_print=True, encoding="utf-8", xml_declaration=True
).decode("utf-8")
return view_as_string


def generate_views_dashboard_xml(addon_name: str) -> str:
Expand All @@ -111,8 +105,10 @@ def generate_views_dashboard_xml(addon_name: str) -> str:
)
label = ET.SubElement(view, "label")
label.text = "Monitoring Dashboard"
view_as_string = ET.tostring(view, encoding="unicode")
return _pretty_print_xml(view_as_string)
view_as_string = ET.tostring(
view, pretty_print=True, encoding="utf-8", xml_declaration=True
).decode("utf-8")
return view_as_string


def generate_views_redirect_xml(addon_name: str) -> str:
Expand All @@ -129,5 +125,7 @@ def generate_views_redirect_xml(addon_name: str) -> str:
)
label = ET.SubElement(view, "label")
label.text = "Redirect"
view_as_string = ET.tostring(view, encoding="unicode")
return _pretty_print_xml(view_as_string)
view_as_string = ET.tostring(
view, pretty_print=True, encoding="utf-8", xml_declaration=True
).decode("utf-8")
return view_as_string
44 changes: 43 additions & 1 deletion splunk_add_on_ucc_framework/generators/file_const.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@
AccountConf,
SettingsConf,
)
from splunk_add_on_ucc_framework.generators.xml_files import (
ConfigurationXml,
DashboardXml,
DefaultXml,
InputsXml,
RedirectXml,
)

__all__ = ["FileClass", "GEN_FILE_LIST"]

Expand All @@ -45,9 +52,14 @@ class FileClass(NamedTuple):
InputsConf,
AccountConf,
SettingsConf,
ConfigurationXml,
DashboardXml,
DefaultXml,
InputsXml,
RedirectXml,
]
]
file_path: str
file_path: Union[str, List[str]]
file_description: str


Expand All @@ -69,4 +81,34 @@ class FileClass(NamedTuple):
FileClass("tags.conf", TagsConf, "default", TagsConf.__description__),
FileClass("_account.conf", AccountConf, "README", AccountConf.__description__),
FileClass("_settings.conf", SettingsConf, "README", SettingsConf.__description__),
FileClass(
"configuration.xml",
ConfigurationXml,
["default", "data", "ui", "views"],
ConfigurationXml.__description__,
),
FileClass(
"dashboard.xml",
DashboardXml,
["default", "data", "ui", "views"],
DashboardXml.__description__,
),
FileClass(
"default.xml",
DefaultXml,
["default", "data", "ui", "nav"],
DefaultXml.__description__,
),
FileClass(
"inputs.xml",
InputsXml,
["default", "data", "ui", "views"],
InputsXml.__description__,
),
FileClass(
"_redirect.xml",
RedirectXml,
["default", "data", "ui", "views"],
RedirectXml.__description__,
),
]
30 changes: 30 additions & 0 deletions splunk_add_on_ucc_framework/generators/xml_files/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#
# Copyright 2024 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.
#
from .xml_generator import XMLGenerator
from .create_default_xml import DefaultXml
from .create_configuration_xml import ConfigurationXml
from .create_dashboard_xml import DashboardXml
from .create_inputs_xml import InputsXml
from .create_redirect_xml import RedirectXml

__all__ = [
"XMLGenerator",
"DefaultXml",
"ConfigurationXml",
"DashboardXml",
"InputsXml",
"RedirectXml",
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#
# Copyright 2024 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.
#
from splunk_add_on_ucc_framework.generators.xml_files import XMLGenerator
from splunk_add_on_ucc_framework.global_config import GlobalConfig
from typing import Any, Dict
from splunk_add_on_ucc_framework import data_ui_generator


class ConfigurationXml(XMLGenerator):
__description__ = " Generates configuration.xml file in `default/data/ui/views/` folder if globalConfig is present."

def __init__(
self,
global_config: GlobalConfig,
input_dir: str,
output_dir: str,
**kwargs: Any,
) -> None:
super().__init__(global_config, input_dir, output_dir, **kwargs)

def _set_attributes(self, **kwargs: Any) -> None:
self.configuration_xml_content = (
data_ui_generator.generate_views_configuration_xml(
kwargs["addon_name"],
)
)

def generate_xml(self) -> Dict[str, str]:
file_path = self.get_file_output_path(
["default", "data", "ui", "views", "configuration.xml"]
)
self.writer(
file_name="configuration.xml",
file_path=file_path,
content=self.configuration_xml_content,
)
return {"configuration.xml": file_path}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#
# Copyright 2024 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.
#
from splunk_add_on_ucc_framework.generators.xml_files import XMLGenerator
from splunk_add_on_ucc_framework.global_config import GlobalConfig
from typing import Any, Dict
from splunk_add_on_ucc_framework import data_ui_generator


class DashboardXml(XMLGenerator):
__description__ = (
" Generates dashboard.xml file based on dashboard configuration present in globalConfig"
" in `default/data/ui/views` folder."
)

def __init__(
self,
global_config: GlobalConfig,
input_dir: str,
output_dir: str,
**kwargs: Any,
) -> None:
super().__init__(global_config, input_dir, output_dir, **kwargs)

def _set_attributes(self, **kwargs: Any) -> None:
if self._global_config and self._global_config.has_dashboard():
self.dashboard_xml_content = data_ui_generator.generate_views_dashboard_xml(
kwargs["addon_name"]
)

def generate_xml(self) -> Dict[str, str]:
if self._global_config and not self._global_config.has_dashboard():
return super().generate_xml()
file_path = self.get_file_output_path(
["default", "data", "ui", "views", "dashboard.xml"]
)
self.writer(
file_name="dashboard.xml",
file_path=file_path,
content=self.dashboard_xml_content,
)
return {"dashboard.xml": file_path}
Loading

0 comments on commit fd0e8b1

Please sign in to comment.