Added osTicket report sections

This commit is contained in:
2Shirt 2018-12-24 17:10:12 -07:00
parent 2372fb0d2f
commit 57572c7527
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C
2 changed files with 162 additions and 0 deletions

View file

@ -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."""

View file

@ -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.")