From 1a06419bc2914f883ff24d89d1410e5bdd273443 Mon Sep 17 00:00:00 2001 From: Simple_Not <44047940+moonbaseDelta@users.noreply.github.com> Date: Wed, 8 Nov 2023 22:40:04 +1000 Subject: [PATCH] upd ansi: add tg --- ansible.cfg | 6 ++ plugins/callback/telegram.py | 198 +++++++++++++++++++++++++++++++++++ 2 files changed, 204 insertions(+) create mode 100644 plugins/callback/telegram.py diff --git a/ansible.cfg b/ansible.cfg index 12920d4..a719725 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -7,3 +7,9 @@ bin_ansible_callbacks = True host_key_checking = false vault_password_file = /etc/ansible/.vaulto + +callback_whitelist = telegram + +[callback_telegram] +tg_token = 6472915685:AAHPvgrQoqG7DxtfbnHWPe3Lfild-CGJ1j8 +tg_chat_id = -4023350326 \ No newline at end of file diff --git a/plugins/callback/telegram.py b/plugins/callback/telegram.py new file mode 100644 index 0000000..a7c09b2 --- /dev/null +++ b/plugins/callback/telegram.py @@ -0,0 +1,198 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +DOCUMENTATION = ''' + callback: telegram + callback_type: notification + requirements: + - whitelist in configuration + - telebot (pip install pyTelegramBotApi) + - prettytable (pip install prettytable) + - latest requests (pip install requests --upgrade) + short_description: Sends play events to a telegram channel + version_added: "2.1" + description: + - This is an ansible callback plugin that sends status updates to a telegram channel during playbook execution. + - Before 2.4 only environment variables were available for configuring this plugin + options: + tg_token: + required: True + description: telegram bot token + env: + - name: TG_TOKEN + ini: + - section: callback_telegram + key: tg_token + tg_chat_id: + required: True + description: telegram chat id to post in. + env: + - name: TG_CHAT_ID + ini: + - section: callback_telegram + key: tg_chat_id + socks5_uri: + description: socks5 proxy uri to bypass rkn's restarictions + env: + - name: SOCKS5_URI + ini: + - section: callback_telegram + key: socks5_uri +''' + +import os +from datetime import datetime + +from ansible import context +from ansible.module_utils._text import to_text +from ansible.module_utils.urls import open_url +from ansible.plugins.callback import CallbackBase + +try: + import telebot + from telebot import apihelper + HAS_TELEBOT = True +except ImportError: + HAS_TELEBOT = False + +try: + import prettytable + HAS_PRETTYTABLE = True +except ImportError: + HAS_PRETTYTABLE = False + +class CallbackModule(CallbackBase): + """This is an ansible callback plugin that sends status + updates to a telegram channel during playbook execution. + """ + CALLBACK_VERSION = 2.0 + CALLBACK_TYPE = 'notification' + CALLBACK_NAME = 'telegram' + CALLBACK_NEEDS_WHITELIST = True + + def __init__(self, display=None): + + super(CallbackModule, self).__init__(display=display) + + if not HAS_TELEBOT: + self.disabled = True + self._display.warning('The `telebot` python module is not ' + 'installed. Disabling the Slack callback ' + 'plugin.') + + if not HAS_PRETTYTABLE: + self.disabled = True + self._display.warning('The `prettytable` python module is not ' + 'installed. Disabling the Slack callback ' + 'plugin.') + + self.playbook_name = None + self.play = None + self.now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + + def set_options(self, task_keys=None, var_options=None, direct=None): + + super(CallbackModule, self).set_options(task_keys=task_keys, var_options=var_options, direct=direct) + + self.tg_token = self.get_option('tg_token') + self.tg_chat_id = self.get_option('tg_chat_id') + self.socks5_uri = self.get_option('socks5_uri') + + if self.tg_token is None: + self.disabled = True + self._display.warning('tg_token was not provided. The ' + 'tg_token can be provided using ' + 'the `TG_TOKEN` environment ' + 'variable.') + + if self.tg_chat_id is None: + self.disabled = True + self._display.warning('tg_chat_id was not provided. The ' + 'tg_chat_id can be provided using ' + 'the `TG_CHAT_ID` environment ' + 'variable.') + + def send_msg(self, msg): + if self.socks5_uri is not None: + apihelper.proxy = {'https': self.socks5_uri} + bot = telebot.TeleBot(self.tg_token) + bot.send_message(self.tg_chat_id, msg, parse_mode='HTML') + + def v2_playbook_on_start(self, playbook): + + self.playbook_name = os.path.abspath(playbook._file_name) + + def v2_playbook_on_play_start(self, play): + self.play = play + + title = [ + 'Ansible: STARTED ⚙️' + ] + + msg_items = [' '.join(title)] + msg_items.append('\n time: ' + '' + str(self.now) + '') + msg_items.append('playbook: ' + '' + self.playbook_name + '') + msg_items.append(' hosts:') + for host in play.hosts: + msg_items.append(' - ' + host + '') + msg_items.append(' tags:') + for tag in play.only_tags: + msg_items.append(' - ' + tag + '') + msg = '\n'.join(msg_items) + self.send_msg(msg=msg) + + def v2_runner_on_failed(self, result, ignore_errors=False): + + msg = [] + title = [ + 'Ansible: FAILED ❌' + ] + msg_items = [' '.join(title)] + msg_items.append('\n time: ' + '' + str(self.now) + '') + msg_items.append('playbook: ' + '' + self.playbook_name + '') + msg_items.append(' host: ' + '' + result._host.get_name() + '') + msg_items.append(' stderr: ' + '' + result._result['stderr'] + '') + + msg = '\n'.join(msg_items) + + self.send_msg(msg=msg) + + def v2_playbook_on_stats(self, stats): + """Display info about playbook statistics""" + + hosts = sorted(stats.processed.keys()) + + t = prettytable.PrettyTable(['Host', 'Ok', 'Changed', 'Unreachable', + 'Failures', 'Rescued', 'Ignored']) + + failures = False + unreachable = False + + for h in hosts: + s = stats.summarize(h) + + if s['failures'] > 0: + failures = True + if s['unreachable'] > 0: + unreachable = True + + t.add_row([h] + [s[k] for k in ['ok', 'changed', 'unreachable', + 'failures', 'rescued', 'ignored']]) + + msg = [] + title = 'Ansible: ENDED' + if failures or unreachable: + msg_items = [ + title + ' ❌' + ] + else: + msg_items = [ + title + ' ✅' + ] + msg_items.append('\n time: ' + '' + str(self.now) + '') + msg_items.append('playbook: ' + '' + self.playbook_name + '') + msg_items.append('\n%s\n' % t) + + msg = '\n'.join(msg_items) + + self.send_msg(msg=msg) \ No newline at end of file