Upgrade to Pro — share decks privately, control downloads, hide ads and more …

明日からできる、st2のActionのつくりかた

 明日からできる、st2のActionのつくりかた

TechNight Shiodome #8 で発表したやつ。

Wataru Manji

May 29, 2018
Tweet

More Decks by Wataru Manji

Other Decks in Programming

Transcript

  1. 明日からできる、st2のActionの作り方
    Wataru Manji

    View Slide

  2. 自己紹介
    ● 名前: 萬治 渉 (マンジ ワタル)
    ● 所属:
    ○ NTTテクノクロス株式会社 IoTイノベーション事業部
    ○ 日本StackStormユーザ会
    ● 仕事:
    ○ OpenStack基盤の設計、運用、保守
    ○ StackStorm関係色々
    ○ その他AnsibleとかNWとか色々
    ● 連絡先:
    ● Twitter: @_manji0
    ● Mail: [email protected]

    View Slide

  3. みなさん、Action書いてますか???
    (・ω・)ノ 1. プロダクションでバリバリ書いてる
    2. 手習い程度に書いてる
    3. 公開されてるものを使ってるだけで、書いてない
    4. Action? ナニソレ?
    Todays
    Target

    View Slide

  4. Action作成のノウハウはいっぱいある
    ● Action入出力を定義する方法
    ● ActionのPythonコードの記述方法
    ● etc
    ○ Workflow内で扱いやすいActionの入出力とは
    ○ Actionの適切な粒度とは
    ○ Actionコードの形式別の記述方法
    ○ 開発中Actionのテスト方法
    ○ ...
    おおまかな勉強順序

    View Slide

  5. その中で今回話すこと
    ● Action入出力を定義する方法
    ○ 入力: ActionのMetadataについて
    ○ 出力: Actionの出力形式、および構造化データの扱いについて
    ● ActionのPythonコードの記述方法
    ○ 基本的な形式と要素の解説
    ● etcは話す時間が無いのでまたいつか

    View Slide

  6. 今回のゴール
    ● Actionの入出力を定義する方法について理解している
    ● Python, BashでActionコードを記述する方法を知っている
    = Actionの「箱」について理解しており、
    明日から「自分の作りたいAction」を作り始められること

    View Slide

  7. ※全ての前提知識について話す時間は無い
    ピンからキリまで20分で話すのは不可能...
    なので、今回はAction, Workflow, Ruleなどの分類については話しません。
    必要に応じて以下の情報を参考にすることで、フォローできるかと思います。
    (どっちも作成に関わってるので、質問にも答えられます)
    ● st2の概要&特徴
    ○ https://speakerdeck.com/ntttechnocross/ntt-techconference-number-2-stackstorm
    ● workflowやruleの書き方
    ○ https://github.com/internetweek2017-st2/handson_documents

    View Slide

  8. 前提: チョット分かるActionの構造

    View Slide

  9. チョット分かるActionの構造
    metadata
    ・Actionコードの形式、path
    ・入力の定義
    Actionコード
    ・実行内容の記述
    ・return値の定義
    st2
    ・metadataに書かれた
    情報の管理
    ・実行リクエストの解釈
    metadataで指定された
    Action-Codeを
    指定された入力で起動
    実行結果をst2にreturn
    事前にst2へActionの
    情報を渡す

    View Slide

  10. Actionの入出力について

    View Slide

  11. それぞれ、どこで定義しているの?
    ● 入力: metadata内
    ○ metadata内での定義記述箇所
    ○ 指定できるオプション
    ● 出力: Actionコード内
    ○ st2の出力定義
    ○ Actionコード内での出力方法
    ○ 構造化データの取り扱い
    順番に解説。

    View Slide

  12. 入力の定義: metadata.parameters
    ● metadata: ActionやWorkflowの名前、コード位置や入力を定義するファイル
    ● parametersセクションで入力を定義する
    ○ 入力の名前
    ○ 入力値の型
    ○ 入力値の初期値
    ○ 入力の必須/任意の選択
    ○ etc...
    ● metadataで定義していない入力は基本的に使うことができない
    (やり方はあるが、今回は解説しない)

    View Slide

  13. metadata.parametersの記述方法(基本)
    # 前略
    parameters:
    hostname:
    type: string
    required: true
    hoge:
    type: string
    ...
    ● YAMLの辞書形式で書いていく
    ● ここでは、”hostname”と”hoge”の2つの
    入力を定義している
    ● “type”の指定は必須!
    ● “required”はオプション。
    trueは「起動時の入力を必須とする」
    という意味。
    required以外のオプションについては後述。

    View Slide

  14. 個々のparameterに指定できるオプションたち
    ● required
    ○ Action起動時にその入力値が指定されていない場合、エラーを出すことができる
    ○ デフォルトはFalse
    ● description
    ○ その入力の役割、意味などを自由に記述することができる。あった方が親切
    ● default
    ○ 入力の初期値を設定できる
    ○ requiredと組み合わせることもできるが、意味が無くなる
    ● enum
    ○ 入力値を選択式にする
    ● immutable
    ○ 入力値をユーザから入力できないようにする
    ○ defaultとセットで使うのが基本
    ● position
    ○ 入力の順序を定義する

    View Slide

  15. 入力定義のポイント
    ● Actionの入力はmetadataのparametersで定義する
    ● 入力は名前付き引数として定義される
    ● 入力値の形式や初期値などを定義できるので、
    「metadata内で定義している部分は」Action内でのvalidateが不要

    View Slide

  16. bash(local-shell-script)でActionを作る場合
    Actionコード内で引数(入力)を名前で引くことができない。
    なので、以下のようにActionを実装する必要がある。
    ● metadata.parametersの各要素にpositionを連続した自然数で設定する
    ● Actionコードとなるスクリプト内で、$で参照する

    View Slide

  17. 出力I: st2の出力形式
    st2は、Actionの出力を以下のように分類している。
    共通 shell-script系Action Python Action
    stdout result_code exit_code
    stderr failed result
    (status) succeeded
    赤字が実質的な差分

    View Slide

  18. 出力I:例(shell-script系)
    core.localでecho helloしてみる
    ! failed is succeeded

    View Slide

  19. 出力I: 例(Python)
    同じようなPythonのActionを実行してみる
    resultの役割とは?
    →次項

    View Slide

  20. 出力II: 構造化データの取り扱い
    ● Pythonで実装する場合
    ○ result以下に構造化データを出力することができる
    ○ dictをそのまま渡せばOK
    ○ ネストしててもリストが混ざってても OK
    ○ 型も保持される
    ● それ以外で実装する場合
    ○ stdoutにJSON or YAMLのStringで出力する
    ○ 別途Jinja Filterで構造化データに変換することで、後続 Actionなどで利用可能

    View Slide

  21. 出力I&II: Pythonでの出力方法
    def run(self, **kwargs):
    sys.stdout.write(“ok”) ← stdout
    sys.stderr.write(“error”) ← stderr
    return (True, {“fuga”: “111”, “list”: [1, 2, 3]})
    ↑return (status, result)
    True → succeeded
    False → failed
    status: succeeded
    exit_code: 0
    result:
    fuga: “111”
    list:
    - 1
    - 2
    - 3
    stdout: “ok”
    stderr: “error”

    View Slide

  22. 出力定義のポイント
    ● 基本的にテキストで出力する
    ● PythonでActionを作ることで、resultという表現力の高い出力形式を使える
    ○ hash, listを用いた構造化データの記述が可能
    ○ 出力値の型の保持が可能

    View Slide

  23. PythonでのActionコード記述方法

    View Slide

  24. Pythonでの書き方
    from st2common.runners.base_action import Action
    class TestAction(Action):
    def run(self, arg1, arg2, **kwargs):
    # なんらかの処理
    return (True, result)

    View Slide

  25. Pythonでの書き方
    from st2common.runners.base_action import Action
    class TestAction(Action):
    def run(self, arg1, arg2, **kwargs):
    # なんらかの処理
    return (True, result)
    特別な理由が無い限り、とりあえず書く

    View Slide

  26. Pythonでの書き方
    from st2common.runners.base_action import Action
    class TestAction(Action):
    def run(self, arg1, arg2, **kwargs):
    # なんらかの処理
    return (True, result)
    名前は自由だが、Action名と対応が
    取れるのが望ましい

    View Slide

  27. Pythonでの書き方
    from st2common.runners.base_action import Action
    class TestAction(Action):
    def run(self, arg1, arg2, **kwargs):
    # なんらかの処理
    return (True, result)
    st2は自動的にrunメソッドを実行するので、必須。
    (同クラス内に、runから呼ばれるメソッドを独自に書いても OK)

    View Slide

  28. Pythonでの書き方
    from st2common.runners.base_action import Action
    class TestAction(Action):
    def run(self, arg1, arg2, **kwargs):
    # なんらかの処理
    return (True, result)
    引数(入力)はmetadata.parametersで設定したものが名前付き
    で渡されるので、列挙してもいいし dictで拾ってもよい

    View Slide

  29. Pythonでの書き方
    from st2common.runners.base_action import Action
    class TestAction(Action):
    def run(self, arg1, arg2, **kwargs):
    # なんらかの処理
    return (True, result)
    ● 何もreturnしない場合
    ○ status = succeededになる
    ○ resultは空になる(None)
    ● Trueだけ返した場合: 同上
    ● タプルを返した場合
    ○ 1つ目のBoolがActionの実行成否になる
    ○ 2つ目のデータがそのまま resultに入る

    View Slide

  30. 応用: exit_codeを定義する
    from st2common.runners.base_action import Action
    class TestAction(Action):
    def run(self, arg1, arg2, **kwargs):
    # なんらかの処理
    if hoge is None:
    sys.stderr.write(‘hoge err’)
    exit(2)
    exit(exit_code)で定義することが可能
    status: failed
    ---
    exit_code: 2
    result: None
    stdout: “”
    stderr: “hoge err”
    exit_code != 0の場合、
    Actionは失敗する

    View Slide

  31. returnとexitの使い分け
    ● 正常系、準正常系を通ったときにはreturnで返すべき
    ○ returnでないと、構造化データを返せない
    ○ statusは可変だが、exit_codeは0に固定される
    ● exitを使うのは特殊ケースのみにすべき
    ○ stdout, stderr, exit_codeしか返せない = テキストと数値だけしか返せない
    → Actionを異常終了させるときに使うと綺麗だと思う (stderr + errno)

    View Slide

  32. まとめ

    View Slide

  33. やったね!Actionが書けるよ!
    ● metadata内のparametersを設定できるようになったので、
    ○ 入力を定義することができるようになった!
    ○ 簡単な入力規則を定義することができるようになった!
    ● Python形式のAction出力の定義方法と全体の書き方が分かったので、
    ○ ナニカを実行するActionを書けるようになった!
    ○ 構造化データを含む自由度の高いActionを作れるようになった!

    View Slide

  34. 明日からActionを作り始める、その前に
    公式ドキュメントの以下の節は読んでおこう!
    ● https://docs.stackstorm.com/actions.html#action-metadata
    ● https://docs.stackstorm.com/actions.html#writing-custom-python-actions
    概要は説明したので、理解も補足もスムーズにいくはず!

    View Slide