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

ステートマシンを実装してコマンド出力をパースする話

 ステートマシンを実装してコマンド出力をパースする話

Pycon 2020 Onlineのビザスク スポンサーブースで話した内容です

A9df8bdde94d0ee38835ba4a02c5853e?s=128

yokoc1322

August 29, 2020
Tweet

Other Decks in Programming

Transcript

  1. ステートマシンを実装して コマンド出力をパースする話 Pycon JP 2020 Online ビザスク スポンサーブースLT よこやま たかし

  2. Confidential 2 All rights reserved VisasQ Inc. 自己紹介 名前: 横山 貴志(よこやま たかし)

    前職: SIer ネットワークサービスのテスト自動化 Pythonでネットワーク機器や対象サービスを操作して あれやこれや 今: ビザスク アドバイザー開発チーム → 9月から検索チーム Elasticsearchと仲良くなろうと頑張り中
  3. コマンド出力のパースどうしてますか?

  4. Confidential 4 All rights reserved VisasQ Inc. 1. コマンド直接打たなくてansibleがよしなにやってくれるよ 2.

    Dockerfileにコマンドは書くけど詳細な結果は必要にならないかな 3. 今どきのコマンド大体JSONなりYAMLなり吐くでしょ? 4. 頑張ってコード書いてパースしてる
  5. パーサをフルスクラッチで書いているあなたへ TextFSMが便利だったので紹介

  6. Confidential 6 All rights reserved VisasQ Inc. 便利だったライブラリ TextFSM https://github.com/google/textfsm

    セミフォーマットテキストをパースするためのPythonモジュール Destination Gateway Dist/Metric Last Change ----------- ------- ----------- ----------- B EX 0.0.0.0/0 via 192.0.2.73 20/100 4w0d via 192.0.2.201 via 192.0.2.202 via 192.0.2.74 B IN 192.0.2.76/30 via 203.0.113.183 200/100 4w2d B IN 192.0.2.204/30 via 203.0.113.183 200/100 4w2d B IN 192.0.2.80/30 via 203.0.113.183 200/100 4w2d B IN 192.0.2.208/30 via 203.0.113.183 200/100 4w2d ↑こんな感じのテキストをpython上でlist/dictで扱えるように 「有限状態機械 (finite state machine, FSM)」を定義してパースする
  7. Confidential 7 All rights reserved VisasQ Inc. (有限)状態機械(ステートマシン)(オートマトンとも呼ばれる) とは? 有限個の状態と遷移と動作の組み合わせからなる数学的に抽象化さ

    れた「ふるまいのモデル」である。 wikipedia 有限オートマトン 2020/08/17 wikipedia 有限オートマトン 2020/08/17 (↑のステートマシンだと) - 0,1からなる数字列を1文字ずつ読む - 状態S1と状態S2を持つ - S1からスタート(初期状態) - S1で「受容(それまでの入力を受け入れる)」する(受容状態) - ↑のステートマシンは「偶数個の0がある数字列」を受容する - 例:(空)、1、1001、10101、1101111101111....
  8. Confidential 8 All rights reserved VisasQ Inc. どうやってTextFSMを使うか? pingの結果を例にとって説明

  9. Confidential 9 All rights reserved VisasQ Inc. 使用例:pingの結果をパースしてみる (Pythonのコード

  10. Confidential 10 All rights reserved VisasQ Inc. 使用例:pingの結果をパースしてみる (ステートマシンの定義 ←保存する値の定義部分

    ↓ステートマシン定義部分 ping.textfsm
  11. Confidential 11 All rights reserved VisasQ Inc. 使用例:保存する値の定義の説明 保存する値の名前 値とマッチする正規表現

    値のオプション、ListとかRequiredとかもろもろを設定できる
  12. Confidential 12 All rights reserved VisasQ Inc. 使用例:ステートマシン定義の説明 状態名 上で定義した値(マッチした値が一時的に保存される)

    赤文字列一行一行が遷移にあたる この遷移にマッチしたときの振る舞い
  13. Confidential 13 All rights reserved VisasQ Inc. 使用例:図 ※表示の都合で改行しているが、それぞれ一行一行が遷移

  14. Confidential 14 All rights reserved VisasQ Inc. 使用例:表示するとこんなかんじ distination, 8.8.8.8

    size, 56 seq, ['1', '2', '3', '4'] seq_size, ['64', '64', '64', '64'] seq_ttl, ['63', '63', '63', '63'] seq_time, ['12.5', '4.44', '11.4', '7.60'] seq_time_unit, ['ms', 'ms', 'ms', 'ms'] transmitted, 4 received, 4 loss, 0 time, 3006 time_unit, ms rtt_min, 4.444 rtt_avg, 8.994 rtt_max, 12.512 rtt_mdev, 3.199 statictics_rtt_unit, ms
  15. 「正規表現を羅列してるだけじゃん 何が便利なの?」

  16. Confidential 16 All rights reserved VisasQ Inc. 何が便利か? 特定のコマンドだけをパースするなら気合でパーサ書いても良さそう 複数のコマンドのパーサが必要

    (+ 複数人で作業)なら、 TextFSMを使うと実装が揃って保守が楽   フレームワークと似た話 どこかのとあるプロジェクトであった話 Aさん「このコマンドは順当に頭から読んでパースしよう」 Bさん「先に各要素の1行目を見つけてからパースしよっと」 Cさん「各要素が何で終わるかわかんないや、     各要素の1行目はわかりやすいから最後尾から読むか」 Dさん「独自のパーサ実装したよ!    ここに正規表現etcを羅列するだけでパースできるよ!」 (劣化TextFSM
  17. Confidential 17 All rights reserved VisasQ Inc. TextFSMが苦手なこと 複雑なデータ構造は表現できない 例えば辞書のネストとかはできない

    複雑なコマンド出力は諦めてコード書く必要あり
  18. Confidential 18 All rights reserved VisasQ Inc. おわり コマンド結果をPythonでパースしなくちゃいけなくなったときは 検討してみる価値あり

    他の人が書いたステートマシンの定義とかも使えるかも https://github.com/networktocode/ntc-templates (これはネットワーク機器関係のリポジトリだけど・・・
  19. 19 非表示おまけ

  20. Confidential 20 All rights reserved VisasQ Inc. 実はpingのやつ状態1個でも行ける

  21. Confidential 21 All rights reserved VisasQ Inc. 「シーケンスの部分、どんなエラーが帰ってくるかわからないから 一行まるごと取って、中身はPython側で処理させるか」 とかだと状態を分けないとダメ、誤った行が認識される

    言い換えると 「複数の行にマッチする可能性がある遷移は状態を分けるべき」