image
В данной статье хотел бы рассказать об отправке уведомлений в Telegram чат при использовании SaltStack. Начиная с версии 2015.5.0, SaltStack предоставляет интеграцию со Slack из коробки, однако Telegram также является популярным мессенджером и активно используется среди российских пользователей. Поэтому надеюсь, что статья окажется полезна ее читателям.


Введение


Вообще говоря, SaltStack представляет собой конструктор и, как и многие другие инструменты, предоставляет возможности для кастомизации и расширения. В частности, собственные исполняемые модули.


О том, как можно создать Telegram бота на Python подробно рассказывается здесь. В качестве дополнения будет описано, как, используя небольшой Python-модуль, такой подход можно привязать к SaltStack.


Процесс настройки


Приступать к написанию модуля следует после того, как:


  1. Создан бот
  2. Бот дабавлен в чат
  3. Получен chat_id

Примечание. Получить id чата можно с помощью следующего скрипта на python:


import requests

URL = 'https://api.telegram.org/bot'
TOKEN = <токен вашего бота>

try:
    request = requests.post('{url}{token}/getUpdates'.format(url=URL, token=TOKEN))
    print request.json()['result'][0]['message']['chat']['id']
except Exception,e:
    print str(e)

Итак, переходим к главному. Как описано в документации, SaltStack модуль должен располагаться в директории _modules/ и выглядеть следующим образом:


import requests

URL='https://api.telegram.org/bot'

def notify(message, token, chat_id):
        message_data = {
                'chat_id': chat_id,
                'text': message
        }

        try:
                request = requests.post('{url}{token}/sendMessage'.format(url=URL, token=token), data=message_data)
        except Exception,e:
                return False, str(e)

        if not request.status_code == 200:
                return False, "Return status is unsuccessful"
        # для наглядности вторым значением возвращается строка со служебной информацией.
        return True, "Message was successfully sent"

Далее необходимо выполнить команду синхронизации модулей, чтобы они появились на миньонах:
salt '*' saltutil.sync_modules


Если все завершилось успешно, результат будет примерно следующим:


image


И, напоследок, создаем файл состояния (в данном примере — send_telegram.sls)


send message about minion id:
  module.run:
    # telegram - имя python-модуля, notify - метод в этом модуле
    - name: telegram.notify
    - kwargs:
      message: command executed on minion with id {{ grains['id'] }}
      token: <токен вашего бота>
      chat_id: <id чата в Telegram>

Проверяем работоспособность созданного модуля:
salt '*' state.apply send_telegram


На стороне мастера:


image


В чате:


image


Источники


  1. Телеграм бот на Python с использованием только requests
  2. Writing execution modules
  3. How do I use salt states?

Поделиться с друзьями
-->

Комментарии (7)


  1. farcaller
    03.06.2017 11:53

    А в чем смысл модуля, который шлет уведомления в телеграм? Может вам returner проще было бы сделать?


    1. SirEdvin
      03.06.2017 13:26

      Зависит от того, что делать через saltstack. Если на нем завязан деплой на тест, то почему бы и нет?


      1. tikhoa
        03.06.2017 13:59

        К тому же может понадобиться расширить модуль и использовать другие возможности API.


      1. farcaller
        03.06.2017 14:26

        не совсем понимаю. То что вы делаете сейчас — это исключительно уведомительная вещь, нет? Тогда вам проще просто дергать "чистый" state, и через returner возврящать статус в человеко-читаемом виде в телеграм.


        1. SirEdvin
          03.06.2017 14:28

          Я плохо знаю salt, но тут имеется ввиду отправить сообщение в духе "деплой закончен". Зачем вам тут state?


          1. farcaller
            03.06.2017 14:47

            а как вы деплоите в принципе? state.apply на sls? или orchestrate?


        1. tikhoa
          03.06.2017 15:59

          Мне кажется оба варианта удобны. Единственное, если у вас стэйт файл состоит из нескольких шагов, с помощью модуля возможна отсылка уведомлений по завершению каждого из них. Насчёт returner'а не уверен.