nccでIOX XEのModle Driven Telemetryを試す

# はじめに

`ncc`はNetconfのオペレーションを実行するためのコマンドラインツールです。内部ではPythonの標準的なNetconfライブラリである`ncclient`を用いています。

**[Github] CiscoDevNet/ncc**
https://github.com/CiscoDevNet/ncc

**[Github] ncclient/ncclient**
https://github.com/ncclient/ncclient

今回は`ncc`を用いてIOS XEのModle Driven Telemetryを試してみたいと思います。

IOS XEのModel Driven Telemetry自体については以下の記事を参考にしてください。
IOS XEのModel Driven Telemetryは、現在、IETF Telemetryのプレスタンダード版(draft-ietf-netconf-yang-push)に準拠してます。

**[Qiita] IOS XEのModel Driven Telemetryを試してみた**
https://qiita.com/tetsusat/items/eae0f79f445e54ef662f

# 前提

以下の環境で試しました。

* Ubuntu 16.04.4
* Python 3.5.2
* virtualenv 16.1.0

# インストール

Githubから`ncc`プロジェクトを`git clone`します。

```bash
$ git clone https://github.com/CiscoDevNet/ncc.git
$ cd ncc/
```

virtualenv環境で`ncc`をインストールします。

```bash
$ virtualenv v
$ source v/bin/activate
(v)$ pip install --upgrade pip
(v)$ pip install -r requirements.txt
```

IOS XEのModel Driven Telemetry機能を試すには、前の処理でインストールされたオフィシャルな`ncclient`をCiscoDevnet版の`ncclient`に置き換える必要があります。

余談ですが、IETF Telemetryの標準化が採択された暁には、CiscoDevnet版の`ncclient`のIETF Telemetryに関係する実装がオフィシャルな`ncclient`にもマージされると思います。

```bash
$ pip install --upgrade git+https://github.com/CiscoDevNet/ncclient.git
```

`ncc`をクローンしたディレクトリに`ncc-establish-subscription.py`というPythonスクリプトがあります。これがIOS XEのIETF Telemetryを試すためのコマンドラインツールになってます。

```bash
$ ./ncc-establish-subscription.py --help
usage: ncc-establish-subscription.py [-h] [--host HOST] [-u USERNAME]
                                     [-p PASSWORD] [--port PORT] [-v]
                                     [--delete-after DELETE_AFTER] -x XPATHS
                                     [XPATHS ...] [--streamns STREAMNS]
                                     [--callback CALLBACK]
                                     (--period PERIOD | --dampening-period DAMPENING_PERIOD | --streamident STREAMIDENT)

Select your telemetry parameters:

optional arguments:
  -h, --help            show this help message and exit
  --host HOST           The IP address for the device to connect to (default
                        localhost)
  -u USERNAME, --username USERNAME
                        Username to use for SSH authentication (default
                        'cisco')
  -p PASSWORD, --password PASSWORD
                        Password to use for SSH authentication (default
                        'cisco')
  --port PORT           Specify this if you want a non-default port (default
                        830)
  -v, --verbose         Exceedingly verbose logging to the console
  --delete-after DELETE_AFTER
                        Delete the established subscription after N seconds
  -x XPATHS [XPATHS ...], --xpaths XPATHS [XPATHS ...]
                        List of xpaths to subscribe to, one or more
  --streamns STREAMNS   Namespace for a custom stream identity, e.g.
                        urn:cisco:params:xml:ns:yang:cisco-xe-ietf-yang-push-
                        ext
  --callback CALLBACK   Module that a callback is defined in
  --period PERIOD       Period in centiseconds for periodic subscription
  --dampening-period DAMPENING_PERIOD
                        Dampening period in centiseconds for on-change
                        subscription
  --streamident STREAMIDENT
                        Custom stream identifier (e.g. yang-notif-native)
```

# 実験

以下のように実行すると、一分間のCPU使用率の情報が定期的（10秒毎）にNotificationがプッシュされてきます。

```bash
$ ./ncc-establish-subscription.py --host 192.0.2.1 --port 830 -u admin -p admin --period=1000 --xpath '/process-cpu-ios-xe-oper:cpu-usage/cpu-utilization/one-minute'
No callback for subscription_id=2147483654
Subscription Result : notif-bis:ok
Subscription Id     : 2147483654
-->>
(Default Callback)
Event time      : 2018-11-06 11:18:39.120000+00:00
Subscription Id : 2147483654
Type            : 1
Data            :
<datastore-contents-xml xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push">
  <cpu-usage xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-process-cpu-oper">
    <cpu-utilization>
      <one-minute>0</one-minute>
    </cpu-utilization>
  </cpu-usage>
</datastore-contents-xml>

<<--
```

複数のオブジェクトの情報を取得するには二通りのやり方があります。

一つ目は、SubscriptionのXPathの指定にユニオンオペレータ(|)が使えるので、以下のようにすると、1つのSubscriptionで複数のオブジェクトにサブスクライブできます。都度のNotificationも一つに集約されていることが分かります。

```
$ ./ncc-establish-subscription.py --host 192.0.2.1 --port 830 -u admin -p admin --period=1000 --xpath '/interfaces/interface[name="GigabitEthernet1"]/statistics/in-octets|/interfaces/interface[name="GigabitEthernet1"]/statistics/out-octets'
No callback for subscription_id=2147483659
Subscription Result : notif-bis:ok
Subscription Id     : 2147483659
-->>
(Default Callback)
Event time      : 2018-11-06 11:22:55.020000+00:00
Subscription Id : 2147483659
Type            : 1
Data            :
<datastore-contents-xml xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push">
  <interfaces xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-interfaces-oper">
    <interface>
      <name>GigabitEthernet1</name>
      <statistics>
        <in-octets>24883842216</in-octets>
        <out-octets>41292190</out-octets>
      </statistics>
    </interface>
  </interfaces>
</datastore-contents-xml>

<<--
```

二つ目は、`ncc-establish-subscription.py`の`--xpath`オプションで複数のオブジェクトを指定することで、複数のSubscriptionで複数のオブジェクトにサブスクライブできます。

```bash
$ ./ncc-establish-subscription.py --host 192.0.2.1 --port 830 -u admin -p admin --period=1000 --xpath '/interfaces/interce[name="GigabitEthernet1"]/statistics/in-octets' '/interfaces/interface[name="GigabitEthernet1"]/statistics/out-octets'
No callback for subscription_id=2147483657
Subscription Result : notif-bis:ok
Subscription Id     : 2147483657
No callback for subscription_id=2147483658
Subscription Result : notif-bis:ok
Subscription Id     : 2147483658
-->>
(Default Callback)
Event time      : 2018-11-06 11:21:43.480000+00:00
Subscription Id : 2147483657
Type            : 1
Data            :
<datastore-contents-xml xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push">
  <interfaces xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-interfaces-oper">
    <interface>
      <name>GigabitEthernet1</name>
      <statistics>
        <in-octets>24883701125</in-octets>
      </statistics>
    </interface>
  </interfaces>
</datastore-contents-xml>

<<--
-->>
(Default Callback)
Event time      : 2018-11-06 11:21:43.590000+00:00
Subscription Id : 2147483658
Type            : 1
Data            :
<datastore-contents-xml xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push">
  <interfaces xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-interfaces-oper">
    <interface>
      <name>GigabitEthernet1</name>
      <statistics>
        <out-octets>41215279</out-octets>
      </statistics>
    </interface>
  </interfaces>
</datastore-contents-xml>

<<--
```

`ncc-establish-subscription.py`の実装内容を参考にすれば、CiscoDevnet版の`ncclient`を使って、IOS XEのModle Driven Telemetryを試してみるプログラムを作成することもできると思います。

おしまい