diff --git a/check-plugins/avelon-tickets/.windows b/check-plugins/avelon-tickets/.windows new file mode 100644 index 00000000..e69de29b diff --git a/check-plugins/avelon-tickets/README.rst b/check-plugins/avelon-tickets/README.rst new file mode 100644 index 00000000..a8c9e982 --- /dev/null +++ b/check-plugins/avelon-tickets/README.rst @@ -0,0 +1,106 @@ +Check avelon-tickets +==================== + +Overview +-------- + +Check if there are any pending tickets (alarms) on the Avelon Cloud and whether they are still open, acknowledged, or closed. + +What is the Avelon Cloud? +Avelon's products and services have been used in professional building operations for over 20 years. From commercial and industrial buildings to office buildings, airports, and railway facilities. The Avelon Cloud propels buildings into a professional era. Avelon takes care of security and maintenance throughout the entire usage period. With Avelon Cloud, operations become cheaper and more professional. + +Notes: + +To use this monitoring plugin, you need to have a REST API license from Avelon. +If you already have a license, log in to Avelon and click on Settings in the user menu at the top right. On the General tab, you will see a section called Public OAuth API Key. The Client ID and Client Secret displayed there are required to authenticate with our API (Monitoring-Plugin). + +Links: + +* `Avelon `_ +* `Avelon Cloud Platform `_ +* `Avelon Documentation `_ +* `API Documentation `_ + + +Fact Sheet +---------- + +.. csv-table:: + :widths: 30, 70 + + "Check Plugin Download", "https://github.com/Linuxfabrik/monitoring-plugins/tree/main/check-plugins/avelon-tickets" + "Check Interval Recommendation", "Once a minute" + "Can be called without parameters", "No" + "Compiled for", "Linux, Windows" + + +Help +---- + +.. code-block:: text + + usage: avelon-tickets [-h] [-V] [--always-ok] --client-id CLIENT_ID --client-secret CLIENT_SECRET [--closed-ticket] + [-c [{ACKNOWLEDGED,ACKNOWLEDGED_AND_GONE,GONE,OPEN} ...]] [--insecure] [--no-proxy] --password PASSWORD --username + USERNAME [--test TEST] [--timeout TIMEOUT] [-w [{ACKNOWLEDGED,ACKNOWLEDGED_AND_GONE,GONE,OPEN} ...]] + + The current tickets (alerts) of your Avelon Cloud are being reviewed, and depending on their status, critical alerts or warnings can be + triggered. You need a license to access the public API of the Avelon Cloud. + + options: + -h, --help show this help message and exit + -V, --version show program's version number and exit + --always-ok Always returns OK. + --client-id CLIENT_ID + Avelon API client_id. + --client-secret CLIENT_SECRET + Avelon API client_secret. + --closed-ticket The option allows viewing the closed alarms as well. Default: False + -c [{ACKNOWLEDGED,ACKNOWLEDGED_AND_GONE,GONE,OPEN} ...], --critical [{ACKNOWLEDGED,ACKNOWLEDGED_AND_GONE,GONE,OPEN} ...] + Set the CRIT threshold as a status of the ticket (alarm). Default: >= [] + --insecure This option explicitly allows to perform "insecure" SSL connections. Default: False + --no-proxy Do not use a proxy.Default: False + --password PASSWORD Avelon Cloud password. + --username USERNAME Avelon Cloud username. + --test TEST For unit tests. Needs "path-to-stdout-file,path-to-stderr-file,expected-retc". + --timeout TIMEOUT Network timeout in seconds. Default: 8 (seconds) + -w [{ACKNOWLEDGED,ACKNOWLEDGED_AND_GONE,GONE,OPEN} ...], --warning [{ACKNOWLEDGED,ACKNOWLEDGED_AND_GONE,GONE,OPEN} ...] + Set the WARN threshold as a status of the ticket (alarm). Default: >= ['ACKNOWLEDGED', 'ACKNOWLEDGED_AND_GONE', + 'GONE', 'OPEN'] + + +Usage Examples +-------------- + +.. code-block:: bash + + ./avelon-tickets --client-id CLIENT_ID --client-secret CLIENT_SECRET --username USER --password PASSWORD --critical ACKNOWLEDGED OPEN + +Output: + +.. code-block:: text + + There are CRITICAL alarm ticket(s). + + ID ! Timestamp ! Message ! State + ---------+----------------------------------+-------------------------------------------------------------+------------------------- + 13927572 ! 2024-06-18 19:46:56 (5D 14h ago) ! Abschaltend: 6102/5/22: Durchfluss Notkühlung FQ201 Störung ! OPEN [CRITICAL] + 13927573 ! 2024-06-18 19:46:56 (5D 14h ago) ! Störung: 6102/5/0: Anlage Zustand Störung ! ACKNOWLEDGED [CRITICAL] + + +States +------ + +* WARN or CRIT if a ticket (alarm) status matches the defined values (ACKNOWLEDGED, ACKNOWLEDGED_AND_GONE, GONE and OPEN). + + +Perfdata / Metrics +------------------ + +There is no perfdata. + + +Credits, License +---------------- + +* Authors: `Linuxfabrik GmbH, Zurich `_ +* License: The Unlicense, see `LICENSE file `_. diff --git a/check-plugins/avelon-tickets/avelon-tickets b/check-plugins/avelon-tickets/avelon-tickets new file mode 100755 index 00000000..d8f5ce92 --- /dev/null +++ b/check-plugins/avelon-tickets/avelon-tickets @@ -0,0 +1,260 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8; py-indent-offset: 4 -*- +# +# Author: Linuxfabrik GmbH, Zurich, Switzerland +# Contact: info (at) linuxfabrik (dot) ch +# https://www.linuxfabrik.ch/ +# License: The Unlicense, see LICENSE file. + +# https://github.com/Linuxfabrik/monitoring-plugins/blob/main/CONTRIBUTING.rst + +"""See the check's README for more details. +""" + +import argparse # pylint: disable=C0413 +import datetime # pylint: disable=C0413 +import json # pylint: disable=C0413 +import re # pylint: disable=C0413 +import sys # pylint: disable=C0413 + +import lib.args # pylint: disable=C0413 +import lib.base # pylint: disable=C0413 +import lib.human # pylint: disable=C0413 +import lib.avelon # pylint: disable=C0413 +import lib.test # pylint: disable=C0413 +import lib.time # pylint: disable=C0413 +import lib.txt # pylint: disable=C0413 +from lib.globals import (STATE_OK, STATE_UNKNOWN, # pylint: disable=C0413 + STATE_WARN, STATE_CRIT) + +__author__ = 'Linuxfabrik GmbH, Zurich/Switzerland' +__version__ = '2024072401' + +DESCRIPTION = """The current tickets (alerts) of your Avelon Cloud are being reviewed, + and depending on their status, critical alerts or warnings can be triggered. + You need a license to access the public API of the Avelon Cloud.""" + +DEFAULT_CLOSED_TICKET = False +DEFAULT_CRIT = [] +DEFAULT_INSECURE = False +DEFAULT_NO_PROXY = False +DEFAULT_TIMEOUT = 8 +DEFAULT_WARN = ['ACKNOWLEDGED', 'ACKNOWLEDGED_AND_GONE', 'GONE', 'OPEN'] + +def parse_args(): + """Parse command line arguments using argparse. + """ + parser = argparse.ArgumentParser(description=DESCRIPTION) + +# parameter alphabetisch + parser.add_argument( + '-V', '--version', + action='version', + version='%(prog)s: v{} by {}'.format(__version__, __author__) + ) + + parser.add_argument( + '--always-ok', + help='Always returns OK.', + dest='ALWAYS_OK', + action='store_true', + default=False, + ) + + parser.add_argument( + '--client-id', + help='Avelon API client_id.', + dest='CLIENT_ID', + required=True, + ) + + parser.add_argument( + '--client-secret', + help='Avelon API client_secret.', + dest='CLIENT_SECRET', + required=True, + ) + + parser.add_argument( + '--closed-ticket', + help='The option allows viewing the closed alarms as well. ' + 'Default: %(default)s', + dest='CLOSED_TICKET', + action='store_true', + default=DEFAULT_CLOSED_TICKET, + ) + + parser.add_argument( + '-c', '--critical', + help='Set the CRIT threshold as a status of the ticket (alarm). ' + 'Default: >= %(default)s', + nargs='*', + choices=['ACKNOWLEDGED', 'ACKNOWLEDGED_AND_GONE', 'GONE', 'OPEN'], + dest='CRIT', + default=DEFAULT_CRIT, + ) + + parser.add_argument( + '--insecure', + help='This option explicitly allows to perform "insecure" SSL connections. ' + 'Default: %(default)s', + dest='INSECURE', + action='store_true', + default=DEFAULT_INSECURE, + ) + + parser.add_argument( + '--no-proxy', + help='Do not use a proxy.' + 'Default: %(default)s', + dest='NO_PROXY', + action='store_true', + default=DEFAULT_NO_PROXY, + ) + + parser.add_argument( + '--password', + help='Avelon Cloud password.', + dest='PASSWORD', + required=True, + ) + + parser.add_argument( + '--username', + help='Avelon Cloud username.', + dest='USERNAME', + required=True, + ) + + parser.add_argument( + '--test', + help='For unit tests. ' + 'Needs "path-to-stdout-file,path-to-stderr-file,expected-retc".', + dest='TEST', + type=lib.args.csv, + ) + + parser.add_argument( + '--timeout', + help='Network timeout in seconds. ' + 'Default: %(default)s (seconds)', + dest='TIMEOUT', + type=int, + default=DEFAULT_TIMEOUT, + ) + + parser.add_argument( + '-w', '--warning', + help='Set the WARN threshold as a status of the ticket (alarm). ' + 'Default: >= %(default)s', + nargs='*', + choices=['ACKNOWLEDGED', 'ACKNOWLEDGED_AND_GONE', 'GONE', 'OPEN'], + dest='WARN', + default=DEFAULT_WARN, + ) + + return parser.parse_args() + + +def main(): + """The main function. + """ + # parse the command line, exit with UNKNOWN if it fails + try: + args = parse_args() + except SystemExit: + sys.exit(STATE_UNKNOWN) + + # init some vars + msg = '' + state = STATE_OK + ticket_table = [] + + if args.TEST is None: + # get token + success, token = lib.avelon.get_token( + client_id=args.CLIENT_ID, + client_secret=args.CLIENT_SECRET, + username=args.USERNAME, + password=args.PASSWORD, + insecure=args.INSECURE, + no_proxy=args.NO_PROXY, + timeout=args.TIMEOUT, + ) + if not success: + lib.base.cu(token) + + # get tickets + success, tickets = lib.avelon.get_tickets( + access_token=token['access_token'], + insecure=args.INSECURE, + no_proxy=args.NO_PROXY, + timeout=args.TIMEOUT, + ) + if not success: + lib.base.cu(tickets) + else: + # do not call the command, put in test data + stdout, stderr, retc = lib.test.test(args.TEST) + tickets = json.loads(stdout) + + # analyze tickets + for ticket in tickets: + if ticket['type'] == 'ALARM': + locked_state = STATE_OK + if ticket['status'] in args.CRIT: + locked_state = STATE_CRIT + elif ticket['status'] in args.WARN: + locked_state = STATE_WARN + state = lib.base.get_worst(state, locked_state) + + # Format timestamp + timestamp = datetime.datetime.strptime(ticket['created'], "%Y-%m-%dT%H:%M:%S.%f%z").strftime("%Y-%m-%d %H:%M:%S") + + # Ticket filter for CLOSED tickets + if ticket['status'] != 'CLOSED' or args.CLOSED_TICKET: + # build ticket_table + ticket_table.append({ + 'id': ticket['id'], + 'timestamp': timestamp + ' (' + lib.human.seconds2human(lib.time.timestrdiff(lib.time.now(as_type='iso'), timestamp)) + ' ago)', + 'msg': re.sub(r'^ALARM: ', '', ticket['message']), + 'state': ticket['status'] + lib.base.state2str(locked_state, prefix=' '), + }) + + if state == STATE_CRIT: + msg = 'There are CRITICAL alarm ticket(s).\n\n' + msg + elif state == STATE_WARN: + msg = 'There are WARNING alarm ticket(s).\n\n' + msg + else: + msg = 'Everything is ok.\n\n' + msg + + # build the message + if ticket_table: + keys = [ + 'id', + 'timestamp', + 'msg', + 'state', + ] + headers = [ + 'ID', + 'Timestamp', + 'Message', + 'State', + ] + + msg += lib.base.get_table( + sorted(ticket_table, key=lambda d: d['id']), + keys, + header=headers, + ) + + # over and out + lib.base.oao(msg, state, always_ok=args.ALWAYS_OK) + + +if __name__ == '__main__': + try: + main() + except Exception: # pylint: disable=W0703 + lib.base.cu() diff --git a/check-plugins/avelon-tickets/icingaweb2-module-director/avelon-tickets.json b/check-plugins/avelon-tickets/icingaweb2-module-director/avelon-tickets.json new file mode 100644 index 00000000..d7bdfd4a --- /dev/null +++ b/check-plugins/avelon-tickets/icingaweb2-module-director/avelon-tickets.json @@ -0,0 +1,351 @@ +{ + "Command": { + "cmd-check-avelon-tickets": { + "arguments": { + "--always-ok": { + "set_if": "$avelon_tickets_always_ok$" + }, + "--client-id": { + "value": "$avelon_tickets_client_id$" + }, + "--client-secret": { + "value": "$avelon_tickets_client_secret$" + }, + "--closed-ticket": { + "set_if": "$avelon_tickets_closed_ticket$" + }, + "--critical": { + "value": "$avelon_tickets_critical$" + }, + "--insecure": { + "set_if": "$avelon_tickets_insecure$" + }, + "--no-proxy": { + "set_if": "$avelon_tickets_no_proxy$" + }, + "--password": { + "value": "$avelon_tickets_password$" + }, + "--username": { + "value": "$avelon_tickets_username$" + }, + "--timeout": { + "value": "$avelon_tickets_timeout$" + }, + "--warning": { + "value": "$avelon_tickets_warning$" + } + }, + "command": "/usr/bin/sudo /usr/lib64/nagios/plugins/avelon-tickets", + "disabled": false, + "fields": [ + { + "datafield_id": 1, + "is_required": "n", + "var_filter": null + }, + { + "datafield_id": 2, + "is_required": "y", + "var_filter": null + }, + { + "datafield_id": 3, + "is_required": "y", + "var_filter": null + }, + { + "datafield_id": 4, + "is_required": "n", + "var_filter": null + }, + { + "datafield_id": 5, + "is_required": "n", + "var_filter": null + }, + { + "datafield_id": 6, + "is_required": "n", + "var_filter": null + }, + { + "datafield_id": 7, + "is_required": "n", + "var_filter": null + }, + { + "datafield_id": 8, + "is_required": "y", + "var_filter": null + }, + { + "datafield_id": 9, + "is_required": "y", + "var_filter": null + }, + { + "datafield_id": 10, + "is_required": "n", + "var_filter": null + }, + { + "datafield_id": 11, + "is_required": "n", + "var_filter": null + } + ], + "imports": [], + "is_string": null, + "methods_execute": "PluginCheck", + "object_name": "cmd-check-avelon-tickets", + "object_type": "object", + "timeout": 30, + "vars": {}, + "zone": null, + "uuid": "4984cd39-46c3-456d-beb6-57126bae63bb" + } + }, + "ServiceTemplate": { + "tpl-service-avelon-tickets": { + "action_url": null, + "apply_for": null, + "assign_filter": null, + "check_command": "cmd-check-avelon-tickets", + "check_interval": 60, + "check_period": null, + "check_timeout": null, + "command_endpoint": null, + "disabled": false, + "display_name": null, + "enable_active_checks": null, + "enable_event_handler": null, + "enable_flapping": null, + "enable_notifications": true, + "enable_passive_checks": null, + "enable_perfdata": false, + "event_command": null, + "fields": [], + "flapping_threshold_high": null, + "flapping_threshold_low": null, + "groups": [], + "host": null, + "icon_image": "avelon-tickets.png", + "icon_image_alt": null, + "imports": [ + "tpl-service-generic" + ], + "max_check_attempts": 4, + "notes": "The current tickets (alerts) of your Avelon Cloud are being reviewed, and depending on their status, critical alerts or warnings can be triggered. You need a license to access the public API of the Avelon Cloud.", + "notes_url": "https://github.com/Linuxfabrik/monitoring-plugins/tree/main/check-plugins/avelon-tickets", + "object_name": "tpl-service-avelon-tickets", + "object_type": "template", + "retry_interval": 15, + "service_set": null, + "template_choice": null, + "use_agent": null, + "use_var_overrides": null, + "vars": { + "criticality": "C", + "avelon_tickets_always_ok": false, + "avelon_tickets_closed_ticket": false, + "avelon_tickets_critical": [], + "avelon_tickets_insecure": false, + "avelon_tickets_no_proxy": false, + "avelon_tickets_timeout": 8, + "avelon_tickets_warning": [ + "ACKNOWLEDGED", + "ACKNOWLEDGED_AND_GONE", + "GONE", + "OPEN" + ] + }, + "volatile": null, + "zone": null, + "uuid": "7a88cf8d-c01a-42f7-a8fc-66d95fde9a5d" + } + }, + "DataList": { + "avelon_tickets_critical_list": { + "list_name": "avelon_tickets_critical_list", + "owner": "icinga-admin", + "entries": [ + { + "entry_name": "ACKNOWLEDGED", + "entry_value": "Acknowledged", + "format": "string", + "allowed_roles": null + }, + { + "entry_name": "ACKNOWLEDGED_AND_GONE", + "entry_value": "Acknowledged And Gone", + "format": "string", + "allowed_roles": null + }, + { + "entry_name": "GONE", + "entry_value": "Gone", + "format": "string", + "allowed_roles": null + }, + { + "entry_name": "OPEN", + "entry_value": "Open", + "format": "string", + "allowed_roles": null + } + ], + "uuid": "fe70f681-28ef-4d1f-95ee-ce99ee983232" + }, + "avelon_tickets_warning_list": { + "list_name": "avelon_tickets_warning_list", + "owner": "icinga-admin", + "entries": [ + { + "entry_name": "ACKNOWLEDGED", + "entry_value": "Acknowledged", + "format": "string", + "allowed_roles": null + }, + { + "entry_name": "ACKNOWLEDGED_AND_GONE", + "entry_value": "Acknowledged And Gone", + "format": "string", + "allowed_roles": null + }, + { + "entry_name": "GONE", + "entry_value": "Gone", + "format": "string", + "allowed_roles": null + }, + { + "entry_name": "OPEN", + "entry_value": "Open", + "format": "string", + "allowed_roles": null + } + ], + "uuid": "1c4e131f-22c0-4238-b2a6-7bb50198090b" + } + }, + "Datafield": { + "1": { + "varname": "avelon_tickets_always_ok", + "caption": "Avelon Tickets: Always OK?", + "description": "Always returns OK.", + "datatype": "Icinga\\Module\\Director\\DataType\\DataTypeBoolean", + "format": null, + "settings": {}, + "uuid": "c4d5d2a6-028c-46a2-9fa4-82dfe45cd187" + }, + "2": { + "varname": "avelon_tickets_client_id", + "caption": "Avelon Tickets: Client ID", + "description": "Avelon API client_id.", + "datatype": "Icinga\\Module\\Director\\DataType\\DataTypeString", + "format": null, + "settings": { + "visibility": "visible" + }, + "uuid": "26f07670-49d1-4102-98c6-1f80293c34b4" + }, + "3": { + "varname": "avelon_tickets_client_secret", + "caption": "Avelon Tickets: Client Secret", + "description": "Avelon API client_secret.", + "datatype": "Icinga\\Module\\Director\\DataType\\DataTypeString", + "format": null, + "settings": { + "visibility": "visible" + }, + "uuid": "84dc37e3-b0f6-4879-8005-4efa34713c75" + }, + "4": { + "varname": "avelon_tickets_closed_ticket", + "caption": "Avelon Tickets: Closed Ticket?", + "description": "The option allows viewing the closed alarms as well.", + "datatype": "Icinga\\Module\\Director\\DataType\\DataTypeBoolean", + "format": null, + "settings": {}, + "uuid": "0c8e75bd-35ec-490c-823b-6313c6004407" + }, + "5": { + "varname": "avelon_tickets_critical", + "caption": "Avelon Tickets: Critical", + "description": "Set the CRIT threshold as a status of the ticket (alarm).", + "datatype": "Icinga\\Module\\Director\\DataType\\DataTypeDatalist", + "format": null, + "settings": { + "behavior": "strict", + "data_type": "string", + "datalist": "avelon_tickets_critical_list" + }, + "uuid": "d2a6d1af-c584-4a00-8405-4029ca00ad14" + }, + "6": { + "varname": "avelon_tickets_insecure", + "caption": "Avelon Tickets: Insecure?", + "description": "This option explicitly allows to perform \"insecure\" SSL connections.", + "datatype": "Icinga\\Module\\Director\\DataType\\DataTypeBoolean", + "format": null, + "settings": {}, + "uuid": "54c366c2-9775-4a00-9314-11b725c6496b" + }, + "7": { + "varname": "avelon_tickets_no_proxy", + "caption": "Avelon Tickets: No Proxy?", + "description": "Do not use a proxy.Default: %(default)s", + "datatype": "Icinga\\Module\\Director\\DataType\\DataTypeBoolean", + "format": null, + "settings": {}, + "uuid": "289c407d-af81-4ddd-92c1-fe529dcb33b7" + }, + "8": { + "varname": "avelon_tickets_password", + "caption": "Avelon Tickets: Password", + "description": "Avelon Cloud password.", + "datatype": "Icinga\\Module\\Director\\DataType\\DataTypeString", + "format": null, + "settings": { + "visibility": "hidden" + }, + "uuid": "e8ac942f-2f09-44ec-a490-b86347fe8660" + }, + "9": { + "varname": "avelon_tickets_username", + "caption": "Avelon Tickets: Username", + "description": "Avelon Cloud username.", + "datatype": "Icinga\\Module\\Director\\DataType\\DataTypeString", + "format": null, + "settings": { + "visibility": "visible" + }, + "uuid": "524dd1e9-b762-40fb-861f-7497ffcb2e5a" + }, + "10": { + "varname": "avelon_tickets_timeout", + "caption": "Avelon Tickets: Timeout", + "description": "Network timeout in seconds.", + "datatype": "Icinga\\Module\\Director\\DataType\\DataTypeString", + "format": null, + "settings": { + "visibility": "visible" + }, + "uuid": "582299ec-1093-46f7-bfd1-ee3e504f3627" + }, + "11": { + "varname": "avelon_tickets_warning", + "caption": "Avelon Tickets: Warning", + "description": "Set the WARN threshold as a status of the ticket (alarm).", + "datatype": "Icinga\\Module\\Director\\DataType\\DataTypeDatalist", + "format": null, + "settings": { + "behavior": "strict", + "data_type": "string", + "datalist": "avelon_tickets_warning_list" + }, + "uuid": "bb372f8f-ba91-4d3c-8740-f7901881f380" + } + } +} diff --git a/check-plugins/avelon-tickets/icingaweb2-module-director/avelon-tickets.yml b/check-plugins/avelon-tickets/icingaweb2-module-director/avelon-tickets.yml new file mode 100644 index 00000000..33bde1bb --- /dev/null +++ b/check-plugins/avelon-tickets/icingaweb2-module-director/avelon-tickets.yml @@ -0,0 +1,6 @@ +--- +overwrites: + '["Command"]["cmd-check-avelon-tickets"]["timeout"]': 30 + '["Command"]["cmd-check-avelon-tickets"]["command"]': '/usr/bin/sudo /usr/lib64/nagios/plugins/avelon-tickets' + '["ServiceTemplate"]["tpl-service-avelon-tickets"]["enable_perfdata"]': false + '["ServiceTemplate"]["tpl-service-avelon-tickets"]["max_check_attempts"]': 4 diff --git a/check-plugins/avelon-tickets/unit-test/run b/check-plugins/avelon-tickets/unit-test/run new file mode 100755 index 00000000..e4bd00fe --- /dev/null +++ b/check-plugins/avelon-tickets/unit-test/run @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8; py-indent-offset: 4 -*- +# +# Author: Linuxfabrik GmbH, Zurich, Switzerland +# Contact: info (at) linuxfabrik (dot) ch +# https://www.linuxfabrik.ch/ +# License: The Unlicense, see LICENSE file. + +# https://github.com/Linuxfabrik/monitoring-plugins/blob/main/CONTRIBUTING.rst + +import sys +sys.path.append("..") # Adds higher directory to python modules path. + + + +import unittest + +from lib.globals import STATE_OK, STATE_UNKNOWN, STATE_WARN, STATE_CRIT +import lib.base +import lib.shell + + +class TestCheck(unittest.TestCase): + + check = '../avelon-tickets' + def test_if_check_runs_tickets(self): + stdout, stderr, retc = lib.base.coe(lib.shell.shell_exec(self.check + ' --client-id "CLIENTID" --client-secret "CLIENTSECRET" --username "USERNAME" --password "PASSWORD" --test=stdout/EXAMPLE01,,0')) + self.assertIn('There are WARNING alarm ticket(s).', stdout) + self.assertIn('', stdout) + self.assertIn('ID ! Timestamp ! Message ! State', stdout) + self.assertIn('---------+----------------------------------+-------------------------------------------------------------+------------------------', stdout) + self.assertIn('13927572 ! 2024-06-18 19:46:56 (5D 13h ago) ! Abschaltend: 6102/5/22: Durchfluss Notkühlung FQ201 Störung ! OPEN [WARNING]', stdout) + self.assertIn('13927573 ! 2024-06-18 19:46:56 (5D 13h ago) ! Störung: 6102/5/0: Anlage Zustand Störung ! ACKNOWLEDGED [WARNING]', stdout) + self.assertEqual(stderr, '') + self.assertEqual(retc, STATE_WARN) + + def test_if_check_runs_tickets(self): + stdout, stderr, retc = lib.base.coe(lib.shell.shell_exec(self.check + ' --client-id "CLIENTID" --client-secret "CLIENTSECRET" --username "USERNAME" --password "PASSWORD" --critical ACKNOWLEDGED OPEN --test=stdout/EXAMPLE01,,0')) + self.assertIn('There are CRITICAL alarm ticket(s).', stdout) + self.assertIn('', stdout) + self.assertIn('ID ! Timestamp ! Message ! State', stdout) + self.assertIn('---------+----------------------------------+-------------------------------------------------------------+-------------------------', stdout) + self.assertIn('13927572 ! 2024-06-18 19:46:56 (5D 13h ago) ! Abschaltend: 6102/5/22: Durchfluss Notkühlung FQ201 Störung ! OPEN [CRITICAL]', stdout) + self.assertIn('13927573 ! 2024-06-18 19:46:56 (5D 13h ago) ! Störung: 6102/5/0: Anlage Zustand Störung ! ACKNOWLEDGED [CRITICAL]', stdout) + self.assertEqual(stderr, '') + self.assertEqual(retc, STATE_CRIT) + + def test_if_check_runs_tickets(self): + stdout, stderr, retc = lib.base.coe(lib.shell.shell_exec(self.check + ' --client-id "CLIENTID" --client-secret "CLIENTSECRET" --username "USERNAME" --password "PASSWORD" --warning ACKNOWLEDGED --critical OPEN --test=stdout/EXAMPLE01,,0')) + self.assertIn('There are CRITICAL alarm ticket(s).', stdout) + self.assertIn('', stdout) + self.assertIn('ID ! Timestamp ! Message ! State', stdout) + self.assertIn('---------+----------------------------------+-------------------------------------------------------------+------------------------', stdout) + self.assertIn('13927572 ! 2024-06-18 19:46:56 (5D 13h ago) ! Abschaltend: 6102/5/22: Durchfluss Notkühlung FQ201 Störung ! OPEN [CRITICAL]', stdout) + self.assertIn('13927573 ! 2024-06-18 19:46:56 (5D 13h ago) ! Störung: 6102/5/0: Anlage Zustand Störung ! ACKNOWLEDGED [WARNING]', stdout) + self.assertEqual(stderr, '') + self.assertEqual(retc, STATE_CRIT) + + def test_if_check_runs_tickets(self): + stdout, stderr, retc = lib.base.coe(lib.shell.shell_exec(self.check + ' --client-id "CLIENTID" --client-secret "CLIENTSECRET" --username "USERNAME" --password "PASSWORD" --test=stdout/EXAMPLE02,,0')) + self.assertIn('There are WARNING alarm ticket(s).', stdout) + self.assertIn('', stdout) + self.assertIn('ID ! Timestamp ! Message ! State', stdout) + self.assertIn('---------+----------------------------------+-------------------------------------------+------------------------', stdout) + self.assertIn('13927573 ! 2024-06-18 19:46:56 (5D 13h ago) ! Störung: 6102/5/0: Anlage Zustand Störung ! ACKNOWLEDGED [WARNING]', stdout) + self.assertEqual(stderr, '') + self.assertEqual(retc, STATE_WARN) + + def test_if_check_runs_tickets(self): + stdout, stderr, retc = lib.base.coe(lib.shell.shell_exec(self.check + ' --client-id "CLIENTID" --client-secret "CLIENTSECRET" --username "USERNAME" --password "PASSWORD" --closed-ticket --test=stdout/EXAMPLE03,,0')) + self.assertIn('Everything is ok.', stdout) + self.assertIn('', stdout) + self.assertIn('ID ! Timestamp ! Message ! State', stdout) + self.assertIn('---------+---------------------------------+------------------------------------------------------------------+--------', stdout) + self.assertIn('13915922 ! 2024-06-14 23:58:36 (1W 2D ago) ! Störung: 6102/5/5: Vorlauftemperatur TT201 zu tief -> Notkühlung ! CLOSED', stdout) + self.assertEqual(stderr, '') + self.assertEqual(retc, STATE_OK) + + def test_if_check_runs_tickets(self): + stdout, stderr, retc = lib.base.coe(lib.shell.shell_exec(self.check + ' --client-id "CLIENTID" --client-secret "CLIENTSECRET" --username "USERNAME" --password "PASSWORD" --test=stdout/EXAMPLE04,,0')) + self.assertIn('Everything is ok.', stdout) + self.assertEqual(stderr, '') + self.assertEqual(retc, STATE_OK) + +if __name__ == '__main__': + unittest.main() + + diff --git a/check-plugins/avelon-tickets/unit-test/stdout/EXAMPLE01 b/check-plugins/avelon-tickets/unit-test/stdout/EXAMPLE01 new file mode 100644 index 00000000..7da7c534 --- /dev/null +++ b/check-plugins/avelon-tickets/unit-test/stdout/EXAMPLE01 @@ -0,0 +1,41 @@ +[ + { + "id": 13927572, + "type": "ALARM", + "message": "ALARM: Abschaltend: 6102/5/22: Durchfluss Notk\u00fchlung FQ201 St\u00f6rung", + "status": "OPEN", + "created": "2024-06-18T19:46:56.000+02:00", + "modified": "2024-06-18T19:47:33.000+02:00", + "resolved": null, + "closable": false, + "dataPointId": 1389273, + "deviceId": 10149, + "recurrences": 6 + }, + { + "id": 13927573, + "type": "ALARM", + "message": "ALARM: St\u00f6rung: 6102/5/0: Anlage Zustand St\u00f6rung", + "status": "ACKNOWLEDGED", + "created": "2024-06-18T19:46:56.000+02:00", + "modified": "2024-06-19T14:43:35.000+02:00", + "resolved": null, + "closable": false, + "dataPointId": 1389326, + "deviceId": 10149, + "recurrences": 6 + }, + { + "id": 13915922, + "type": "ALARM", + "message": "ALARM: St\u00f6rung: 6102/5/5: Vorlauftemperatur TT201 zu tief -> Notk\u00fchlung", + "status": "CLOSED", + "created": "2024-06-14T23:58:36.000+02:00", + "modified": "2024-06-17T08:04:46.000+02:00", + "resolved": "2024-06-17T08:04:46.000+02:00", + "closable": false, + "dataPointId": 1389359, + "deviceId": 10149, + "recurrences": 55 + } +] \ No newline at end of file diff --git a/check-plugins/avelon-tickets/unit-test/stdout/EXAMPLE02 b/check-plugins/avelon-tickets/unit-test/stdout/EXAMPLE02 new file mode 100644 index 00000000..b8d57bcd --- /dev/null +++ b/check-plugins/avelon-tickets/unit-test/stdout/EXAMPLE02 @@ -0,0 +1,28 @@ +[ + { + "id": 13927573, + "type": "ALARM", + "message": "ALARM: St\u00f6rung: 6102/5/0: Anlage Zustand St\u00f6rung", + "status": "ACKNOWLEDGED", + "created": "2024-06-18T19:46:56.000+02:00", + "modified": "2024-06-19T14:43:35.000+02:00", + "resolved": null, + "closable": false, + "dataPointId": 1389326, + "deviceId": 10149, + "recurrences": 6 + }, + { + "id": 13915922, + "type": "ALARM", + "message": "ALARM: St\u00f6rung: 6102/5/5: Vorlauftemperatur TT201 zu tief -> Notk\u00fchlung", + "status": "CLOSED", + "created": "2024-06-14T23:58:36.000+02:00", + "modified": "2024-06-17T08:04:46.000+02:00", + "resolved": "2024-06-17T08:04:46.000+02:00", + "closable": false, + "dataPointId": 1389359, + "deviceId": 10149, + "recurrences": 55 + } +] \ No newline at end of file diff --git a/check-plugins/avelon-tickets/unit-test/stdout/EXAMPLE03 b/check-plugins/avelon-tickets/unit-test/stdout/EXAMPLE03 new file mode 100644 index 00000000..4503818f --- /dev/null +++ b/check-plugins/avelon-tickets/unit-test/stdout/EXAMPLE03 @@ -0,0 +1,15 @@ +[ + { + "id": 13915922, + "type": "ALARM", + "message": "ALARM: St\u00f6rung: 6102/5/5: Vorlauftemperatur TT201 zu tief -> Notk\u00fchlung", + "status": "CLOSED", + "created": "2024-06-14T23:58:36.000+02:00", + "modified": "2024-06-17T08:04:46.000+02:00", + "resolved": "2024-06-17T08:04:46.000+02:00", + "closable": false, + "dataPointId": 1389359, + "deviceId": 10149, + "recurrences": 55 + } +] \ No newline at end of file diff --git a/check-plugins/avelon-tickets/unit-test/stdout/EXAMPLE04 b/check-plugins/avelon-tickets/unit-test/stdout/EXAMPLE04 new file mode 100644 index 00000000..0637a088 --- /dev/null +++ b/check-plugins/avelon-tickets/unit-test/stdout/EXAMPLE04 @@ -0,0 +1 @@ +[] \ No newline at end of file