CSR1000vのNETCONF

[REST](http://qiita.com/_norin_/items/b902c0e675f4f5e32145)に引き続いてNETCONF


NETCONFのプロトコルは規定されていても中身に関しては各社ばらばらです。
実際に利用出来るスキーマなどは（公開されていれば）ベンダのマニュアルを参照してください。
ここではCSR1000vで検証していますがC2600でも同様のやりかたでアクセス出来たので、IOS・IOS-XEどちらもいけそうな感じです。

#1. 前準備
ルータを設定します。マニュアルに沿って設定していきます。

http://www.cisco.com/cisco/web/support/JP/docs/CIAN/IOS/IOS15_1M_T/CG/009/nm_cns_netconf.html?bid=0900e4b18252971b


・SSH
・ユーザ
・NETCONF
の順に一つずつ設定・確認していけばミスも見つけやすいかと思います。


※注意
上記ドキュメント（元の英語版も含む）の取得・設定例はXMLに文字化けや省略が多々あって、そのままでは動かないものがほとんどです。



#2. 接続
sshの-sオプションでNETCONFサブシステムを起動します

```
$ ssh -s router@csr1000v netconf
<?xml version="1.0" encoding="UTF-8"?>
<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <capabilities>
    <capability>urn:ietf:params:netconf:base:1.0</capability>
    <capability>urn:ietf:params:netconf:capability:writeable-running:1.0</capability>
    <capability>urn:ietf:params:netconf:capability:startup:1.0</capability>
    <capability>urn:ietf:params:netconf:capability:url:1.0</capability>
    <capability>urn:cisco:params:netconf:capability:pi-data-model:1.0</capability>
    <capability>urn:cisco:params:netconf:capability:notification:1.0</capability>
  </capabilities>
  <session-id>817679984</session-id>
</hello>
]]>]]>
```


※見やすいように整形してます

Ciscoの実装ではメッセージの最後は ]]>]]> であると規定されているので、これを区切り文字にしてメッセージを切り出せばいいと思います。



サーバ応答に対してレスポンスを返します

```xml:Response
<?xml version="1.0" encoding="UTF-8"?>
<hello>
  <capabilities>
    <capability>urn:ietf:params:netconf:base:1.0</capability>
    <capability>urn:ietf:params:netconf:capability:writeable-running:1.0</capability>
    <capability>urn:ietf:params:netconf:capability:startup:1.0</capability>
    <capability>urn:ietf:params:netconf:capability:url:1.0</capability>
    <capability>urn:cisco:params:netconf:capability:pi-data-model:1.0</capability>
    <capability>urn:cisco:params:netconf:capability:notification:1.0</capability>
  </capabilities>
</hello>]]>]]>
```

応答はありませんが、これでセッションが確立されました



#3．リクエスト
##3.1 コンフィグ
コンフィグを取得してみます。

```xml:Request
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:cpi="http://www.cisco.com/cpi_10/schema" message-id="101">
  <get-config>
    <source>
      <running/>
    </source>
    <filter>
      <config-format-text-block/>
    </filter>
  </get-config>
</rpc>
]]>]]>
```


```xml:Response
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <data>
    <cli-config-data-block>!
! Last configuration change at 13:49:29 JST Thu Jul 9 2015 by cisco
! NVRAM config last updated at 14:40:40 JST Mon Jul 6 2015
!
version 15.5
service timestamps debug datetime localtime
service timestamps log datetime

・・・・・・

netconf ssh
!
    </cli-config-data-block>
  </data>
</rpc-reply>
]]>]]>
```


出力フォーマットは
> \<config-format-text-block/\>
> \<config-format-text-cmd/\>
> \<config-format-xml/\>

の三種類あります。
blockがshow config相当、cmdが一行ごとのエレメント化、XMLはブロック単位にオブジェクト化されるようです。
文字列解析をするよりもXMLで出力してXMLライブラリにてクラスに変換するのがエレガントなやり方かと思います。

※\<config-format-text-cmd/\>は不具合がある感じ


##3.2 設定変更
以下のコマンドイメージをNETCONFで設定してみます

```text:CLI
interface gigabitEthernet 3.23
encapsulation dot1Q 23
ip address 172.16.23.1 255.255.255.0
no shutdown
```

```xml:Request
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:cpi="http://www.cisco.com/cpi_10/schema" message-id="101">
  <edit-config>
    <target>
      <running/>
    </target>
    <config>
      <cli-config-data>
        <cmd>interface gigabitEthernet 3.23</cmd>
        <cmd>encapsulation dot1Q 23</cmd>
        <cmd>ip address 172.16.23.1 255.255.255.0</cmd>
        <cmd>no shutdown</cmd>
      </cli-config-data>
    </config>
  </edit-config>
</rpc>
]]>]]>
```

```xml:Response
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <ok />
</rpc-reply>
]]>]]>
```


エラー時には以下のようなレスポンスが返ってきます

```xml:error-response
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <rpc-error>
    <error-type>rpc</error-type>
    <error-tag>missing-element</error-tag>
    <error-severity>error</error-severity>
    <error-info>
      <bad-element>edit-config</bad-element>
    </error-info>
  </rpc-error>
</rpc-reply>
]]>]]>
```


設定でも生コンフィグだったりXMLだったりと表記が３種類あります

```xml
<cli-config-data>
  <cmd>
  <cli-config-data-block>
  <xml-config-data>
```
普段のCLIイメージそのままを入れられるblockが楽かもしれません。

##3.3 情報取得
ルーティングテーブルを取得してみます

```xml:Request
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"xmlns:cpi="http://www.cisco.com/cpi_10/schema" message-id="101">
  <get>
    <filter>
      <oper-data-format-text-block>
        <show>
          ip route
        </show>
      </oper-data-format-text-block>
    </filter>
  </get>
</rpc>
]]>]]>
```

```xml:Response
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <data>
    <cli-config-data-block>!
! Last configuration change at 14:26:43 JST Thu Jul 9 2015 by cisco
! NVRAM config last updated at 14:33:01 JST Thu Jul 9 2015 by cisco

・・・・・

netconf lock-time 300
netconf max-message 2147483
netconf ssh
!
    </cli-config-data-block>
    <cli-oper-data-block>
      <item>
        <show>
          ip route
        </show>
        <response>
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area 
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2

・・・・・

C        192.168.1.0/24 is directly connected, GigabitEthernet1
L        192.168.1.1/32 is directly connected, GigabitEthernet1
        </response>
      </item>
    </cli-oper-data-block>
  </data>
</rpc-reply>
]]>]]>
```





不具合なのか仕様なのかわかりませんが、コンフィグも同時に出力されました。
getでコンフィグの取得も出来るので、不具合っぽいですが。


##3.4 セッション終了

```xml:Request
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
  <close-session />
</rpc>
]]>]]>
```

```xml:Response
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <ok />
</rpc-reply>
]]>]]>
```

#4. スキーマ
実装しているスキーマの資料が見つけられなかったのですが、CLI上で確認出来ます

```text
csr1000v#show netconf schema
New Name Space 'urn:ietf:params:xml:ns:netconf:base:1.0'
<VirtualRootTag> [0, 1] required
  <rpc-reply> [0, 1] required
    <ok> [0, 1] required
    <data> [0, 1] required
    <rpc-error> [0, 1] required
      <error-type> [0, 1] required
      <error-tag> [0, 1] required
      <error-severity> [0, 1] required
      <error-app-tag> [0, 1] required
・・・・・
```




#5. おわりに
NETCONFをラップするライブラリがいくつかあるのですが、我が道を征くCisco機器への対応を求めるとそれはNETCONFishだから、とつれない対応されてるようです。

NETCONFもちゃんと実装されれば使えるのですが、対応モデルが増えることと、SNMPv3のような複雑な制御を実装しないことが普及の前提かと思います。