network機器のWeb API化

# これはなにか
自作gemの[xlogin](https://rubygems.org/gems/xlogin)を利用し、Web APIを提供していないネットワーク機器にも外付けのAPIを提供するツール。

# 動作イメージ

![Screenshot from 2017-07-20 21-01-28.png](https://qiita-image-store.s3.amazonaws.com/0/16560/d0616d02-cbfc-7623-359e-46463320be7a.png)




図のように、対象機器に対してパラメータ付きでコマンドを解釈・実行し、必要な情報のみキャプチャすることができる。

JSON APIもサポートしているので以下のようにCLIからも情報取得でき、`captured`を切り出せばinfluxdb等の時系列DBによる可視化が容易にできる。

~~~.sh
$ curl -s -XGET http://localhost:3000/FDytULGzpXufoA.json?intf=eth1 | jq .
{
  "status": "success",
  "query": "show interfaces ethernet eth1",
  "body": "show interfaces ethernet eth1\n\u001b=\reth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN gro\u001b[m \bup default \u001b[m\n    link/ether dc:9f:db:28:0f:de brd ff:ff:ff:ff:ff:ff\u001b[m\n    inet 192.168.1.1/24 brd 192.168.1.255 scope global eth1\u001b[m\n       valid_lft forever preferred_lft forever\u001b[m\n    inet6 2001::1/64 scope global \u001b[m\n       valid_lft forever preferred_lft forever\u001b[m\n    inet6 fe80::de9f:dbff:fe28:fde/64 scope link \u001b[m\n       valid_lft forever preferred_lft forever\u001b[m\n    Description: LAN1\u001b[m\n\u001b[m\n    RX:  bytes    packets     errors    dropped    overrun      mcast\u001b[m\n    5463830257   38892904          0       1849          0      83149\u001b[m\n    TX:  bytes    packets     errors    dropped    carrier collisions\u001b[m\n    81354474060   61170118          0          0          0          0\u001b[m\n\r\u001b[K\u001b>haccht@erl-3:~$ \n",
  "captured": {
    "input_bytes": 5463830257,
    "input_errors": 0,
    "input_drops": 1849,
    "output_bytes": 81354474060,
    "output_errors": 0,
    "output_drops": 0
  }
}
~~~


# インストール

DBにはmysqlを利用しているので、予めmysqlもしくはmariadbをインストールしておく必要がある。

~~~.sh
$ git clone https://github.com/haccht/networkapi.git

$ cd networkapi
$ bundle install --path vendor/bundle

$ MYSQL_PASSWORD='<password>' bundle exec rails db:create
$ MYSQL_PASSWORD='<password>' bundle exec rails db:migrate
$ MYSQL_PASSWORD='<password>' bundle exec rails server -b 0.0.0.0 -p 3000
~~~

ブラウザから http://localhost:3000/ にアクセスしてうまくトップページが表示されていればOK。

# 利用方法

## 対象ネットワーク機器のHostを登録する

これは自宅のedgerouter-lite3を登録した様子。
対象機器へのコネクションはURI形式で指定する。
xlogin側が対応できていないので現状とりあえずtelnetのみサポート。ssh対応？手が空いたときにやります。

![Screenshot from 2017-07-20 21-02-04.png](https://qiita-image-store.s3.amazonaws.com/0/16560/d6cf90a3-da80-755b-a2c1-1d4480ab9351.png)


なお、`Architecture`の欄には`lib/templates`ディレクトリにある機器のファームウェアテンプレートを指定する。
IOS等のファームウェアに追加対応する場合は、ビルトインしている`vyos.rb`を参考に作成すればよい。


## 対象ネットワーク機器に投入するCommandを登録する

ここでは実際に機器に投入するコマンドを入力する。
パラメータとして実行時に指定する項目は`{{ }}`で囲んで変数として定義しておくことができる。

![Screenshot from 2017-07-20 21-02-18.png](https://qiita-image-store.s3.amazonaws.com/0/16560/594ba586-7126-2ac1-96a4-0e65ca43cb52.png)


また`Captures`で指定した[名前付き正規表現](http://www.regular-expressions.info/named.html)で任意の文字列をコマンドの出力結果から抽出できる。


## HostとCommandをQueryに紐付ける

最後にこれまで登録したHostとCommandを紐付けるQueryを作成すればOK。

![Screenshot from 2017-07-20 21-11-13.png](https://qiita-image-store.s3.amazonaws.com/0/16560/3e9868cc-aa20-409a-33d4-5dd3526f2e6b.png)


完了すれば下図のようになっているはず。
ここで実行ボタン(青の紙飛行機)を押せば冒頭の実行結果画面が表示される。(パラメータが不足している場合は入力を促される)

![Screenshot from 2017-07-20 21-01-44.png](https://qiita-image-store.s3.amazonaws.com/0/16560/95793458-2dfc-d91d-18cf-652e6a6590d7.png)


# 実装、利用技術について

そのうち追記します。

## 参考
https://github.com/haccht/xlogin.git
https://github.com/haccht/networkapi.git

ネットワークAPIを試作してみた with Ruby/Rails/Redis/expect
http://qiita.com/kooshin/items/21f96c5c32c20a1968a0