Added osTicket report sections
This commit is contained in:
parent
2372fb0d2f
commit
57572c7527
2 changed files with 162 additions and 0 deletions
|
|
@ -102,6 +102,7 @@ class CpuObj():
|
|||
self.tests = OrderedDict()
|
||||
self.get_details()
|
||||
self.name = self.lscpu.get('Model name', 'Unknown CPU')
|
||||
self.description = self.name
|
||||
|
||||
def get_details(self):
|
||||
"""Get CPU details from lscpu."""
|
||||
|
|
|
|||
|
|
@ -5,6 +5,11 @@ import mysql.connector as mariadb
|
|||
from functions.common import *
|
||||
from settings.osticket import *
|
||||
|
||||
# Regex
|
||||
REGEX_BLOCK_GRAPH = re.compile(r'(▁|▂|▃|▄|▅|▆|▇|█)')
|
||||
REGEX_NVME_SMART_ATTRIBUTES = re.compile(r'^\s*(\d+) / (\w+): (.{28})(.*)$')
|
||||
REGEX_TEMPS = re.compile(r'^\s*(.*?)\s+(idle.*)$')
|
||||
|
||||
# Classes
|
||||
class osTicket():
|
||||
"""Class to track osTicket data and functions."""
|
||||
|
|
@ -171,6 +176,162 @@ class osTicket():
|
|||
self.disconnect()
|
||||
|
||||
# Functions
|
||||
def convert_report(name, test):
|
||||
"""Convert report into an osTicket friendly format, returns list."""
|
||||
out_report = []
|
||||
source_report = test.source_report
|
||||
status = strip_colors(test.status)
|
||||
status = status.replace(test.label, '').strip()
|
||||
|
||||
# Header
|
||||
index = 1
|
||||
if name == 'NVMe / SMART':
|
||||
out_report.append('{} ({})'.format(name, status))
|
||||
if not source_report:
|
||||
index = 0
|
||||
source_report = test.dev.generate_attribute_source_report()
|
||||
else:
|
||||
out_report.append('{} ({})'.format(strip_colors(source_report[0]), status))
|
||||
|
||||
# Body
|
||||
for line in source_report[index:]:
|
||||
# Remove colors and leading spaces
|
||||
line = strip_colors(line)
|
||||
if line[:2] == ' ':
|
||||
line = line[2:]
|
||||
|
||||
# Test-specific modifications
|
||||
if name == 'Prime95':
|
||||
r = REGEX_TEMPS.match(line)
|
||||
if r:
|
||||
_sensor = '{:<20}'.format(r.group(1))
|
||||
_temps = r.group(2)
|
||||
line = '{} {}'.format(
|
||||
pad_with_dots(_sensor, pad_right=True),
|
||||
_temps)
|
||||
elif name == 'NVMe / SMART':
|
||||
r = REGEX_NVME_SMART_ATTRIBUTES.match(line)
|
||||
if r:
|
||||
_dec = '{:>3}'.format(r.group(1))
|
||||
_hex = r.group(2)
|
||||
_atr = r.group(3).strip()
|
||||
_val = '{:<20}'.format(r.group(4))
|
||||
line = '{}/{}: {} {}'.format(
|
||||
_hex,
|
||||
pad_with_dots(_dec),
|
||||
pad_with_dots(_val, pad_right=True),
|
||||
_atr)
|
||||
elif name == 'I/O Benchmark':
|
||||
line = REGEX_BLOCK_GRAPH.sub('', line)
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
|
||||
# Remove extra spaces
|
||||
line = line.strip()
|
||||
line = re.sub(r'(\s+)', ' ', line)
|
||||
|
||||
# Add line to report
|
||||
out_report.append(line)
|
||||
|
||||
# Done
|
||||
return out_report
|
||||
|
||||
def get_device_overall_results(dev):
|
||||
"""Get overall results from tests for device, returns dict."""
|
||||
results = {
|
||||
'Dev Type': 'Unknown',
|
||||
'Full Diag': False,
|
||||
'Asterisk': None,
|
||||
'Failed': 0,
|
||||
'N/A': 0,
|
||||
'Passed': 0,
|
||||
'Status': 'Unknown',
|
||||
}
|
||||
|
||||
# Get test list for device type
|
||||
test_list = []
|
||||
if isinstance(dev, CpuObj):
|
||||
results['Dev Type'] = 'CPU'
|
||||
test_list = TESTS_CPU
|
||||
elif isinstance(dev, DiskObj):
|
||||
results['Dev Type'] = 'Disk'
|
||||
test_list = TESTS_DISK
|
||||
else:
|
||||
raise GenericError('Unrecognized device type.')
|
||||
|
||||
# Check if a full diag was run (i.e. all dev tests were enabled)
|
||||
results['Full Diag'] = len(dev.tests) == len(test_list)
|
||||
|
||||
# Tally test results
|
||||
for test in dev.tests.value():
|
||||
if test.failed:
|
||||
results['Failed'] += 1
|
||||
if test.passed:
|
||||
results['Passed'] += 1
|
||||
if 'N/A' in test.status:
|
||||
results['N/A'] += 1
|
||||
|
||||
# Set overall status
|
||||
if results['Failed'] > 0:
|
||||
dev.checkbox = False
|
||||
results['Status'] = 'FAILED'
|
||||
elif results['Passed'] + results['N/A'] == len(dev.tests):
|
||||
dev.checkbox = True
|
||||
results['Status'] = 'PASSED'
|
||||
else:
|
||||
results['Status'] = 'UNKNOWN'
|
||||
if results['Full Diag'] and results['N/A'] > 0:
|
||||
results['Asterisk'] = True
|
||||
results['Status'] += '*'
|
||||
|
||||
# Done
|
||||
return results
|
||||
|
||||
def generate_osticket_report(dev):
|
||||
"""Generate device report for osTicket, returns list."""
|
||||
report = []
|
||||
results = get_device_overall_results(dev)
|
||||
|
||||
# Header
|
||||
if results['Full Diag']:
|
||||
report.append(
|
||||
'{Dev Type} hardware diagnostic tests: {Status}'.format(**results))
|
||||
report.append(' ')
|
||||
|
||||
# Device
|
||||
report.append(dev.description)
|
||||
report.append(' ')
|
||||
|
||||
# Test reports
|
||||
for name, test in dev.tests.items():
|
||||
report.extend(convert_report(name, test))
|
||||
if name == 'I/O Benchmark':
|
||||
# TODO: Create PNG graph and upload to imgur/Nextcloud
|
||||
report.append('Imgur: TODO')
|
||||
report.append('Nextcloud: TODO')
|
||||
report.append(' ')
|
||||
|
||||
# Volumes
|
||||
if results['Dev Type'] == 'Disk':
|
||||
# TODO: Mount all volumes and extend report
|
||||
report.append('Volumes:')
|
||||
report.append('TODO')
|
||||
report.append(' ')
|
||||
|
||||
# Asterisk
|
||||
if results['Asterisk']:
|
||||
report.append('* NOTE: One or more tests were not run on this device')
|
||||
|
||||
def pad_with_dots(s, pad_right=False):
|
||||
"""Replace space padding with dots, returns str."""
|
||||
s = str(s).replace(' ', '..')
|
||||
if '.' in s:
|
||||
if pad_right:
|
||||
s = s + '.'
|
||||
else:
|
||||
s = '.' + s
|
||||
return s
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
|
|
|
|||
Loading…
Reference in a new issue