てくなべ (tekunabe)

ansible / network automation / 学習メモ

Netmiko が NEC IX ルーターに対応したので試してみた

はじめに

先日、ネットワーク機器の操作を自動化できる Python ライブラリ、Netmiko のバージョン 4.6.0 がリリースされました。

github.com

このリリースで、NEC IX ルーターにも対応したそうなので、少し試してみます。

実装者は inaba-vdom-0(X inaba_aho_me)さん。ありがとうございます!!

  • 検証環境
    • netmiko 4.6.0
    • python 3.11.10
    • IX2105 Version 10.2.42

[2025/06/29 追記]

実装者による記事も、Netmiko 4.6.0 リリースに伴って更新されました。一番正確な記事なのでぜひご覧ください。

qiita.com

そもそも Netmiko とは

このブログで Netmiko を取り上げる ことが多くなかったため、前置きです。

Netmiko は、Cisco IOS や、Juniper Junos、YAMAHA RTX シリーズ などのネットワーク機器を操作するための Python ライブラリです。ネットワーク自動化系の書籍、資格でも取り上げられることが多いメジャーなライブラリです。Paramiko をネットワーク機器向けにしたものです。

同じ分野の Python ライブラリだと、他には NAPALM、nornir、scrapli などがあります。

Ansible が Playbook 経由で操作するのとは異なり、Python のコードとして実装するタイプのものです。

これまでもさまざまなプラットフォームに対応していましたが、今回 NEC IX ルーターへの対応が加わった形です。

ログイン、ログアウト、各種モード変更がメソッドで抽象化されていたり、プラットフォーム固有のプロンプトハンドリングが必要なため、プラットフォームごとに対応が必要という事情です。抽象度は低いので、他のライブラリやツールに比べると、対応しやすい印象です。とはいえ、プラットフォーム固有の仕様を Netmiko のどのメソッドに対応させるかは、悩むことも少なくないのではと思っています。

だいぶ古くなってしまいましたが、Netmiko は以下の資料の中でも紹介しています。事情が変わっているところもありますが、抽象度が低いという設計は変わっていません。

ネットワーク自動化、なに使う? ~自動化ツール紹介~(2017/08/18追加開催) | PPT

準備

久々に使うので、まっさらな venv で Netmiko をインストールします。

% pip install netmiko
...(略)...
% pip list | grep netmiko
netmiko          4.6.0

お目当ての 4.6.0 がインストールできました。

基本的なお作法

device_type の指定

Netmiko では、各種接続の設定を ConnectHandler に渡します。その際、どのプラットフォームなのかをdevice_type を指定します。

NEC IX ルーター の場合、device_type には SSH であれば nec_ix を、TELNET であれば nec_ix_telnet を指定します。後述するサンプルでは、SSH を利用します。この指定により、内部的にプラットフォーム固有のモード変更やプロンプトハンドリングをしてくれるようになります。

なお、Netmiko にはdevice_type を自動判定する機能もあります。自動判定する場合は、device_type には、"autodetect" を指定します。今回の IX ルーター対応の場合は、内部的には show hardware を実行した結果に IX Series が含まれているかをチェックしているようです。ここまで実装いただいてありがたいです。

モード変更など

「そもそも Netmiko とは」で、モード変更などが抽象化されてると書きました。具体的には、netmiko.BaseConnection クラス内のメソッドで抽象化されています。

代表的なものを以下にまとめます。(コードをざっと拝見しただけですが・・)

メソッド 実行されるコマンド 補足
enable svintr-config 他にコンフィギュレーションモードに入っているユーザーがいたら追い出して自分がはいる(参考
config_mode configure
save_config write memory

ページャーの無効化には、内部的にterminal length 0 を利用しているようです。

show コマンドの実行

まずは、show コマンドを利用して情報を取得して、その結果を画面に表示してみます。ここでは show versions で試します。

なお、機器側は SSH 接続を有効にしていて、Netmiko からも SSH 接続を利用します。device_type はまずはオーソドックスに明示しています。

少々荒いですが、今回は administrator 権限があるユーザーを利用します。

from netmiko import ConnectHandler

ix01 = {
    "device_type": "nec_ix",     # デバイスタイプの指定
    "host": "10.0.0.5",      # 対象デバイスの IP アドレス、ホスト
    "username": "dummy_user",    # ログインユーザー
    "password": "dummy_password" # ログインパスワード
}

command = "show version"
with ConnectHandler(**ix01) as net_connect:
    output = net_connect.send_command(command) # コマンドの実行

print(output)   # 結果の表示

実行します。

% python ix.py 
NEC Portable Internetwork Core Operating System Software
IX Series IX2105 (magellan-sec) Software, Version 10.2.42, RELEASE SOFTWARE
Compiled Sep 09-Fri-2022 13:40:53 JST #2 by sw-build, coregen-10.2(42)

ROM: System Bootstrap, Version 19.1
System Diagnostic, Version 19.1
Initialization Program, Version 19.1

System uptime is 72 weeks 21 hours 51 minutes
System woke up by reload, caused by power-on
System started at Feb 09-Fri-2024 22:16:22 JST
System image file is "ix2105-ms-10.2.42.ldc"

Processor board ID <0>
IX2105 (MPC8314E) processor with 131072K bytes of memory.
2 GigaEthernet/IEEE 802.3 interfaces
512K bytes of non-volatile configuration memory.
16384K bytes of processor board System flash (Read/Write)

Current configuration is based on "startup-configuration"
Default console is web.
% 

無事に show コマンドの結果が表示されました。

なお、show running-config のように、コンフィギュレーションモードになっている必要がある show コマンドは、事前に enable() しておきます。

command = "show running-config"
with ConnectHandler(**ix01) as net_connect:
    net_connect.enable()    # svintr-config が実行される
    output = net_connect.send_command(command)

print(output)

設定変更してみる

今度は設定変更してみます。

ここではインターフェースの description を設定する簡単な例で試します。

from netmiko import ConnectHandler

ix01 = {
    "device_type": "nec_ix",     # デバイスタイプの指定
    "host": "10.0.0.5",      # 対象デバイスの IP アドレス、ホスト
    "username": "dummy_user",    # ログインユーザー
    "password": "dummy_password" # ログインパスワード
}

# 設定したいコンフィグをリストで指定
config_commands = [ "interface GigaEthernet0.0",    
                    "description hogehoge"]
with ConnectHandler(**ix01) as net_connect:
    output = net_connect.send_config_set(config_commands) # 設定の投入
    net_connect.save_config()  # write memory

print(output)   # おまけ的ですが戻り値を表示

実行してみます。なお、実行前の desciption は未設定です。

% python ix_config.py
interface GigaEthernet0.0
IX01(config-GigaEthernet0.0)# description hogehoge
IX01(config-GigaEthernet0.0)# exit
IX01# 
%

出力があるのは、おまけ的に print() しているためです。

手動で確認してみると、無事に running-config にも startup-config にも(write memoryしたため)設定変更されてました。

実行コマンドをデバッグ

今回のケースに限りませんが、DEBUG レベルのログ出力をすると、内部的に実行されるコマンドが確認できました。

例えば、

import logging
logging.basicConfig(filename='debug.log', level=logging.DEBUG)
logger = logging.getLogger("netmiko")

のように仕込んでおくと、以下のような内容を確認できました。

...(略)...
DEBUG:netmiko:read_channel: 
DEBUG:netmiko:In disable_paging
DEBUG:netmiko:Command: 
terminal length 0

DEBUG:netmiko:write_channel: b'\nterminal length 0\n'
DEBUG:netmiko:read_channel: 
...(略)...

おわりに

Netmiko で NEC の IX ルーターの show コマンド事項や設定変更を試してみました。

日本のベンダーの機器に対応するのは嬉しいですね。あらめて機能追加ありがとうございました!