PyEZとJSNAPyを使ってみた。第一部: 概要編

NetOpsCoding AdventCalendar2016の1日目の記事です。まだ空きがありますので、記事書けそうな方がいらっしゃれば是非ご参加ください！
[NetOpsCoding Advent Calendar 2016](http://qiita.com/advent-calendar/2016/netopscoding)

別に難しいことでなくても構いません。パッションあふれるエモーショナルな記事でも構いません。地味で小さいTipsでも構いません。(むしろ小さいTipsはありがたいです)。
もしネットワーク運用で悶々としている方がいらっしゃれば、ぜひきっかけの一つとして自動化の一歩目を踏み出していただけると、NetOpsCodingの中の人としてとてもうれしく思います。


# 概要

Juniperさんにご招待いただいて、「Juniper Cloud Builder Community 2016」というイベントで12/1に発表させていただきました。

発表内容としては、Juniperがオープンソフトウェアとして公開されている[PyEZ](https://github.com/Juniper/py-junos-eznc)と[JSNAPy](https://github.com/juniper/jsnapy)というツールを使ってみて、ISPの実際のネットワーク運用現場で使えそうか検証する、というものです。


発表に使った資料はこちらです。
[JSNAPyとPyEZで作る次世代ネットワークオペレーションの可能性](http://www.slideshare.net/taijitsuchiya5/jsnapypyez)

発表では時間が25分ということもあり、ツールやサンプルコードの詳細部分がほとんど紹介できなかったので、このブログで詳しい部分を紹介させていただきます。

先に結論を言ってしまうと、PyEZ、JSNAPyはルータ設定作業を自動化するためのソフトウェアであり、とても強力なツールです。手動作業とほぼ同様の手順をソフトウェアによって置き換えることができます。

サンプルやノウハウを書き出してみるとあまりに分量が多くなりすぎてしまったので、以下の4つのパートに分けてブログを書いています。

- [PyEZとJSNAPyを使ってみた。第一部: 概要編](http://qiita.com/taijijiji/items/065eef08f7b673cb7bb6) (イマココ)
- [PyEZとJSNAPyを使ってみた。第二部: PyEZ使ってみた編](http://qiita.com/taijijiji/items/626cef18757d638251cf)
- [PyEZとJSNAPyを使ってみた。第三部: JSNAPy使ってみた編](http://qiita.com/taijijiji/items/b6e3da3d3aeb351ff7ff)
- [PyEZとJSNAPyを使ってみた。第四部: PyEZとJSNAPyでISP設定作業を自動化する編](http://qiita.com/taijijiji/items/983189f9bdebaa53e499)

最終的に、以下のようなデモプログラムを作りました。画面右が対象装置のFirefly(右上firefly1が設定対象)、画面左が自動化ツールです。「第四部: PyEZとJSNAPyでISP設定作業を自動化する編」で紹介します。

![demo_v4.gif](https://qiita-image-store.s3.amazonaws.com/0/45596/c29b2bca-e4e0-aab9-58c7-f2e382ceea2f.gif)

## PyEZ 概要
PyEZは、JUNOSルータを設定変更するためのPythonライブラリです。コンフィグ読み込みやcommitだけでなく、手動でルータ設定する手順と全く同じ機能が用意されています。

- commit
- rollback
- load merge
 - Activeコンフィグを残した上で、candidateコンフィグを読み込み(未コミット)
- load overload
 - Activeコンフィグを消去した上で、candidateコンフィグを読み込み(未コミット)
- commit check
 - candidateコンフィグがcommit可能かチェック
- diff (show | compare)
 - Activeコンフィグとcandidateコンフィグの差分を確認。 


ルータ設定を自動化するに際に「手動設定の手順と全く同じ手順で、自動設定したい」といったニーズは多いので、「デグレードすることなく手動設定と全く同じことができる」ということは非常にありがたいです。(利用可能機能や設定方法に制約がある自動化ツールは案外多いです。)

## JSNAPy 概要
JSNAPyは、JUNOSルータの状態をスナップショットとして取得・管理し、事前に定義した条件とマッチするかを判定するツールです。簡単にいうと、JSNAPyを使うことでテストツールを楽に実装することができます。「インタフェース xe-0/0/0がupである場合は"Passed(合格)"を返す」「状態1に対して、状態2の経路情報が想定以上に増えてしまった場合は"Failed(不合格)"を返す」といったことができます。

「テストが書ける」ということは、ルータ設定を自動化する上に非常に強力です。ルータ設定作業において、「設定後の状態が正常に動作しているか」ということを確認することが重要なのは言うまでもありません。ルータはサービス影響範囲が大きいこともあり「設定に失敗してネットワーク消えちゃった」なんてことになれば目も当てられません。

しかし、この正常性確認工程を自動化することは、実はとてもとても骨が折れる作業です。「ルータCLIで投入する全てのルータコマンドに対して、ルータが返しうる出力結果の全パターンを定義して、正規表現でターゲットとなる文字列を抽出し、事前に定義した条件とマッチするか判定する」、言ってしまえばそれだけなのですが、「エラー時に出力されうるパターン数が膨大で、定義しきれない」「機種/OS versionによって出力結果が微妙に異なる」「プログラムが正規表現の山になってしまい、実装者以外にはメンテナンスできなくなってしまう」といったたくさんの壁があり、人海戦術作戦で乗り越えていくしかありません。そのあたりの苦労話に興味がある方は @stereocat さんのブログで紹介されてたので参考にしてみてください。（見てるだけでお腹が痛くなれます）
[CLIベースのNW自動化バッドノウハウのあれこれ](http://d.hatena.ne.jp/stereocat/20141026/1414295413)

JSNAPyを利用することでテストツール実装の苦労をすっ飛ばしてくれるので、非常にありがたい存在です。さきほど挙げた課題のすべてが楽になるかどうかは実際に試してみないとわからないところではありますが、大部分が楽になることには間違いないと思います。

サーバでいうところのテストツール [Serverspec](http://serverspec.org/) 相当のルータ版が存在しないことが、今のネットワーク運用自動化を難しくしてしまっている大きな要因の一つとなっているので、このJSNAPyのようなテストツールの登場にはとても期待しています。

## マルチベンダー化への考え方
PyEZ、JSNAPyについて具体的に紹介する前に、自動化に関するちょっとしたヨモヤマ話です。

ネットワークを運用されている組織の方の中には「Juniper専用ツールで自動化したって、他社ルータでも動かせなかったら効果半減じゃない」というご批判はあるかもしれません。まったくその通りです。上記でご紹介したツールはJUNOSルータ以外では動きません。私の所属する組織でも、もちろんJuniper以外のネットワーク装置はたくさんあります。当然ながら上記のJuniperツールで全ての装置を対応することはできません。

ただ、ネットワーク運用業務を自動化するにあたって、いきなりすべてのベンダーに対応させることを狙うのは、現時点では非常に難しい課題です。なぜなら現時点でマルチベンダー製品すべてに対応できるオープンなソフトウェアはまだあまり無いからです。(現時点ではAnsibleやNAPALMのようなサードパーティAPIがその位置を狙っているように見えますが、自動化したい機能要件を満たせているかは装置ごとにマチマチなので注意しなければなりません。)

マルチベンダ対応への実現方法については、おそらくみなさまそれぞれの考えがあると思うので、ここでは是非については議論しませんが、現時点での私個人の考えとして以下の流れで検討・検証を進めていくとうまく前に進むのではないかと考えています。

1. まず、1製品に絞って、運用業務を自動化するための仕組みを検討->実装->検証し、運用方針を確立させる。
 - 作業頻度の多さや自動化の容易さで、対象の１製品を選択する。
 - この時点では、ベンダーが提供しているAPIやライブラリを使って、存分にラクをする。
 - １製品で自動化を実装しつつも、他社製品にも応用ができないか、応用するとしたらどのようにシステム設計すれば移行可能か、常にマルチベンダ対応化をイメージしながら検証を進める
2.  1. の実施後、作業自動化の方針に確信が持てたら、同じ仕組みで他ベンダー製品にも展開できないか、検討->実装->検証する。
3.  2.で既存手法でうまくいかない場合は、1.で利用した仕組みを真似て、代替版を自ら実装してみる。1人での実装が難しい場合は、社内外問わず協力者を見つける

以上のように、まずは自動化しやすい部分から検討をはじめ、最終的にオープンソースソフトウェア開発に近い流れを作り出せると、マルチベンダー対応ツールの実装が進んでいくのかなと想像しています。実際、このようなアイディアで実装が進められているマルチベンダ対応ライブラリとして[NAPALM](https://github.com/napalm-automation/napalm) というツールもあったりします。

NAPALMについては、過去のブログで紹介していますのでご興味があればみてみてください。
- [ルータ制御APIライブラリ NAPALMを触ってみた](http://qiita.com/taijijiji/items/a3f21c8b9e7a0d3afdc6)
- 続編を[NetOpsCoding Advent Calendar 2016](http://qiita.com/advent-calendar/2016/netopscoding)の後半でも書く予定です。

このような考えのもとで、私の場合は

1. まずネットワーク自動化の仕組みやドキュメントが充実しているJuniper製品で自動化を試して、検証するための仕組みを構築。(今回の発表/ブログはここがターゲット)
2. Juniper製品での自動化の手法が洗練されてきたら、別のベンダー製品にも仕組みを展開/応用する手段を模索。
  - リソース管理モジュールや命令実行モジュールはそのまま流用し、ルータ制御モジュールのみを他ベンダー製品に対応できるモジュール(現時点ではNAPALMが有力?)に置き換えるプランを検討。
  - JSNAPy相当のテストツールは、まだ他ベンダ製品に対応できるものがまだ無いので、実装手段は検討中。
3. ネットワーク運用への本番導入への目処が立ってきたら、社外コミュニティでアイディアおよび検証結果を公開することで社内外で議論を深め、アイディアと実装方法をさらに洗練させる。

というアイディアで、自動化開発の方針を進めることにしています。


前置きが長くなってしまいましたが、次回からPyEZおよびJSNAPyの具体的な利用方法について紹介していきます。

[PyEZとJSNAPyを使ってみた。第二部: PyEZ使ってみた編](http://qiita.com/taijijiji/items/626cef18757d638251cf)