Add rendering functions to report tool
This update generates an index.html file in the collect bundle folder. Both Correlated Results and Plugin Results have its sub-items. Clicking items will show corresponding content in the content area. Test Plan: PASS: Verify the current report tool functions is not affected PASS: Verify the index.html is generated in the collect bundle folder PASS: Verify Correlated Results and Plugin Results are shown PASS: Verify the subitems of the Results are clickable and shown PASS: Verify the menu is expandable/collapsible PASS: Verify vertical scrollbar is applied when overflow occurs Story: 2010533 Task: 49041 Change-Id: Icf9c727b4f9418e03c0c7e273c8477e5ef9480ac Signed-off-by: Lance Xu <lance.xu@windriver.com>
This commit is contained in:
parent
49478c3526
commit
0a20762275
|
@ -267,7 +267,9 @@ class ExecutionEngine:
|
||||||
system_info_output,
|
system_info_output,
|
||||||
self.hosts, True)
|
self.hosts, True)
|
||||||
|
|
||||||
for host_dir in self.host_dirs:
|
start_index = self.active_controller_directory is None
|
||||||
|
|
||||||
|
for host_dir in self.host_dirs[start_index:]:
|
||||||
if host_dir != self.active_controller_directory:
|
if host_dir != self.active_controller_directory:
|
||||||
hostname = re.sub(regex_chop_bundle_date, "",
|
hostname = re.sub(regex_chop_bundle_date, "",
|
||||||
os.path.basename(host_dir))
|
os.path.basename(host_dir))
|
||||||
|
|
|
@ -0,0 +1,542 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
# extract 'plugins' part and 'correlated' part
|
||||||
|
def extract_section(log_contents, start_phrase):
|
||||||
|
start = log_contents.find(start_phrase)
|
||||||
|
if start == -1:
|
||||||
|
return ""
|
||||||
|
end = log_contents.find("\n\n", start)
|
||||||
|
if end == -1:
|
||||||
|
end = len(log_contents)
|
||||||
|
return log_contents[start:end].strip()
|
||||||
|
|
||||||
|
|
||||||
|
# remove timestamp for results
|
||||||
|
def remove_timestamp(text):
|
||||||
|
lines = text.split('\n')
|
||||||
|
temp = []
|
||||||
|
for line in lines:
|
||||||
|
if line.startswith('2023'):
|
||||||
|
temp.append(line[20:])
|
||||||
|
else:
|
||||||
|
temp.append(line)
|
||||||
|
final_text = '\n'.join(temp)
|
||||||
|
return final_text
|
||||||
|
|
||||||
|
|
||||||
|
# remove 'INFO:' text
|
||||||
|
def remove_emptyinfo(text):
|
||||||
|
lines = text.split('\n')
|
||||||
|
temp = []
|
||||||
|
for line in lines:
|
||||||
|
if line.strip() != 'INFO:':
|
||||||
|
temp.append(line)
|
||||||
|
final_text = '\n'.join(temp)
|
||||||
|
return final_text
|
||||||
|
|
||||||
|
|
||||||
|
# classify node type
|
||||||
|
def classify_node(data):
|
||||||
|
node_type = ''
|
||||||
|
|
||||||
|
for item in data:
|
||||||
|
if 'Node Type' in item:
|
||||||
|
node_type = item.split(':')[-1].strip().lower()
|
||||||
|
return node_type
|
||||||
|
|
||||||
|
|
||||||
|
# place the controller-0 in the top
|
||||||
|
def controller_sort(x):
|
||||||
|
return x[0] != 'controller-0'
|
||||||
|
|
||||||
|
|
||||||
|
# static css code
|
||||||
|
def html_css():
|
||||||
|
html_content_css = """
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Report Analysis</title>
|
||||||
|
<style>
|
||||||
|
html, body {{
|
||||||
|
overflow-x: hidden;
|
||||||
|
}}
|
||||||
|
|
||||||
|
iframe, textarea {{
|
||||||
|
height: 70vh;
|
||||||
|
width: 70vw;
|
||||||
|
resize: none;
|
||||||
|
}}
|
||||||
|
|
||||||
|
#content-maxheight {{
|
||||||
|
max-height: 70vh;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}}
|
||||||
|
|
||||||
|
.container-menu {{
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 25% 75%;
|
||||||
|
grid-gap: 10px;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}}
|
||||||
|
|
||||||
|
.menu {{
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
overflow-y: auto;
|
||||||
|
max-height: 80vh;
|
||||||
|
}}
|
||||||
|
|
||||||
|
.menu ul, .menu li {{
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}}
|
||||||
|
|
||||||
|
.menu a,
|
||||||
|
.menuItem,
|
||||||
|
#plugin-results-submenu a,
|
||||||
|
#correlated-results-submenu a,
|
||||||
|
#storage-info-submenu a,
|
||||||
|
#worker-info-submenu a {{
|
||||||
|
text-decoration: none;
|
||||||
|
color: #00ada4;
|
||||||
|
font-weight: bold;
|
||||||
|
display: block;
|
||||||
|
padding: 6px 10px;
|
||||||
|
}}
|
||||||
|
|
||||||
|
.menuTitle {{
|
||||||
|
color: #00857e !important;
|
||||||
|
}}
|
||||||
|
|
||||||
|
.menuItem {{
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
}}
|
||||||
|
|
||||||
|
.menuItem .icon {{
|
||||||
|
margin-right: 5px;
|
||||||
|
}}
|
||||||
|
|
||||||
|
.icon {{
|
||||||
|
display: inline-block;
|
||||||
|
}}
|
||||||
|
|
||||||
|
.menu a:hover, .menuItem:hover {{
|
||||||
|
background-color: #c3e3e2;
|
||||||
|
border-radius: 3px;
|
||||||
|
}}
|
||||||
|
|
||||||
|
.content{{
|
||||||
|
padding: 10px;
|
||||||
|
font-family: monospace;
|
||||||
|
margin-top: 10px;
|
||||||
|
}}
|
||||||
|
|
||||||
|
.content-item,
|
||||||
|
.content-itemtwo,
|
||||||
|
#plugin-results-submenu {{
|
||||||
|
display: none;
|
||||||
|
}}
|
||||||
|
|
||||||
|
.hidden {{
|
||||||
|
display: none;
|
||||||
|
}}
|
||||||
|
|
||||||
|
#show-worker {{
|
||||||
|
background-color: #00857e;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
}}
|
||||||
|
|
||||||
|
#show-worker:disabled {{
|
||||||
|
background-color: #ccc;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}}
|
||||||
|
|
||||||
|
#correlated-results-toggle, #plugin-results-toggle {{
|
||||||
|
font-size: 24px;
|
||||||
|
color: #3100b8;
|
||||||
|
}}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
"""
|
||||||
|
return html_content_css
|
||||||
|
|
||||||
|
|
||||||
|
# return text with timestamp and INFO: removed
|
||||||
|
def process_section(section, title):
|
||||||
|
# Remove the title from the section
|
||||||
|
section = section[len(title):]
|
||||||
|
# Remove timestamps and empty information
|
||||||
|
section = remove_timestamp(section)
|
||||||
|
section = remove_emptyinfo(section)
|
||||||
|
return section
|
||||||
|
|
||||||
|
|
||||||
|
# static script code
|
||||||
|
def html_script():
|
||||||
|
html_content_script = """
|
||||||
|
<script>
|
||||||
|
|
||||||
|
function toggleSub(event, submenuId, toggleButtonId) {{
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const submenu = document.getElementById(submenuId);
|
||||||
|
const toggleButton = document.getElementById(toggleButtonId);
|
||||||
|
|
||||||
|
if (submenu.style.display === "none") {{
|
||||||
|
submenu.style.display = "block";
|
||||||
|
toggleButton.textContent = "- ";
|
||||||
|
}} else {{
|
||||||
|
submenu.style.display = "none";
|
||||||
|
toggleButton.textContent = "+ ";
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
function toggleMenu(event, submenuId) {{
|
||||||
|
if (submenuId === 'correlated-results-submenu') {{
|
||||||
|
showContentTwo(event, 'content-item-correlated_results');
|
||||||
|
}}
|
||||||
|
|
||||||
|
if (submenuId === 'plugin-results-submenu') {{
|
||||||
|
showContentTwo(event, 'content-item-plugin_results');
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
function showContentStorage(event, contentId) {{
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const submenu = document.getElementById('storage-info-submenu');
|
||||||
|
const element = document.getElementById('storageicon');
|
||||||
|
var subicon = submenu.getElementsByClassName('icon');
|
||||||
|
|
||||||
|
if (submenu.style.display === 'block') {{
|
||||||
|
submenu.style.display = 'none';
|
||||||
|
element.textContent = '+';
|
||||||
|
for (var i = 0; i < subicon.length; i++) {{
|
||||||
|
subicon[i].textContent = '+';
|
||||||
|
}}
|
||||||
|
hideAllStorageId();
|
||||||
|
}} else {{
|
||||||
|
submenu.style.display = 'block';
|
||||||
|
element.textContent = '-';
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
function showContentWorker(event, contentId) {{
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const submenu = document.getElementById('worker-info-submenu');
|
||||||
|
const element = document.getElementById('workericon');
|
||||||
|
var subicon = submenu.getElementsByClassName('icon');
|
||||||
|
|
||||||
|
if (submenu.style.display === 'block') {{
|
||||||
|
submenu.style.display = 'none';
|
||||||
|
element.textContent = '+';
|
||||||
|
for (var i = 0; i < subicon.length; i++) {{
|
||||||
|
subicon[i].textContent = '+';
|
||||||
|
}}
|
||||||
|
if (document.getElementById("show-worker")) {{
|
||||||
|
document.getElementById("show-worker").disabled = true;
|
||||||
|
}}
|
||||||
|
hideAllWorkerId();
|
||||||
|
}} else {{
|
||||||
|
submenu.style.display = 'block';
|
||||||
|
element.textContent = '-';
|
||||||
|
if (document.getElementById("show-worker")) {{
|
||||||
|
document.getElementById("show-worker").disabled = false;
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
function showContentTwo(event, contentId) {{
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const contentItems = document.querySelectorAll('.content-itemtwo');
|
||||||
|
contentItems.forEach(item => {{
|
||||||
|
item.style.display = 'none';
|
||||||
|
}});
|
||||||
|
|
||||||
|
const selectedContent = document.getElementById(contentId);
|
||||||
|
if (selectedContent) {{
|
||||||
|
selectedContent.style.display = 'block';
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
function toggleContent(option, menuItem) {{
|
||||||
|
const contentDiv = document.getElementById(option);
|
||||||
|
const icon = menuItem.querySelector('.icon');
|
||||||
|
|
||||||
|
if (contentDiv.style.display === 'none') {{
|
||||||
|
contentDiv.style.display = 'block';
|
||||||
|
icon.textContent = '-';
|
||||||
|
}} else {{
|
||||||
|
contentDiv.style.display = 'none';
|
||||||
|
icon.textContent = '+';
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
function hideAllStorageId() {{
|
||||||
|
var outerDiv = document.getElementById('content-maxheight');
|
||||||
|
var innerDivs = outerDiv.getElementsByTagName('div');
|
||||||
|
var ids = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < innerDivs.length; i++) {{
|
||||||
|
if (innerDivs[i].id) {{
|
||||||
|
ids.push(innerDivs[i].id);
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
for (var i = 0; i < ids.length; i++) {{
|
||||||
|
if (ids[i].includes("storage")) {{
|
||||||
|
document.getElementById(ids[i]).style.display = 'none';
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
function hideAllWorkerId() {{
|
||||||
|
var outerDiv = document.getElementById('content-maxheight');
|
||||||
|
var innerDivs = outerDiv.getElementsByTagName('div');
|
||||||
|
var ids = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < innerDivs.length; i++) {{
|
||||||
|
if (innerDivs[i].id) {{
|
||||||
|
ids.push(innerDivs[i].id);
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
for (var i = 0; i < ids.length; i++) {{
|
||||||
|
if (!ids[i].includes("controller")
|
||||||
|
&& !ids[i].includes("storage")) {{
|
||||||
|
document.getElementById(ids[i]).style.display = 'none';
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
var hiddenItems = document.querySelectorAll(".menuItem.nothidden");
|
||||||
|
for (var i = 0; i < hiddenItems.length; i++) {{
|
||||||
|
hiddenItems[i].classList.remove("nothidden");
|
||||||
|
hiddenItems[i].classList.add("hidden");
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
function showMoreWorker() {{
|
||||||
|
var visibleItemCount = 5;
|
||||||
|
var hiddenItems = document.querySelectorAll(".menuItem.hidden");
|
||||||
|
for (var i = 0; i < hiddenItems.length; i++) {{
|
||||||
|
if (i < visibleItemCount) {{
|
||||||
|
hiddenItems[i].classList.remove("hidden");
|
||||||
|
hiddenItems[i].classList.add("nothidden");
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
if (hiddenItems.length <= visibleItemCount) {{
|
||||||
|
var button = document.getElementById("show-worker");
|
||||||
|
button.disabled = true;
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
|
"""
|
||||||
|
return html_content_script
|
||||||
|
|
||||||
|
|
||||||
|
# info part genearation
|
||||||
|
def html_info(sys_section):
|
||||||
|
controller_section = []
|
||||||
|
storage_section = []
|
||||||
|
worker_section = []
|
||||||
|
|
||||||
|
for i in sys_section:
|
||||||
|
section_lines = i.strip().split("\n")
|
||||||
|
section_type = classify_node(section_lines)
|
||||||
|
|
||||||
|
if "controller" == section_type:
|
||||||
|
controller_section.append(section_lines)
|
||||||
|
|
||||||
|
if "storage" == section_type:
|
||||||
|
storage_section.append(section_lines)
|
||||||
|
|
||||||
|
if "worker" == section_type:
|
||||||
|
worker_section.append(section_lines)
|
||||||
|
|
||||||
|
controller_section = sorted(controller_section, key=controller_sort)
|
||||||
|
|
||||||
|
controller_zero = controller_section.pop(0)
|
||||||
|
|
||||||
|
sections = {
|
||||||
|
"controller": controller_section,
|
||||||
|
"storage": storage_section,
|
||||||
|
"worker": worker_section
|
||||||
|
}
|
||||||
|
|
||||||
|
html_content_one = ""
|
||||||
|
|
||||||
|
html_content_one += """
|
||||||
|
<body>
|
||||||
|
<div class="container-menu">
|
||||||
|
<div class="menu">
|
||||||
|
<ul>
|
||||||
|
<a href="#" class="menuTitle" onclick="location.reload()">System Information</a>
|
||||||
|
"""
|
||||||
|
|
||||||
|
html_content_one += "<li>"
|
||||||
|
html_content_one += """<div class="menuItem" onclick="toggleContent('controller-0', this)">"""
|
||||||
|
html_content_one += """<div class="icon">-</div> controller-0</div>"""
|
||||||
|
for i in range(len(controller_section)):
|
||||||
|
controlname = controller_section[i][0]
|
||||||
|
html_content_one += f'<div class="menuItem" onclick="toggleContent(\'{controlname}\', this)">'
|
||||||
|
html_content_one += f'<div class="icon">+</div> {controlname}</div>'
|
||||||
|
html_content_one += "</li><hr>"
|
||||||
|
|
||||||
|
if storage_section:
|
||||||
|
html_content_one += """<li><a href="#" onclick="showContentStorage(event, 'storage')" style="color: #00857e">"""
|
||||||
|
html_content_one += """<div id="storageicon" class="icon">-</div> Storage</a><ul id="storage-info-submenu" style="display: block">"""
|
||||||
|
for i in range(len(storage_section)):
|
||||||
|
storagename = storage_section[i][0]
|
||||||
|
html_content_one += f'<div class="menuItem" onclick="toggleContent(\'{storagename}\', this)"><div class="icon">+</div> {storagename}</div>'
|
||||||
|
html_content_one += "</ul></li><hr>"
|
||||||
|
|
||||||
|
if worker_section:
|
||||||
|
html_content_one += """<li><a href="#" onclick="showContentWorker(event, 'worker')" style="color: #00857e">"""
|
||||||
|
html_content_one += """<div id="workericon" class="icon">-</div> Workers</a><ul id="worker-info-submenu" style="display: block">"""
|
||||||
|
|
||||||
|
max_workers_to_display = min(len(worker_section), 5)
|
||||||
|
for i in range(len(worker_section)):
|
||||||
|
workername = worker_section[i][0]
|
||||||
|
if i < max_workers_to_display:
|
||||||
|
html_content_one += f'<div class="menuItem" onclick="toggleContent(\'worker-{i}\', this)"><div class="icon">+</div> {workername}</div>'
|
||||||
|
else:
|
||||||
|
html_content_one += f'<div class="menuItem hidden" onclick="toggleContent(\'worker-{i}\', this)"><div class="icon">+</div> {workername}</div>'
|
||||||
|
|
||||||
|
if len(worker_section) > 5:
|
||||||
|
html_content_one += """<button id="show-worker" onClick="showMoreWorker()">Show More</button>"""
|
||||||
|
|
||||||
|
html_content_one += "</ul></li>"
|
||||||
|
|
||||||
|
html_content_one += """</ul></div><div class="content" id="content-maxheight">"""
|
||||||
|
|
||||||
|
# controller-0
|
||||||
|
html_content_one += """<div id="controller-0">"""
|
||||||
|
for i in controller_zero:
|
||||||
|
html_content_one += f'{i}'
|
||||||
|
html_content_one += "<br>"
|
||||||
|
html_content_one += "<br></div>"
|
||||||
|
|
||||||
|
for section_type, section_list in sections.items():
|
||||||
|
for i, section in enumerate(section_list):
|
||||||
|
if section_type == "controller":
|
||||||
|
div_id = f"{section_type}-{i + 1}"
|
||||||
|
else:
|
||||||
|
div_id = f"{section_type}-{i}"
|
||||||
|
html_content_one += f'<div id="{div_id}" style="display:none">'
|
||||||
|
for j in section:
|
||||||
|
html_content_one += f'{j}<br>'
|
||||||
|
html_content_one += "<br></div>"
|
||||||
|
|
||||||
|
html_content_one += "</div></div><br>"""
|
||||||
|
return html_content_one
|
||||||
|
|
||||||
|
|
||||||
|
# menu and content generation for results
|
||||||
|
def html_result(log_contents, output_dir):
|
||||||
|
# Extract sections from the log
|
||||||
|
plugin_section = extract_section(log_contents, 'Plugin Results:')
|
||||||
|
correlated_section = extract_section(log_contents, 'Correlated Results:')
|
||||||
|
|
||||||
|
# Process the extracted sections
|
||||||
|
plugin_section = process_section(plugin_section, 'Plugin Results:')
|
||||||
|
correlated_section = process_section(correlated_section, 'Correlated Results:')
|
||||||
|
|
||||||
|
# HTML part
|
||||||
|
correlated_directory = os.path.join(os.getcwd(), output_dir)
|
||||||
|
os.chdir(correlated_directory)
|
||||||
|
correlated_items = []
|
||||||
|
for file in os.listdir(correlated_directory):
|
||||||
|
if os.path.isfile(file) and '.' not in file:
|
||||||
|
correlated_items.append({'name': file, 'id': f'content-item-{file}'})
|
||||||
|
|
||||||
|
plugin_directory = os.path.join(correlated_directory, 'plugins')
|
||||||
|
os.chdir(plugin_directory)
|
||||||
|
|
||||||
|
plugin_items = []
|
||||||
|
for file in os.listdir(plugin_directory):
|
||||||
|
if os.path.isfile(file) and file != "system_info":
|
||||||
|
plugin_items.append({'name': file, 'id': f'content-item-{file}'})
|
||||||
|
|
||||||
|
html_content_two = ""
|
||||||
|
|
||||||
|
html_content_two += """
|
||||||
|
<div class="container-menu">
|
||||||
|
<div class="menu">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="#" onclick="toggleMenu(event, 'correlated-results-submenu')" class="menuTitle"> <span id="correlated-results-toggle" onclick="toggleSub(event, 'correlated-results-submenu', 'correlated-results-toggle')">- </span>
|
||||||
|
Correlated Results</a>
|
||||||
|
<ul id="correlated-results-submenu" style="display: block">"""
|
||||||
|
|
||||||
|
for item in correlated_items:
|
||||||
|
html_content_two += f'<li><a href="#" class="toggle-sign" onclick="showContentTwo(event, \'{item["id"]}\')">{item["name"]}</a></li>'
|
||||||
|
|
||||||
|
html_content_two += """ </ul>
|
||||||
|
</li>
|
||||||
|
<hr>
|
||||||
|
<li>
|
||||||
|
<a href="#" onclick="toggleMenu(event, 'plugin-results-submenu')" class="menuTitle"> <span id="plugin-results-toggle" onclick="toggleSub(event, 'plugin-results-submenu', 'plugin-results-toggle')">+ </span>
|
||||||
|
Plugin Results</a>
|
||||||
|
<ul id="plugin-results-submenu" style="display: none">"""
|
||||||
|
|
||||||
|
for item in plugin_items:
|
||||||
|
html_content_two += f'<li><a href="#" class="toggle-sign" onclick="showContentTwo(event, \'{item["id"]}\')">{item["name"]}</a></li>'
|
||||||
|
|
||||||
|
html_content_two += """</ul></li></ul></div>"""
|
||||||
|
html_content_two += """<div class="content">"""
|
||||||
|
|
||||||
|
for item in correlated_items:
|
||||||
|
html_content_two += f'<div class="content-itemtwo" id="{item["id"]}"><h2>{item["name"].capitalize()}</h2><iframe src="{item["name"]}"></iframe></div>'
|
||||||
|
|
||||||
|
for item in plugin_items:
|
||||||
|
html_content_two += f'<div class="content-itemtwo" id="{item["id"]}"><h2>{item["name"].capitalize()}</h2><iframe src="plugins/{item["name"]}"></iframe></div>'
|
||||||
|
|
||||||
|
html_content_two += f'<div class="content-itemtwo" id="content-item-correlated_results" style="display:block"><h2>Correlated Results</h2><textarea>{correlated_section}</textarea></div>'
|
||||||
|
html_content_two += f'<div class="content-itemtwo" id="content-item-plugin_results"><h2>Plugin Results</h2><textarea>{plugin_section}</textarea></div>'
|
||||||
|
html_content_two += """
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
"""
|
||||||
|
|
||||||
|
return html_content_two
|
||||||
|
|
||||||
|
|
||||||
|
# main
|
||||||
|
def main(input_dir, output_dir):
|
||||||
|
|
||||||
|
reportlog_path = os.path.join(output_dir, 'report.log')
|
||||||
|
|
||||||
|
with open(reportlog_path, 'r') as file:
|
||||||
|
log_contents = file.read()
|
||||||
|
|
||||||
|
sysinfo_path = os.path.join(output_dir, 'plugins/system_info')
|
||||||
|
|
||||||
|
with open(sysinfo_path, 'r') as file:
|
||||||
|
sysinfo_contents = file.read()
|
||||||
|
|
||||||
|
sys_section = sysinfo_contents.strip().split("\n\n")
|
||||||
|
html_content = html_css() + html_info(sys_section) + html_result(log_contents, output_dir) + html_script()
|
||||||
|
html_content = html_content.format()
|
||||||
|
|
||||||
|
# change back to upper level
|
||||||
|
os.chdir('..')
|
||||||
|
|
||||||
|
# Write the HTML content to a file
|
||||||
|
with open("index.html", "w") as file:
|
||||||
|
file.write(html_content)
|
|
@ -121,6 +121,7 @@ import time
|
||||||
import algorithms
|
import algorithms
|
||||||
from execution_engine import ExecutionEngine
|
from execution_engine import ExecutionEngine
|
||||||
from plugin import Plugin
|
from plugin import Plugin
|
||||||
|
import render
|
||||||
|
|
||||||
# Globals
|
# Globals
|
||||||
now = datetime.now(timezone.utc)
|
now = datetime.now(timezone.utc)
|
||||||
|
@ -963,4 +964,7 @@ else:
|
||||||
# analyze the collect bundle
|
# analyze the collect bundle
|
||||||
engine.execute(obj.plugins, output_dir)
|
engine.execute(obj.plugins, output_dir)
|
||||||
|
|
||||||
|
# generate report tool rendering html file
|
||||||
|
render.main(input_dir, output_dir)
|
||||||
|
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
|
@ -38,6 +38,7 @@ override_dh_auto_install:
|
||||||
install -m 755 -p report/algorithms.py $(ROOT)/usr/local/bin/report/algorithms.py
|
install -m 755 -p report/algorithms.py $(ROOT)/usr/local/bin/report/algorithms.py
|
||||||
install -m 755 -p report/plugin.py $(ROOT)/usr/local/bin/report/plugin.py
|
install -m 755 -p report/plugin.py $(ROOT)/usr/local/bin/report/plugin.py
|
||||||
install -m 755 -p report/correlator.py $(ROOT)/usr/local/bin/report/correlator.py
|
install -m 755 -p report/correlator.py $(ROOT)/usr/local/bin/report/correlator.py
|
||||||
|
install -m 755 -p report/render.py $(ROOT)/usr/local/bin/report/render.py
|
||||||
install -m 644 -p report/README $(ROOT)/usr/local/bin/report/README
|
install -m 644 -p report/README $(ROOT)/usr/local/bin/report/README
|
||||||
|
|
||||||
# Report Tool Plugin Algorithms
|
# Report Tool Plugin Algorithms
|
||||||
|
|
Loading…
Reference in New Issue