Upload
hideki-saito
View
1.212
Download
4
Embed Size (px)
Citation preview
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
自己紹介氏名: 齊藤 秀喜 (さいとう ひでき)
勤務先: 株式会社インターネットイニシアティブ 所属: 日本OpenStackユーザ会 ボードメンバー
趣味: OpenStack / Ansible / Solaris TwitterID: @saito_hideki IRC: saitou
JAPAN OPENSTACK USER GROUP 2
JULY TECH FESTA 2016
00
JAPAN OPENSTACK USER GROUP 3
はじめに
JULY TECH FESTA 2016
みなさんに伝えたいこと
はじめに今日、みなさんに伝えたいこと(2つ)
1.効率的にCLIを開発する手法の紹介 メインロジックに注力するために、OpenStackの成果を利用しよう!
2.OSSに対する貢献 少しだけ肩の力を抜いてやってみませんか?
JAPAN OPENSTACK USER GROUP 4
JULY TECH FESTA 2016
目次1. DevOpsとInfrastructure as Code 2. 自分のためにコードを書こう 3. まとめ 4. おまけ - ちょっとエモーショナル
JAPAN OPENSTACK USER GROUP 5
JULY TECH FESTA 2016
01
JAPAN OPENSTACK USER GROUP 6
DevOpsとInfrastructure as Code
JULY TECH FESTA 2016
Infrastructure as Codeって何だっけ?
Infrastructure as Code
JAPAN OPENSTACK USER GROUP 7
JULY TECH FESTA 2016
[出典] https://en.wikipedia.org/wiki/DevOps<Infrastructure as Codeの真価>
Devの現場で利用されている、QAのような仕組みをOpsの仕事にも適用できるのが最大のメリット。
• 手順書のコード化 <= 今日の主題 • コードのリビジョンの管理 • チケットシステムによる課題管理 • コードレビュー • テスト • デプロイシステム • インフラの構成管理
コード化により得られる恩恵
JAPAN OPENSTACK USER GROUP 8
JULY TECH FESTA 2016
テスト&激怒 レビューデプロイ
リビジョン管理 課題管理
真の目的に集中したいDevOpsが定着した現在、われわれインフラエンジニアも、作業を自動化するために、手順書ではなくコードを書くのが日常的な仕事の1つとなっています。
しかしながら、日常のオペレーションをコード化しようとするとき、ソフトウェア開発を生業としていない我々が、ゼロからコードを書くのは、かなりの苦行です。
JAPAN OPENSTACK USER GROUP 9
JULY TECH FESTA 2016
OpenStackのコンポーネントが利用している ライブラリが使えないかな?
02
JAPAN OPENSTACK USER GROUP 10
自分のためにコードを 書こう
JULY TECH FESTA 2016
実際にCLIベースのツールを書いてみましょう
OPS♡CLIですよね? • インフラエンジニアが開発するツールは、CLIベースとなる場合
が多い(当社比) => コマンドライン中心の作業手順をコード化
○
手順書からソフトウェアへ
JAPAN OPENSTACK USER GROUP 11
JULY TECH FESTA 2016
WebUI CLI
△
こんな素敵なCLIを作りたい
JAPAN OPENSTACK USER GROUP 12
JULY TECH FESTA 2016
普通に書いてみるSlackクライアントを例に、Osloライブラリ群の利用方法を紹介します。
JAPAN OPENSTACK USER GROUP 13
JULY TECH FESTA 2016
メッセージを投稿Slack CLI
I♡CLI
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
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にメッセージを投稿する
Slack CLIを書く - デモ
実際に動かしてみる
JAPAN OPENSTACK USER GROUP 16
JULY TECH FESTA 2016
次のステップとして
JAPAN OPENSTACK USER GROUP 17
JULY TECH FESTA 2016
機能をライブラリ としてまとめて…
単機能コマンド1 チャネルリスト取得
単機能コマンド2 メンバーリスト取得
単機能コマンド3 メッセージ取得
単機能コマンド4 メッセージ送信
CLI化する
– 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” を利用してみよう
Osloが提供するライブラリ群
JAPAN OPENSTACK USER GROUP 19
JULY TECH FESTA 2016
# Name1 automaton2 cliff (☆)3 debtcollector4 futurist5 openstack-cookiecutter6 osprofiler7 oslo.cache8 oslo.concurrency9 oslo.context
10 oslo.config 11 oslo-cookiecutter12 oslo.db13 oslo.i18n14 oslo.log 15 oslo.messaging16 oslo.middleware17 oslo.policy18 oslo.privsep
# Name19 oslo.reports20 oslo.rootwrap21 oslo.serialization22 oslo.service23 oslosphinx24 oslotest25 oslo.utils26 oslo.versionedobjects27 oslo.version28 oslo.vmware29 pylockfile 30 hacking31 pbr (☆)32 pyCADF33 stevedore34 taskflow35 tooz- -
OpenStackの各コンポーネントが、独自に実装していた基本的な機能を整理して切り出した。
https://wiki.openstack.org/wiki/Oslo
(1)
(2)
CLIに必要な機能を提供するフレームワーク(cliff)とsetuptools用パッケージマネージャ(pbr)を利用してCLIを書いてみる。
$ git clone https://github.com/saito-hideki/slackcli.git $ cd slackli && python setup.py build && python setup.py install
slackcli ├── sc │ ├── __init__.py │ ├── libsc.py │ ├── main.py │ ├── command.py │ ├── list.py │ └── show.py ├── setup.cfg └── setup.py
CLIを書いてパッケージング
JAPAN OPENSTACK USER GROUP 20
JULY TECH FESTA 2016
<cliffがフレームワークを提供>
CLIを書く - cliffを活用コマンドラインベースのツールに必要な機能、実は3つしかない。 「1.機能実行」・「2.一覧取得」・「3.詳細情報取得」
JAPAN OPENSTACK USER GROUP 21
JULY TECH FESTA 2016
機能を実行
なにかの一覧情報を取得
なにかの詳細情報を取得
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 = [email protected]
[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.
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が提供してくれる!!
Slack CLI - デモ
scコマンドを動かしてみます
JAPAN OPENSTACK USER GROUP 24
JULY TECH FESTA 2016
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()を実行
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 を継承する。
戻り値として、((キーのタプル), (キーに対応する値のタプル)) を返す。
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> のように オプションなしの引数を取得する
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 を継承する。
実装の過程 - デモ
実際に実装の過程を みていきましょう
JAPAN OPENSTACK USER GROUP 29
JULY TECH FESTA 2016
03
JAPAN OPENSTACK USER GROUP 30
まとめ
JULY TECH FESTA 2016
本セッションのまとめ
まとめ本セッションでは、OpenStackのように巨大なOSSプロダクトの成果を、インハウスな開発にも応用できる例を紹介しました。
• cliffはCLI開発用のフレームワークです • CLIで提供したい本来の機能の開発に集中できます • pbrは独自Pythonコードのパッケージ化を支援してくれます • cliffとpbrはOsloプロジェクトがメンテナンスしています • OpenStack OsloはIaaS管理基盤向けのライブラリ群です • Osloは、さまざまな機能をライブラリとして提供しています
JAPAN OPENSTACK USER GROUP 31
JULY TECH FESTA 2016
04
JAPAN OPENSTACK USER GROUP 32
ちょっとエモーショナル
JULY TECH FESTA 2016
今年は何かいいことしませんか? 社会貢献ってやつですよ:-)
ちょっとエモーショナル
JAPAN OPENSTACK USER GROUP 33
JULY TECH FESTA 2016
我々が得ている OSSからの恩恵
恩返しをしませんか?一方的に利用するだけではなく、OSSに貢献してみませんか? July Tech Festaに参加している皆さんなら、すぐにでもできることが何かあります!
• OSSのユーザグループに参加してノウハウをシェア(自慢もできて満足) • 勉強会を企画・運営する • カンファレンスのボランティアとして協力する • OSSプロダクトのドキュメント翻訳プロジェクトに参加する • バグレポートを出す • コードを書く • コードをレビューする • あなたが大富豪なら開発資金を寄付する
JAPAN OPENSTACK USER GROUP 34
JULY TECH FESTA 2016
You can do it if you try:) Thank you!
JAPAN OPENSTACK USER GROUP 35
JULY TECH FESTA 2016
参考にした情報• 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