2018年10月8日月曜日

slack + errbot(python)でAWSリソースを表示してみる


Slackとpython製の errbot を使用して、以下の動作を試してみた。

 1) Slack に "!subnet search" と入力する
 2) ボットがAWSを検索してサブネット一覧を取得する
 3) サブネット一覧をSlackに表示する

errbot は VirtualBox(CentOS7)のDockerコンテナで動かします。


1.errbot のDockerイメージ作成



Dockerfileは以下のようにしました。
FROM python:3.5.2-alpine

# apk update
RUN apk update

# for errbot
RUN apk add gcc g++ libffi-dev openssl-dev

# for develop
RUN apk add vim bash

# errbot, boto3
RUN pip install errbot slackclient boto3

# aws accesskey
ADD .aws /root/.aws

# errbot external plugins
ADD errbot-root /errbot-root

# entrypoint
ENV OPT ""
Entrypoint cd /errbot-root && errbot $OPT

ディレクトリ構成は以下のとおり。
errbot-root は空です。.aws には config と credentials があります。
[root@centos702 errbot]# ls -al
合計 4
drwxr-xr-x 5 root root  74 10月  8 11:18 .
drwxr-xr-x 4 root root  37 10月  6 21:45 ..
drwxr-xr-x 2 root root  56 10月  8 00:45 .aws
-rw-r--r-- 1 root root 365 10月  8 11:17 Dockerfile
drwxr-xr-x 2 root root   6 10月  8 11:19 errbot-root

Dockerイメージをビルドします。
[root@centos702 errbot]# docker build . -t bot

2.errbot の初期化と動作確認


errbot を初期化します。
[root@centos702 slackbot]# docker run --rm -v `pwd`/errbot-root:/errbot-root --env "OPT=--init" -it bot
Your Errbot directory has been correctly initialized !
Just do "errbot" and it should start in text/development mode.

空だったerrbot-root ディレクトリに、設定ファイルと 拡張プラグインのひな形が作成されます。
[root@centos702 errbot]# ls -l errbot-root
合計 4
-rw-r--r-- 1 root root 680 10月  8 11:42 config.py
drwxr-xr-x 2 root root   6 10月  8 11:42 data
drwxr-xr-x 3 root root  24 10月  8 11:42 plugins

errbot を起動します。
[root@centos702 errbot]# docker run --rm -v `pwd`/errbot-root:/errbot-root --env "OPT=--text" -it bot
02:45:47 INFO     errbot.specific_plugin_ma storage search paths {'/usr/local/lib/python3.5/site-packages/errbot/storage'}
02:45:47 INFO     errbot.specific_plugin_ma Found those plugings available:
02:45:47 INFO     errbot.specific_plugin_ma         Memory  (/usr/local/lib/python3.5/site-packages/errbot/storage/memory.py)
02:45:47 INFO     errbot.specific_plugin_ma          Shelf  (/usr/local/lib/python3.5/site-packages/errbot/storage/shelf.py)
02:45:47 INFO     errbot.bootstrap          Found Storage plugin: 'Shelf'
Description: This is the storage plugin for the traditional shelf store for errbot.
02:45:47 DEBUG    errbot.specific_plugin_ma Refilter the plugins...
02:45:47 DEBUG    errbot.specific_plugin_ma Load the one remaining...
02:45:47 DEBUG    errbot.specific_plugin_ma Class to load ShelfStoragePlugin
02:45:47 DEBUG    errbot.storage            Opening storage 'repomgr'
02:45:47 DEBUG    errbot.storage.shelf      Open shelf storage /errbot-root/data/repomgr.db
02:45:47 DEBUG    errbot.storage            Opening storage 'core'
02:45:47 DEBUG    errbot.storage.shelf      Open shelf storage /errbot-root/data/core.db
02:45:47 INFO     errbot.specific_plugin_ma backends search paths {'/usr/local/lib/python3.5/site-packages/errbot/backends'}
02:45:47 INFO     errbot.specific_plugin_ma Found those plugings available:
02:45:47 INFO     errbot.specific_plugin_ma        Graphic  (/usr/local/lib/python3.5/site-packages/errbot/backends/graphic.py)
02:45:47 INFO     errbot.specific_plugin_ma        Hipchat  (/usr/local/lib/python3.5/site-packages/errbot/backends/hipchat.py)
02:45:47 INFO     errbot.specific_plugin_ma            IRC  (/usr/local/lib/python3.5/site-packages/errbot/backends/irc.py)
02:45:47 INFO     errbot.specific_plugin_ma           Null  (/usr/local/lib/python3.5/site-packages/errbot/backends/null.py)
02:45:47 INFO     errbot.specific_plugin_ma          Slack  (/usr/local/lib/python3.5/site-packages/errbot/backends/slack.py)
02:45:47 INFO     errbot.specific_plugin_ma       Telegram  (/usr/local/lib/python3.5/site-packages/errbot/backends/telegram_messenger.py)
02:45:47 INFO     errbot.specific_plugin_ma           Test  (/usr/local/lib/python3.5/site-packages/errbot/backends/test.py)
02:45:47 INFO     errbot.specific_plugin_ma           Text  (/usr/local/lib/python3.5/site-packages/errbot/backends/text.py)
02:45:47 INFO     errbot.specific_plugin_ma           XMPP  (/usr/local/lib/python3.5/site-packages/errbot/backends/xmpp.py)
02:45:47 INFO     errbot.bootstrap          Found Backend plugin: 'Text'
                                                Description: This is the text backend for Err.
02:45:47 DEBUG    errbot.specific_plugin_ma Refilter the plugins...
02:45:47 DEBUG    errbot.specific_plugin_ma Load the one remaining...
02:45:47 DEBUG    errbot.specific_plugin_ma Class to load TextBackend
02:45:47 DEBUG    errbot.core               ErrBot init.
02:45:47 DEBUG    errbot.backends.base      Backend init.
02:45:47 DEBUG    errbot.core               created a thread pool of size 10.
02:45:47 DEBUG    errbot.backends.text      Text Backend Init.
02:45:47 DEBUG    errbot.backends.text      Bot username set at @errbot.
02:45:47 DEBUG    MARKDOWN                  Successfully loaded extension "markdown.extensions.fenced_code.FencedCodeExtension".
02:45:47 DEBUG    MARKDOWN                  Successfully loaded extension "markdown.extensions.footnotes.FootnoteExtension".
02:45:47 DEBUG    MARKDOWN                  Successfully loaded extension "markdown.extensions.attr_list.AttrListExtension".
02:45:47 DEBUG    MARKDOWN                  Successfully loaded extension "markdown.extensions.def_list.DefListExtension".
02:45:47 DEBUG    MARKDOWN                  Successfully loaded extension "markdown.extensions.tables.TableExtension".
02:45:47 DEBUG    MARKDOWN                  Successfully loaded extension "markdown.extensions.abbr.AbbrExtension".
02:45:47 DEBUG    MARKDOWN                  Successfully loaded extension "markdown.extensions.extra.ExtraExtension".
02:45:47 DEBUG    MARKDOWN                  Successfully loaded extension "errbot.rendering.ansiext.AnsiExtension".
02:45:47 DEBUG    errbot.core               Initializing backend storage
02:45:47 DEBUG    errbot.storage            Opening storage 'text_backend'
02:45:47 DEBUG    errbot.storage.shelf      Open shelf storage /errbot-root/data/text_backend.db
02:45:47 DEBUG    errbot.plugin_manager     All plugin roots:
02:45:47 DEBUG    errbot.plugin_manager     -> /usr/local/lib/python3.5/site-packages/errbot/core_plugins
02:45:47 DEBUG    errbot.plugin_manager     Add /usr/local/lib/python3.5/site-packages/errbot/core_plugins to sys.path
02:45:47 DEBUG    errbot.plugin_manager     -> /errbot-root/plugins/err-example
02:45:47 DEBUG    errbot.plugin_manager     Add /errbot-root/plugins/err-example to sys.path
02:45:47 DEBUG    errbot.plugin_manager     /usr/local/lib/python3.5/site-packages/errbot/core_plugins has no requirements.txt file
02:45:47 DEBUG    errbot.plugin_manager     /errbot-root/plugins/err-example has no requirements.txt file
02:45:47 DEBUG    errbot.plugins.ACLs       Logger for plugin initialized...
02:45:47 DEBUG    errbot.plugins.Backup     Logger for plugin initialized...
02:45:47 DEBUG    errbot.plugins.ChatRoom   Logger for plugin initialized...
02:45:47 DEBUG    errbot.plugins.CommandNot Logger for plugin initialized...
02:45:47 DEBUG    errbot.plugins.Flows      Logger for plugin initialized...
02:45:47 DEBUG    errbot.plugins.Health     Logger for plugin initialized...
02:45:47 DEBUG    errbot.plugins.Help       Logger for plugin initialized...
02:45:47 DEBUG    errbot.plugins.Plugins    Logger for plugin initialized...
02:45:47 DEBUG    errbot.plugins.TextCmds   Logger for plugin initialized...
02:45:47 DEBUG    errbot.plugins.Utils      Logger for plugin initialized...
02:45:48 DEBUG    errbot.plugins.VersionChe Logger for plugin initialized...
02:45:48 INFO     errbot                    webhooks:  Flag to bind /echo to                           echo
02:45:48 DEBUG    errbot.plugins.Webserver  Logger for plugin initialized...
02:45:48 DEBUG    errbot.plugins.Example    Logger for plugin initialized...
02:45:48 DEBUG    errbot.bootstrap          Start serving commands from the text backend
────────────────────────────────────────────────────────────────────────────────
 You start as a bot admin in a one-on-one conversation with the bot.

    Context of the chat

• Use !inroom to switch to a room conversation.
• Use !inperson to switch back to a one-on-one conversation.
• Use !asuser to talk as a normal user.
• Use !asadmin to switch back as a bot admin.

    Preferences

• Use !ml to flip on/off the multiline mode (Enter twice at the end to send).
────────────────────────────────────────────────────────────────────────────────

[@CHANGE_ME ➡ @errbot] >>> 

!tryme と入力してENTERし、It works ! と表示されたらOKです。
Ctrl+Dで終了します。
[@CHANGE_ME ➡ @errbot] >>> !tryme
It works !

[@CHANGE_ME ➡ @errbot] >>> [root@centos702 errbot]#


3.SlackでBotの作成


チャット画面の左メニューのApp の横にある[+] をクリックします。

[Appディレクトリ表示]をクリックします。

[ビルド]をクリックします。

[Start Building]をクリックします。

[AppName], [Development Slack Workspace]を入力して、[CreateApp]をクリックします。

[Bot Users]をクリックします。

[Add a Bot User]をクリックします。

[Add Bot User] をクリックします。

[Install App]をクリックします。

[Install App to Workspace] をクリックします。

[許可する]をクリックします。

[Bot User OAuth Access Token] を、errbot の設定で使用します。

あとで、Appの設定変更/確認したい場合は、[YourApp]をクリックします。
下図のようにAppの一覧が表示されるので、見たいAppをクリックします。

チャット画面にAppが追加されます。

4.errbot のSlack対応


errbot の config.py を修正します。修正ポイントは次のとおり。
・BACKENDは Slack に変更
・BOT_IDENTITY を追加。tokenには、上記3で作成したAppの Bot User OAuth Access Token を設定
・BOT_LOG_LEVELを logging.INFO に変更
[root@centos702 errbot]# cat errbot-root/config.py
import logging

# This is a minimal configuration to get you started with the Text mode.
# If you want to connect Errbot to chat services, checkout
# the options in the more complete config-template.py from here:
# https://raw.githubusercontent.com/errbotio/errbot/master/errbot/config-templat                                                           e.py

BACKEND = 'Slack'  # Errbot will start in text mode (console only mode) and will                                                            answer commands from there.

BOT_DATA_DIR = r'/errbot-root/data'
BOT_EXTRA_PLUGIN_DIR = r'/errbot-root/plugins'

BOT_LOG_FILE = r'/errbot-root/errbot.log'
BOT_LOG_LEVEL = logging.INFO

BOT_ADMINS = ('@blue21', )  # !! Don't leave that to "@CHANGE_ME" if you connect                                                            your errbot to a chat system !!

BOT_IDENTITY = {
    'token': 'xoxb-*******************************************'
}


5.errbot の拡張プラグイン作成


プラグインを格納するディレクトリを作成します。
[root@centos702 errbot]# mkdir errbot-root/plugins/aws

aws.plug を作成します。
[root@centos702 errbot]# cat errbot-root/plugins/aws/aws.plug
[Core]
Name = Aws
Module = aws

[Documentation]
Description = example aws.

[Python]
Version = 2+

aws.py を作成します。
[root@centos702 errbot]# cat errbot-root/plugins/aws/aws.py
import boto3
from errbot import BotPlugin, botcmd, arg_botcmd

class Aws(BotPlugin):

    @arg_botcmd('--key', dest='key', type=str, default='*')
    def subnet_search(self, msg, key=None):

        yield "検索中です ..."

        client = boto3.client('ec2')
        response = client.describe_subnets(
            Filters=[
                {
                    'Name': 'tag:Name',
                    'Values': [
                        key,
                    ]
                },
            ]
        )

        t=()
        for s in response['Subnets']:
            nm = [x['Value'] for x in s['Tags'] if x['Key'] == 'Name'][0]
            cidr = s['CidrBlock']
            t+=((nm,cidr),)

        self.send_card(title='** AWS Subnet List **',
                       body='検索キーワード=> ' + key,
                       color='green',
                       fields=t,
                       in_reply_to=msg)


6.動作確認


errbot を起動します。
[root@centos702 errbot]# docker run --rm -v `pwd`/errbot-root:/errbot-root -it bot
08:51:58 INFO     errbot.specific_plugin_ma storage search paths {'/usr/local/lib/python3.5/site-packages/errbot/storage'}
08:51:58 INFO     errbot.specific_plugin_ma Found those plugings available:
08:51:58 INFO     errbot.specific_plugin_ma         Memory  (/usr/local/lib/python3.5/site-packages/errbot/storage/memory.py)
08:51:58 INFO     errbot.specific_plugin_ma          Shelf  (/usr/local/lib/python3.5/site-packages/errbot/storage/shelf.py)
08:51:58 INFO     errbot.bootstrap          Found Storage plugin: 'Shelf'
Description: This is the storage plugin for the traditional shelf store for errbot.
08:51:58 INFO     errbot.specific_plugin_ma backends search paths {'/usr/local/lib/python3.5/site-packages/errbot/backends'}
08:51:58 INFO     errbot.specific_plugin_ma Found those plugings available:
08:51:58 INFO     errbot.specific_plugin_ma        Graphic  (/usr/local/lib/python3.5/site-packages/errbot/backends/graphic.py)
08:51:58 INFO     errbot.specific_plugin_ma        Hipchat  (/usr/local/lib/python3.5/site-packages/errbot/backends/hipchat.py)
08:51:58 INFO     errbot.specific_plugin_ma            IRC  (/usr/local/lib/python3.5/site-packages/errbot/backends/irc.py)
08:51:58 INFO     errbot.specific_plugin_ma           Null  (/usr/local/lib/python3.5/site-packages/errbot/backends/null.py)
08:51:58 INFO     errbot.specific_plugin_ma          Slack  (/usr/local/lib/python3.5/site-packages/errbot/backends/slack.py)
08:51:58 INFO     errbot.specific_plugin_ma       Telegram  (/usr/local/lib/python3.5/site-packages/errbot/backends/telegram_messenger.py)
08:51:58 INFO     errbot.specific_plugin_ma           Test  (/usr/local/lib/python3.5/site-packages/errbot/backends/test.py)
08:51:58 INFO     errbot.specific_plugin_ma           Text  (/usr/local/lib/python3.5/site-packages/errbot/backends/text.py)
08:51:58 INFO     errbot.specific_plugin_ma           XMPP  (/usr/local/lib/python3.5/site-packages/errbot/backends/xmpp.py)
08:51:58 INFO     errbot.bootstrap          Found Backend plugin: 'Slack'
                                                Description: This is the slack backend for Err.
08:52:01 INFO     errbot                    webhooks:  Flag to bind /echo to                           echo
08:52:01 INFO     errbot.backends.slack     Verifying authentication token
08:52:02 INFO     errbot.backends.slack     Connecting to Slack real-time-messaging API
08:52:03 INFO     errbot.backends.slack     Connected
08:52:03 INFO     errbot.core               Activate internal commands
08:52:03 INFO     errbot.plugin_manager     Activate bot plugins...
08:52:03 INFO     errbot.plugin_manager     Activate plugin: Aws
08:52:03 INFO     errbot.plugin_manager     Activating Aws with min_err_version = 5.2.0 and max_version = 5.2.0
08:52:03 INFO     errbot.core_plugins.wsvie Checking Aws for webhooks
08:52:03 INFO     errbot.plugin_manager     Activate plugin: Example
08:52:03 INFO     errbot.plugin_manager     Activating Example with min_err_version = 5.2.0 and max_version = 5.2.0
08:52:03 INFO     errbot.core_plugins.wsvie Checking Example for webhooks
08:52:03 INFO     errbot.plugin_manager     Activate plugin: ACLs
08:52:03 INFO     errbot.plugin_manager     Activating ACLs with min_err_version = 5.2.0 and max_version = 5.2.0
08:52:03 INFO     errbot.core_plugins.wsvie Checking ACLS for webhooks
08:52:03 INFO     errbot.plugin_manager     Activate plugin: Backup
08:52:03 INFO     errbot.plugin_manager     Activating Backup with min_err_version = 5.2.0 and max_version = 5.2.0
08:52:03 INFO     errbot.core_plugins.wsvie Checking Backup for webhooks
08:52:03 INFO     errbot.plugin_manager     Activate plugin: ChatRoom
08:52:03 INFO     errbot.plugin_manager     Activating ChatRoom with min_err_version = 5.2.0 and max_version = 5.2.0
08:52:03 INFO     errbot.core_plugins.wsvie Checking ChatRoom for webhooks
08:52:03 INFO     errbot.plugin_manager     Activate plugin: CommandNotFoundFilter
08:52:03 INFO     errbot.plugin_manager     Activating CommandNotFoundFilter with min_err_version = 5.2.0 and max_version = 5.2.0
08:52:03 INFO     errbot.core_plugins.wsvie Checking CommandNotFoundFilter for webhooks
08:52:03 INFO     errbot.plugin_manager     Activate plugin: Flows
08:52:03 INFO     errbot.plugin_manager     Activating Flows with min_err_version = 5.2.0 and max_version = 5.2.0
08:52:03 INFO     errbot.core_plugins.wsvie Checking Flows for webhooks
08:52:03 INFO     errbot.plugin_manager     Activate plugin: Health
08:52:03 INFO     errbot.plugin_manager     Activating Health with min_err_version = 5.2.0 and max_version = 5.2.0
08:52:03 INFO     errbot.core_plugins.wsvie Checking Health for webhooks
08:52:03 INFO     errbot.plugin_manager     Activate plugin: Help
08:52:03 INFO     errbot.plugin_manager     Activating Help with min_err_version = 5.2.0 and max_version = 5.2.0
08:52:03 INFO     errbot.core_plugins.wsvie Checking Help for webhooks
08:52:03 INFO     errbot.plugin_manager     Activate plugin: Plugins
08:52:03 INFO     errbot.plugin_manager     Activating Plugins with min_err_version = 5.2.0 and max_version = 5.2.0
08:52:03 INFO     errbot.core_plugins.wsvie Checking Plugins for webhooks
08:52:03 INFO     errbot.plugin_manager     Activate plugin: TextCmds
08:52:03 INFO     errbot.plugin_manager     Plugin TextCmds has no section [Python]. Assuming this plugin is running only under python 3.
08:52:03 INFO     errbot.plugin_manager     Activating TextCmds with min_err_version = 5.2.0 and max_version = 5.2.0
08:52:03 INFO     errbot.core_plugins.wsvie Checking TextModeCmds for webhooks
08:52:03 INFO     errbot.plugin_manager     Activate plugin: Utils
08:52:03 INFO     errbot.plugin_manager     Activating Utils with min_err_version = 5.2.0 and max_version = 5.2.0
08:52:03 INFO     errbot.core_plugins.wsvie Checking Utils for webhooks
08:52:03 INFO     errbot.plugin_manager     Activate plugin: VersionChecker
08:52:03 INFO     errbot.plugin_manager     Activating VersionChecker with min_err_version = 5.2.0 and max_version = 5.2.0
08:52:03 INFO     errbot.core_plugins.wsvie Checking VersionChecker for webhooks
08:52:03 INFO     errbot.plugin_manager     Activate plugin: Webserver
08:52:03 INFO     errbot.plugin_manager     Activating Webserver with min_err_version = 5.2.0 and max_version = 5.2.0
08:52:03 INFO     errbot.plugins.Webserver  Webserver is not configured. Forbid activation
08:52:03 INFO     errbot.core_plugins.wsvie Checking Webserver for webhooks
08:52:03 INFO     errbot.core_plugins.wsvie Webhook routing echo
08:52:03 INFO     errbot.core
08:52:03 INFO     errbot.core               Notifying connection to all the plugins...
08:52:03 INFO     errbot.plugins.ChatRoom   Callback_connect
08:52:03 INFO     errbot.core               Plugin activation done.

Slack で !tryme や !subnet search を入力すると、下図のように errbot が返信してくれます。