pyATS/GenieとRobot Framework で簡単にマルチベンダーネットワークをチェックする

この記事はシスコの有志による Cisco Systems Japan Advent Calendar 2018 の 11 日目として投稿しています。
2017年版: https://qiita.com/advent-calendar/2017/cisco
2018年版: https://qiita.com/advent-calendar/2018/cisco

今回は [pyATS/Genie](https://developer.cisco.com/site/pyats/) と [Robot Framework](http://robotframework.org/) を使って、マルチベンダーのネットワーク機器達をチェックする例を紹介したいと思います。

# pyATS/Genie とは

[pyATS(Python Automated Test System)](https://developer.cisco.com/site/pyats/)は、[Cisco](https://www.cisco.com/) によって開発さている python ベースのテストフレームワークです。ネットワーク機器のテストを行うことをメインで作成されているため、ネットワーク構成を定義したり、ネットワーク機器への接続するコネクター([Unicon](https://pubhub.devnetcloud.com/media/pyats-packages/docs/unicon/index.html))も用意されています。

pyATS には下記の記事も参照ください。
* [pyATSの初歩](https://qiita.com/tokatsu/items/58fbd2b2b219f33b8721)
* [pyATSに夜Cisco IOS Routerのテスト例](https://qiita.com/tokatsu/items/46565062e93d01405f93)

[Genie](https://pubhub.devnetcloud.com/media/pyats-packages/docs/genie/index.html) は pyATS のフレームワークの上で動く機能ライブラリとなり、BGP、OSPF、NTP などの情報を機器から取得する Parser、プロトコルの情報を一元的に集約する Ops 、機器の設定を行う Conf、またテストを行うための事前定義された Trigger/Verification を含む SDK で構成されています。

また、[Genie](https://pubhub.devnetcloud.com/media/pyats-packages/docs/genie/index.html) のライブラリはオープンソースとなっており、公開されているため、必要であればユーザー環境に応じて変更/追加するといったことが可能です。

* [pyATS & Genie の GitHub Repository](https://github.com/CiscoTestAutomation)

今回はほぼ python の知識無しで pyATS/Genie を使うことを想定して書いていますので、掘り下げたところはあまり書かず、こういう事が [pyATS/Genie](https://developer.cisco.com/site/pyats/) で可能なんだというのを知ってもらうのが目的です。

それではさっそく始めてみましょう。

# pyATS & Genie のインストール

[pyATS/Genie](https://developer.cisco.com/site/pyats/) は Python の仮想環境(virtualenv)にインストールを行います。下記は MacOS で pyenv/virtualenv を使った場合の例です。

```
$ pyenv install 3.6.5
$ pyenv virtualenv 3.6.5 genie_env
$ pyenv activate genie_env
(genie_env)$ python -V
Python 3.6.5
```

Python の pyenv/virtualenv を試したことが無いかたは、ググるとたくさん情報が出てきますので、探してみてください。

Python の仮想環境が構築できたら、インストールは1コマンドです。

```
(genie_env)$ pip install pyats genie genie.libs.robot
```

Docker が使える環境の人は Docker でもインストールが可能です。

```
$ docker pull ciscotestautomation/pyats:latest-robot
```
* [pyATS の DockerHub](https://hub.docker.com/r/ciscotestautomation/pyats/)

今回はpythonの仮想環境を使っている場合を想定して説明を続けます。

注: [pyATS/Genie](https://developer.cisco.com/site/pyats/) が現在サポートしている Python バージョンは 3.4/3.5/3.6 になります。

# Robot Framework とは

[Robot Framework](http://robotframework.org/) はキーワードを用いて対話的なインタフェースでプログラムを実行ができるようになるフレームワークです。コードが書けない、苦手という人にとってキーワードで用意されたプログラムを簡単に実行できるようになります。

[pyATS/Genie](https://developer.cisco.com/site/pyats/) でもこの [Robot Framework](http://robotframework.org/) を使用することにより、対話的にネットワーク機器のチェック/テストを行うことが可能にしています。

# マルチベンダー環境でのNTP同期のチェックを行う

今回は下記の構成で NTP 同期ができているか全機器に対して行う例を紹介します。
マルチベンダーということで、今回は [Juniper](https://juniper.net/) 社の JUNOS を構成に入れています。

### ネットワーク構成

![image.png](https://qiita-image-store.s3.amazonaws.com/0/309712/c0cc4b46-f98e-1434-8451-3868d834bb3d.png)

|Hostname |OS |Version |
|:--------|:--|:-------|
|iosv-1   |IOS|15.6(3)M2|
|iosv-2   |IOS|15.6(3)M2|
|iosv-3   |IOS|15.6(3)M2|
|csr1000v-1|IOSXE|16.6.1|
|nx-osv9000-1|NXOS|7.0(3)I7(1)|
|vsrx-1|JUNOS|12.1X46-D10.2|

### CLI での実行結果

ではさっそく、[pyATS/Genie](https://developer.cisco.com/site/pyats/) を [Robot Framework](http://robotframework.org/) で実行した画面を見てみましょう。

```
$ robot genie_ntp_example.robot
==============================================================================
Genie Ntp Example
==============================================================================
Initialize                                                            | PASS |
------------------------------------------------------------------------------
Verify NTP synchronization check on all devices                       | PASS |
------------------------------------------------------------------------------
Profile ntp on nx-osv9000-1                                           | PASS |
------------------------------------------------------------------------------
TriggerSleep on nx-osv9000-1                                          | PASS |
TriggerSleep has passed
------------------------------------------------------------------------------
Profile ntp on nx-osv9000-1, Compare it with previous snapshot        | PASS |
Comparison between snap2 and snap1 is identical
------------------------------------------------------------------------------
Verify NTP synchronization check on iosv-1                            | PASS |
------------------------------------------------------------------------------
Verify NTP synchronization check on iosv-2                            | PASS |
------------------------------------------------------------------------------
Verify NTP synchronization check on iosv-3                            | PASS |
------------------------------------------------------------------------------
Verify NTP synchronization check on csr1000v-1                        | PASS |
------------------------------------------------------------------------------
Verify NTP synchronization check on nx-osv9000-1                      | PASS |
------------------------------------------------------------------------------
Verify NTP synchronization check on vsrx-1                            | PASS |
------------------------------------------------------------------------------
Genie Ntp Example                                                     | PASS |
11 critical tests, 11 passed, 0 failed
11 tests total, 11 passed, 0 failed
==============================================================================
Output:  /Users/tahigash/.pyenv/versions/3.6.5/envs/genie_20181208/ntp_robot_example/output.xml
Log:     /Users/tahigash/.pyenv/versions/3.6.5/envs/genie_20181208/ntp_robot_example/log.html
Report:  /Users/tahigash/.pyenv/versions/3.6.5/envs/genie_20181208/ntp_robot_example/report.html
```

上の結果画面だけを見ても各項目に対して結果が表示されており、分かりやすいですね。

### HTML でのログ確認

上記 CLI 実行結果の最後の3行から分かるように出力ファイルとして log.html が作成されるため、Web ブラウザでさらに視覚的に、またコンソールログと一緒に詳細が確認可能です。

**log.html 画面の例:**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/309712/9da79678-d36d-bdd3-b392-db196aadb1d7.png)

**コンソールログを表示した例(csr1000v-1:IOSXE):**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/309712/374f156e-1439-9641-67a2-8d41cb3b4e39.png)

**コンソールログを表示した例(vsrx-1:JUNOS)**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/309712/d98d8e22-7a3e-c754-c6c2-b582ed6bbff5.png)

NTP 同期がされている状態かは上記画面の NTP サーバアドレスの '*' をチェックしています。

### 作成したのは２つのファイルのみ！

#### testbed yaml (ntp_testbed\.yaml)

一つ目はネットワーク機器を定義した ntp_testbed.yaml に各機器へのアクセス情報(IPアドレス/Telnet or SSH)などを下記今回の機器1台分のみの例です。

```:ntp_testbed.yaml
testbed:
  name: ntp_testbed             # テストベッドの名前
devices:
  csr1000v-1:                   # デバイス名（ホスト名)
    alias: csr1000v-1
    os: iosxe
    platform: iosxe
    type: CSR1000v
    tacacs:
      login_prompt: 'login:'    # ログインプロンプトの定義
      password_prompt: 'Password:' # パスワードプロンプトの定義
      username: admin           # アクセスするユーザ名
    passwords:
      enable: cisco             # ログインパスワード
      line: cisco
      tacacs: cisco
    connections:
      defaults:
        class: unicon.Unicon    # コネクターの指定
      a:                        # Console アクセス情報
        ip: 172.25.192.134
        port: 17012
        protocol: telnet
      vty:                      # Telnet アクセス情報
        ip: 10.255.7.248
        protocol: telnet
    custom:                     
      abstraction:              # 抽象化のための設定
        order:
        - os
        - platform
  iosv-1:
  (snip)
```

上記は [pyATS/Genie](https://developer.cisco.com/site/pyats/) では testbed.yaml と呼ばれます。詳細は下記のドキュメントも参照してみてください。

* [pyATS:Testbed & Topology Information](https://pubhub.devnetcloud.com/media/pyats/docs/topology/index.html)
* [pyATS:Example Testbed File](https://pubhub.devnetcloud.com/media/pyats/docs/topology/example.html)

#### robot file (genie_ntp_example\.robot)

二つ目は robot のファイル genie_ntp_example.robot です。英語会話風の対話的な形で実行したい項目追加します。

```:genie_ntp_example.robot
# Genie NTP example with Robot

*** Settings ***
Library        ats.robot.pyATSRobot         # pyATS/Genie をライブラリとして指定
Library        genie.libs.robot.GenieRobot

*** Variables ***
${testbed}     ntp_testbed.yaml             # テストベッドファイルの指定

*** Test Cases ***
Initialize
    use genie testbed "${testbed}"          # テストベッドファイルの読み込み
    connect to all devices                  # 全機器への接続

Verify NTP synchronization check on all devices          # アイテム名（項目名）
    verify NTP is synchronized on device "iosv-1"        # Robot キーワード。ここでは各機器のNTP同期を一つのアイテムでまとめてチェックしている
    verify NTP is synchronized on device "iosv-2"
    verify NTP is synchronized on device "iosv-3"
    verify NTP is synchronized on device "csr1000v-1"
    verify NTP is synchronized on device "nx-osv9000-1"
    verify NTP is synchronized on device "vsrx-1"

Profile ntp on nx-osv9000-1
    Profile the system for "ntp" on devices "nx-osv9000-1" as "snap1"    # Genie NTP Ops のスナップショット 'snap1'

TriggerSleep on nx-osv9000-1
    run trigger "TriggerSleep" on device "nx-osv9000-1"                  # Genie TriggerSleep デフォルトで 5秒間 のスリープ

Profile ntp on nx-osv9000-1, Compare it with previous snapshot
    Profile the system for "ntp" on devices "nx-osv9000-1" as "snap2"    # Genie NTP Ops のスナップショット 'snap2'
    Compare profile "snap2" with "snap1" on devices "nx-osv9000-1"       # Genie NTP Ops snap1/snap2 を比較

Verify NTP synchronization check on iosv-1           # 最初の NTP 同期を各アイテムごとに１機器のみにしてチェック
    verify NTP is synchronized on device "iosv-1"

Verify NTP synchronization check on iosv-2
    verify NTP is synchronized on device "iosv-2"

Verify NTP synchronization check on iosv-3
    verify NTP is synchronized on device "iosv-3"

Verify NTP synchronization check on csr1000v-1
    verify NTP is synchronized on device "csr1000v-1"

Verify NTP synchronization check on nx-osv9000-1
    verify NTP is synchronized on device "nx-osv9000-1"

Verify NTP synchronization check on vsrx-1
    verify NTP is synchronized on device "vsrx-1"
```

"connect to all devices", "verify NTP is ..." という Robot キーワードは事前にライブラリで定義されている必要があります。汎用性のあるキーワードがすでに用意されているため、それを使うことで今回のようなチェックを簡単に行うことができます。
[pyATS/Genie](https://developer.cisco.com/site/pyats/) で用意されている Robot キーワードは下記から確認できます。Genie のキーワードはオープンソースのため、無いものは作成して追加することが可能です。

* [pyATS Keywords](https://pubhub.devnetcloud.com/media/pyats/docs/robot/index.html)
* [Genie Keywords](https://pubhub.devnetcloud.com/media/pyats-packages/docs/genie/robot/index.html)

"Profile ntp ..." というアイテムでは、Genie Ops を使用しています。Genie Ops は各プロトコル/機能のオペレーショナルデータを複数の show コマンドから共通のモデルで収集したオブジェクトになります。
上の例を見ると分かるかと思いますが、共通モデルのおかげにより OS/Vendor の異なる機器に対しても同じ形で操作を行うことができます。
今回はシンプルに使ってもらうことが目的だったので、このあたりについてはまた別の機会に紹介できればと思っています。

どうでしょうか？ [pyATS/Genie](https://developer.cisco.com/site/pyats/) + [Robot Framework](http://robotframework.org/) で簡単な使い方ができるというのが伝わったら幸いです。

# まとめ

今回の簡単なまとめ。

* Cisco がネットワークテストオートメーションツール [pyATS/Genie](https://developer.cisco.com/site/pyats/) を無料で公開している
* [Genie](https://pubhub.devnetcloud.com/media/pyats-packages/docs/genie/index.html) のライブラリはオープンソースとして GitHub で公開している。ユーザ側で変更および追加、コードの貢献ができる！
* [pyATS/Genie](https://developer.cisco.com/site/pyats/) + [Robot Framework](http://robotframework.org/) による対話的な記述によるほぼ python 知識無しでのテストの実行が可能
* [pyATS/Genie](https://developer.cisco.com/site/pyats/) はマルチベンダ対応が可能！フレームワーク、ライブラリのコンセプトがシスコ機器に特化しているという訳ではない
* [Genie](https://pubhub.devnetcloud.com/media/pyats-packages/docs/genie/index.html) ライブラリは共通モデルによりOS、ベンダ問わず同じ形で操作が可能。
* [日本人の開発エンジニア(@tahigash3)](https://twitter.com/tahigash3)がいる。日本語情報が入りやすいかも！？（おまけ）

皆さん、ぜひこれを機会に [pyATS/Genie](https://developer.cisco.com/site/pyats/) をインストールして使ってみてくださいね。

# 免責事項

本サイトおよび対応するコメントにおいて表明される意見は、投稿者本人の個人的意見であり、シスコの意見ではありません。本サイトの内容は、情報の提供のみを目的として掲載されており、シスコや他の関係者による推奨や表明を目的としたものではありません。各利用者は、本Webサイトへの掲載により、投稿、リンクその他の方法でアップロードした全ての情報の内容に対して全責任を負い、本Web サイトの利用に関するあらゆる責任からシスコを免責することに同意したものとします。