diff --git a/.bin/Scripts/functions/hw_diags.py b/.bin/Scripts/functions/hw_diags.py index c5002882..c1e0fefa 100644 --- a/.bin/Scripts/functions/hw_diags.py +++ b/.bin/Scripts/functions/hw_diags.py @@ -4,7 +4,10 @@ import json import re import time +# TODO: Still need functions.data ? from collections import OrderedDict +from functions.data import * +from functions.osticket import * from functions.sensors import * from functions.tmux import * diff --git a/.bin/Scripts/functions/osticket.py b/.bin/Scripts/functions/osticket.py new file mode 100644 index 00000000..0d1561c0 --- /dev/null +++ b/.bin/Scripts/functions/osticket.py @@ -0,0 +1,178 @@ +# Wizard Kit: Functions - osTicket + +import mysql.connector as mariadb + +from functions.common import * +from settings.osticket import * + +# Classes +class osTicket(): + """Class to track osTicket data and functions.""" + def __init__(self): + self.db_connection = None + self.db_cursor = None + self.errors = False + self.tunnel_proc = None + + def connect(self): + """Establish connection to osTicket via a SSH tunnel.""" + cmd = [ + 'ssh', '-N', + '-p', OSTICKET['SSH']['Port'], + '-L3306:127.0.0.1:{Port}'.format(**OSTICKET['Database']), + '{User}@{Host}'.format(**OSTICKET['SSH']), + ] + + # Only open tunnel if one doesn't exist + if self.tunnel_proc is None or self.tunnel_proc.poll() is not None: + self.tunnel_proc = popen_program(cmd) + + # Connect to database + for x in range(5): + sleep(2) + try: + self.db_connection = mariadb.connect( + user=OSTICKET['Database']['User'], + password=OSTICKET['Database']['Pass'], + database=OSTICKET['Database']['Name'], + ) + self.db_cursor = self.db_connection.cursor() + except Exception: + # TODO: Refine exception handling + pass + else: + # Connection established + break + + def disconnect(self, reset_errors=False): + """Close osTicket connection.""" + try: + self.db_cursor.close() + self.db_connection.close() + except Exception: + # TODO: Fix exception handling + pass + + # Reset errors + if reset_errors: + self.errors = False + + # Reset vars + self.db_cursor = None + self.db_connection = None + + def get_ticket_name(self, ticket_id): + """Lookup ticket and return name as str.""" + name = None + sql_cmd = "SELECT name FROM `{Ticket}`".format(**OSTICKET['Tables']) + sql_cmd += " WHERE `ticket_id` = `{}`".format(ticket_id) + sql_cmd += ";" + # TODO: Is the ';' needed above? It wasn't in the prev version?? + + # Lookup name + # NOTE: If multiple entries are found it will return the last + try: + self.db_cursor.execute(sql_cmd) + for s in self.db_cursor: + name = s[0] + except Exception: + # TODO: Fix exception handling + self.errors = True + + def get_ticket_number(self): + """Get ticket number and confirm with name from osTicket DB.""" + ticket_number = None + + # Main loop + while ticket_number is None: + print_standard(' ') + _input = input('Enter ticket number (or leave blank to disable): ') + _input = _input.strip() + + # No ticket ID entered + if re.match(r'^\s*$', _input): + if ask('Disable osTicket integration for this run?'): + break + + # Invalid ID entered + if not re.match(r'^([0-9]+)$', _input): + continue + + # Valid ID entered, lookup name and verify + _name = self.get_ticket_name(_input) + if _name: + print_standard('You have selected ticket #{} {}'.format( + _input, _name)) + if ask('Is this correct?'): + ticket_number = _input + + # Done + return ticket_number + + def post_response(self, ticket_id, response): + """Post a reply to a ticket in osTicket.""" + self.connect() + + # Build SQL cmd + sql_cmd = "INSERT INTO `{Name}`.`{Response}`".format( + **OSTICKET['Database'], **OSTICKET['Tables']) + sql_cmd += " (ticket_id, staff_id, staff_name, response, created)" + sql_cmd += " VALUES (" + sql_cmd += " '{}',".format(ticket_id) + sql_cmd += " '{ID}', '{Name}',".format(**OSTICKET['Staff']) + sql_cmd += " '{}',".format(response) + sql_cmd += " '{}'".format(time.strftime("%Y-%m-%d %H:%M:%S")) + sql_cmd += " );" + + # Run SQL cmd + try: + self.cursor.execute(sql_cmd) + except Exception: + # TODO: Fix exception handling + self.errors = True + + # Done + self.disconnect() + + def set_disk_failed(self, ticket_id): + """Mark disk as failed in osTicket.""" + self.set_flag( + ticket_id, + OSTICKET['Disk Flag']['Name'], + OSTICKET['Disk Flag']['Fail']) + + def set_disk_passed(self, ticket_id): + """Mark disk as passed in osTicket.""" + self.set_flag( + ticket_id, + OSTICKET['Disk Flag']['Name'], + OSTICKET['Disk Flag']['Pass']) + + def set_flag(self, ticket_id, flag_name, flag_value): + """Set flag in osTicket.""" + self.connect() + + # Build SQL cmd + sql_cmd = "UPDATE `{Name}`.`{Ticket}`".format( + **OSTICKET['Database'], **OSTICKET['Tables']) + sql_cmd += " SET `{}` = `{}`".format(flag_name, flag_value) + sql_cmd += " WHERE `{Ticket}`.`ticket_id` = `{ticket_id}`".format( + ticket_id=ticket_id, **OSTICKET['Tables']) + sql_cmd += ";" + + # Run SQL cmd + try: + self.cursor.execute(sql_cmd) + except Exception: + # TODO: Fix exception handling + self.errors = True + + # Done + self.disconnect() + +# Functions + +if __name__ == '__main__': + print("This file is not meant to be called directly.") + +# vim: sts=2 sw=2 ts=2 diff --git a/.bin/Scripts/settings/main.py b/.bin/Scripts/settings/main.py index e6aff08f..5e9002f5 100644 --- a/.bin/Scripts/settings/main.py +++ b/.bin/Scripts/settings/main.py @@ -14,13 +14,6 @@ ARCHIVE_PASSWORD='Sorted1201' KIT_NAME_FULL='1201-WizardKit' KIT_NAME_SHORT='1201' SUPPORT_MESSAGE='Please let support know by opening an issue on Gogs' -# osTicket -DB_HOST='osticket.1201.com' -DB_NAME='osticket' -DB_USER='wizardkit' -DB_PASS='U9bJnF9eamVkfsVw' -SSH_PORT='22' -SSH_USER='sql_tunnel' # imgur IMGUR_CLIENT_ID='3d1ee1d38707b85' # Live Linux diff --git a/.bin/Scripts/settings/osticket.py b/.bin/Scripts/settings/osticket.py new file mode 100644 index 00000000..fe998eb2 --- /dev/null +++ b/.bin/Scripts/settings/osticket.py @@ -0,0 +1,33 @@ +# Wizard Kit: Settings - osTicket + +OSTICKET = { + 'Database': { + 'Name': 'osticket', + 'User': 'wizardkit', + 'Pass': 'U9bJnF9eamVkfsVw', + 'Port': '3306', + }, + 'Disk Flag': { + 'Name': 'zHDTune', + 'Pass': 1, + 'Fail': 2, + }, + 'SSH': { + 'Host': 'osticket.1201.com', + 'Port': '22', + 'User': 'sql_tunnel', + }, + 'Staff': { + 'ID': '23', + 'Name': 'Wizard Kit', + }, + 'Tables': { + 'Response': 'ost_ticket_response', + 'Ticket': 'ost_ticket', + }, + } + +if __name__ == '__main__': + print("This file is not meant to be called directly.") + +# vim: sts=2 sw=2 ts=2