1. OpenStack Osloを使おう
~ cliff編 ~
July Tech Festa 2016
Hideki Saito
Japan OpenStack User Group
Internet Initiative Japan Inc.
JAPAN OPENSTACK USER GROUP 1
JULY TECH FESTA 2016
2. 自己紹介
氏名: 齊藤 秀喜 (さいとう ひでき)
勤務先: 株式会社インターネットイニシアティブ
所属: 日本OpenStackユーザ会 ボードメンバー
趣味: OpenStack / Ansible / Solaris
TwitterID: @saito_hideki
IRC: saitou
JAPAN OPENSTACK USER GROUP 2
JULY TECH FESTA 2016
5. 目次
1. DevOpsとInfrastructure as Code
2. 自分のためにコードを書こう
3. まとめ
4. おまけ - ちょっとエモーショナル
JAPAN OPENSTACK USER GROUP 5
JULY TECH FESTA 2016
6. 01
JAPAN OPENSTACK USER GROUP 6
DevOpsとInfrastructure as
Code
JULY TECH FESTA 2016
Infrastructure as Codeって何だっけ?
7. Infrastructure as Code
JAPAN OPENSTACK USER GROUP 7
JULY TECH FESTA 2016
[出典] https://en.wikipedia.org/wiki/DevOps<Infrastructure as Codeの真価>
Devの現場で利用されている、QAのような仕組みをOpsの
仕事にも適用できるのが最大のメリット。
• 手順書のコード化 <= 今日の主題
• コードのリビジョンの管理
• チケットシステムによる課題管理
• コードレビュー
• テスト
• デプロイシステム
• インフラの構成管理
14. Slack CLIを書く
事前準備
1.Slackにチームを作成する
➡ 例: coffee4u.slack.com
2.チームにチャネルを追加する
➡ 例: #notice
3.プログラムで利用するBot用のTOKENを取得する
4.python-slackclientをインストールする
5.クライアントコードを書く!
JAPAN OPENSTACK USER GROUP 14
JULY TECH FESTA 2016
15. Slack CLIを書く
01: import sys
02: from slackclient import SlackClient
03:
04: TOKEN = “自主規制”
05: CHANNEL = "#notice"
06: USER = "misuzu_aoyama"
07: ICON_URL = "https://pbs.twimg.com/profile_images/354648329/600-600_B.jpg"
08:
09: def get_client(token):
10: return SlackClient(token)
11: def check_client(client):
12: result = client.api_call("api.test")
13: return result["ok"]
14: def send_message(client, message):
15: result = client.api_call("chat.postMessage", channel=CHANNEL, username=USER, text=message, icon_url=ICON_URL)
16: return result[“ok"]
17: def main():
18: sc = get_client(TOKEN)
19: if not check_client(sc):
20: sys.stderr.write("Error: {0:s} Invalid connection.n".format(__file__))
21: for message in sys.argv[1:]:
22: print('Send message: "{0:s}" ...'.format(message))
23: result = send_message(sc, message)
24: if result:
25: print('Succeeded')
26: else:
27: print('Failed')
28: if __name__ == "__main__":
29: main()
JAPAN OPENSTACK USER GROUP 15
JULY TECH FESTA 2016
slackのチャネル(#noticeにメッセージを投稿する
16. Slack CLIを書く - デモ
実際に動かしてみる
JAPAN OPENSTACK USER GROUP 16
JULY TECH FESTA 2016
17. 次のステップとして
JAPAN OPENSTACK USER GROUP 17
JULY TECH FESTA 2016
機能をライブラリ
としてまとめて…
単機能コマンド1
チャネルリスト取得
単機能コマンド2
メンバーリスト取得
単機能コマンド3
メッセージ取得
単機能コマンド4
メッセージ送信
CLI化する
18. – Oslo Mission Statement –
“To produce a set of python libraries containing code shared by
OpenStack projects. The APIs provided by these libraries should be
high quality, stable, consistent, documented and generally applicable.”
JAPAN OPENSTACK USER GROUP
JULY TECH FESTA 2016
もうすこしブラッシュアップ!
18
OsloのCLIフレームワーク”cliff”
を利用してみよう
22. CLIを書く - モジュールマップ
pbrはsetuptoolsを少しだけ簡単に使うためのライブラリ。
JAPAN OPENSTACK USER GROUP 22
JULY TECH FESTA 2016
import setuptools
setuptools.setup(
setup_requires=['pbr>=1.8'], pbr=True)
[metadata]
name = sc
summary = Command-Line for Slack
author = Hideki Saito
author-email = saito@fgrep.org
[files]
packages =
sc
[entry_points]
console_scripts =
sc = sc.main:main
sc.cli =
channel_list = sc.list:ChannelList
channel_history = sc.list:ChannelHistory
member_list = sc.list:MemberList
member_show = sc.show:MemberShow
message_send = sc.command:MessagePost
<setup.py> <setup.cfg>
作成するパッケージ名:”sc”
scコマンドのmain()メソッド
サブコマンドとクラスのマップ: ”sc.cli”
定義
$ sc help
<…>
Commands:
channel history Show a list of channel histroy.
channel list Show a list of channels in the slack team.
complete print bash completion command
help print detailed help for another command
member list Show a list of members in the slack team.
member show Show detail information of user
message send Sending message to the specified channel.
23. CLIを書く - cliffの恩恵
JAPAN OPENSTACK USER GROUP 23
JULY TECH FESTA 2016
今回、scコマンドに実装した機能は以下の通り。
1. チャネルの一覧取得 => "channel list"
2. チームメンバーの一覧取得 => "member list"
3. チームメンバーの情報取得 => "member show"
4. チャネルのメッセージ取得 => "channel history"
5. チャネルへのメッセージ送信 => "message send"
<cliffの恩恵>
help、history、出力フォーマットの指定などの
CLIに必要な共通機能は、利用者が独自実装しなくても
cliffが提供してくれる!!
24. Slack CLI - デモ
scコマンドを動かしてみます
JAPAN OPENSTACK USER GROUP 24
JULY TECH FESTA 2016
25. CLIを書く - サンプルコード
import sys, pbr.version
from cliff.app import App
from cliff.commandmanager import CommandManager
version_info = pbr.version.VersionInfo('sc')
class SlackClientCommand(App):
def __init__(self):
super(SlackClientCommand, self).__init__(
description='Slack Command-line Client', version=version_info,
command_manager=CommandManager('sc.cli'), deferred_help=True)
def main(argv=sys.argv[1:]):
return SlackClientCommand().run(argv)
JAPAN OPENSTACK USER GROUP 25
JULY TECH FESTA 2016
<main.py>
"sc"コマンド実行時に呼び出されるcliffのapp.Appを継承したクラスを定義
CommandManagerにsetup.cfgで定義済の"sc.cli"を指定
cliffのapp.Appで定義されているrun()を実行
26. CLIを書く - サンプルコード
import datetime, os, sc.libsc
from cliff.lister import Lister
def _append_global_args(parser):
parser.add_argument('--token', default=os.environ.get('SC_TOKEN'),
help='Defaults to env[SC_TOKEN] or None.')
return parser
class ChannelList(Lister):
"Show a list of channels in the slack team."
def get_parser(self, prog_name):
parser = super(ChannelList, self).get_parser(prog_name)
parser = _append_global_args(parser)
return parser
def take_action(self, parsed_args):
client = sc.libsc.Client(parsed_args.token)
channels = client.list_channels()
return (('Name', 'Id'),
((name, channels[name]) for name in channels)
)
<…>
JAPAN OPENSTACK USER GROUP 26
JULY TECH FESTA 2016
<list.py>
"token"オプションをコマンドラインに追加する
ために get_parser() をオーバーライド
サブコマンドが指定された際に実行されるメソッド
"channel list"サブコマンド実行時に呼び出されるクラスを定義
一覧を取得する機能なので cliff.lister.Lister を継承する。
戻り値として、((キーのタプル), (キーに対応する値のタプル)) を返す。
27. CLIを書く - サンプルコード
import os, sc.libsc
from cliff.show import ShowOne
def _append_global_args(parser):
parser.add_argument('--token', default=os.environ.get('SC_TOKEN'),
help='Defaults to env[SC_TOKEN] or None.')
return parser
class MemberShow(ShowOne):
"Show detail information of user"
def get_parser(self, prog_name):
parser = super(MemberShow, self).get_parser(prog_name)
parser.add_argument('name', nargs='?', default='.')
parser = _append_global_args(parser)
return parser
def take_action(self, parsed_args):
client = sc.libsc.Client(parsed_args.token)
result = client.show_member(parsed_args.name)
columns = ('Id', 'Name', 'Email', 'Skype', 'Phone', 'RealName', 'TimeZone', 'Bot')
data = (result['id'], result['name'], result['email'], result['skype'],
result['phone'], result['real_name'], result['tz'], result['is_bot'])
return (columns, data)
JAPAN OPENSTACK USER GROUP 27
JULY TECH FESTA 2016
<show.py>
"member show"サブコマンド実行時に呼び出されるクラスを定義
詳細情報を取得する機能なので cliff.show.ShowOne を継承する。
戻り値の形式は、一覧を取得する場合と同様
sc member list <name> のように
オプションなしの引数を取得する
28. CLIを書く - サンプルコード
import os, sc.libsc
from cliff.command import Command
class MessagePost(Command):
"Sending message to the specified channel."
def get_parser(self, prog_name):
parser = super(MessagePost, self).get_parser(prog_name)
parser.add_argument('--token', default=os.environ.get('SC_TOKEN'),
help='Defaults to env[SC_TOKEN] or None.')
parser.add_argument('--channel', default='general', help='Defaults to "general"')
parser.add_argument('--user', default='None', help='Defaults to None')
parser.add_argument('--icon_url', default=os.environ.get('SC_ICON_URL'),
help='Defaults to env[SC_ICON_URL] or None.')
parser.add_argument('message', nargs='?', default='')
return parser
def take_action(self, parsed_args):
client = sc.libsc.Client(parsed_args.token)
result = client.send_message(username=parsed_args.user, channel=parsed_args.channel,
message=parsed_args.message, icon_url=parsed_args.icon_url)
print('Send message: "{0:s}" to "{1} channel"'.format(parsed_args.message, parsed_args.channel))
if result:
print('Succeeded')
else:
print('Failed')
JAPAN OPENSTACK USER GROUP 28
JULY TECH FESTA 2016
<command.py>
"message send"サブコマンド実行時に呼び出されるクラスを定義
命令を実行する機能は cliff.command.Command を継承する。
35. You can do it if you try:)
Thank you!
JAPAN OPENSTACK USER GROUP 35
JULY TECH FESTA 2016
36. 参考にした情報
• OpenStack
- https://wiki.openstack.org/wiki/Main_Page
• Oslo - OpenStack
- https://wiki.openstack.org/wiki/Oslo
• Contribute to OpenStack
- https://wiki.openstack.org/wiki/How_To_Contribute
• python-slackclient
- http://python-slackclient.readthedocs.io/en/latest/index.html
• Slack - Creating and regenerating API tokens
- https://api.slack.com/bot-users
JAPAN OPENSTACK USER GROUP 36
JULY TECH FESTA 2016