Netmikoの基本的な使用方法と対応機種の追加

Pythonのネットワーク機器の操作補助ライブラリである netmikoの基本的な使用方法と、
標準では未対応の機種の追加方法についてご紹介します。

Multi-vendor library to simplify Paramiko SSH connections to network devices
https://github.com/ktbyers/netmiko

目次

  1. Netmikoとは
  2. 基本的な使用方法
    1. SSH接続(パスワード認証)
    2. SSH接続(公開鍵認証)
    3. Telnet接続
    4. シリアルポート接続
    5. device_typeに指定する文字列
  3. 対応機種の追加方法
  4. まとめ

1. Netmikoとは

  • リモート機器に接続し、操作の補助をする Pythonライブラリ
  • ログイン、ログアウト、モード移行や、ページング設定コマンド、
    その他のコマンドを個別に実行できるメソッドなどが実装されている。
  • SSH接続が基本。一部機種で Telnet接続、シリアルポート接続にも対応。
  • Cisco, Juniper, Palo Alto, Dell, Linuxなどマルチベンダに対応。
  • pipでインストール可能:pip install netmiko
  • 2020年1月24日時点の最新バージョンはVersion 3.0.0

2. 基本的な使用方法

ssh_dispatcherから、ConnectHandlerをインポートして、接続情報を引数に指定し、
netmikoクラスオブジェクトを取得します。
netmikoクラスオブジェクトには、コマンドが実行できるメソッドなどが実装されており、
接続時に指定した機種に応じて、実行されるコマンドや処理は異なります。
# モジュールのインポート
from netmiko.ssh_dispatcher import ConnectHandler

# リモート機器への接続、コネクションオブジェクトの取得
connection = ConnectHandler(**remote_params)    # remote_params: 接続情報

# netmikoクラスメソッドの実行
# 例:ページング設定コマンドを実行
connection.disable_paging()         # Cisco IOS: terminal length 0
                                    # Linux    : なし(return "")
# 例:モード変更コマンドを実行
connection.enable()     # Cisco IOS: enable
                        # Linux    : sudo -s

# 例:コマンド実行、結果受信
result = connection.send_command(command_string='実行コマンド')

# 接続の解除
connection.disconnect()
接続方式ごとに ConnectHandlerの引数に指定する値については、以下の通りです。(Cisco IOSの例)

2.1 SSH接続(パスワード認証)

connection = ConnectHandler(ip='接続機器のipアドレス',      # 引数:hostにホスト名を指定することも可能
                            username='ログインユーザ名',    # ログインするユーザ名
                            password='ログインパスワード',  # ログインユーザのパスワード
                            device_type='cisco_ios'      # 接続機器の機種
                            )

2.2 SSH接続(公開鍵認証:鍵ファイルを指定する例)

connection = ConnectHandler(host='名前解決できるホスト名',   # 引数:ipが指定されている場合はipが優先
                            username='ログインユーザ名',    # ログインするユーザ名
                            key_file='鍵ファイルパス',     # 鍵ファイルのパス
                            device_type='cisco_ios'      # 接続機器の機種
                            )

2.3 Telnet接続

必要な情報は SSHパスワード認証と同様ですが、device_typeに Telnet接続用の指定が必要となります。
connection = ConnectHandler(ip='接続機器のipアドレス',      # 引数:hostにホスト名を指定することも可能
                            username='ログインユーザ名',    # ログインするユーザ名
                            password='ログインパスワード',  # ログインユーザのパスワード
                            device_type='cisco_ios_telnet' # 接続機器の機種
                            )

2.4 シリアルポート接続

シリアルポート接続時は、SSH接続や Telnet接続とは大きく異なり、
引数 serial_settingsに COMポート番号などの値を指定します。
また、device_typeには、シリアルポート接続用の指定が必要となります。
connection = ConnectHandler(serial_settings={'port': 'COM1',                  # COMポート番号
                                             'baudrate': 9600,                # ボー・レート
                                             'bytesize': serial.EIGHTBITS,    # データビット長
                                             'parity': serial.PARITY_NONE,    # パリティチェック
                                             'stopbits': serial.STOPBITS_ONE  # ストップビット長
                                             },
                            device_type='cisco_ios_serial'                    # 接続機器の機種
                            )
上記の serial_settingsの値は、デフォルトで指定されています。
指定できる項目は、Tera Termを使用したことのある方なら 、
「設定」→「シリアルポート」から確認できる項目と同じです。
多くの場合でCOMポート番号の変更のみで対応可能だと思います。

COMポート番号の確認はデバイスマネージャーなどから行ってください。

2.5 device_typeに指定する文字列

ssh_dispatcher.pyに定義されている CLASS_MAPPER辞書には、機種ごとの機能を備えたクラスが、
機種名をキーにマッピングされています。device_typeには、このキー名を指定します。
# 例
# SSH
CLASS_MAPPER['cisco_ios'] = CiscoIosSSH
CLASS_MAPPER['juniper_junos'] = JuniperSSH
CLASS_MAPPER['linux'] = LinuxSSH
# Telnet
CLASS_MAPPER['cisco_ios_telnet'] = CiscoIosTelnet
CLASS_MAPPER['juniper_junos_telnet'] = JuniperTelnet
# Serial
CLASS_MAPPER['cisco_ios_serial'] = CiscoIosSerial

3. 対応機種の追加方法

CLASS_MAPPER辞書に定義されていない機種に接続して netmikoを使用したい場合は、独自にクラスを定義して、CLASS_MAPPER辞書に追加する必要があります。

独自に定義するクラスは、base_connection.pyの BaseConnectionを継承します。
BaseConnectionの initメソッドで機器への接続を実施しており、
接続した時に、session_preparationメソッドを呼び出しています。
接続した際に実施する処理は、機器により異なる処理を実施するので、独自に定義するクラスでも、
session_preparationメソッドを定義し、機器に接続したときに実行される処理を実装します。
また、BaseConnectionクラスに定義されているメソッドで、独自の機器では、
異なるコマンドの実行や処理が必要な場合は、独自のクラス内でメソッドを上書きします。
# BaseConnectionのインポート
from netmiko.base_connection import BaseConnection

# BaseConnectionを継承したクラスを定義
class OriginalConnection(BaseConnection):

    def session_preparation(self):
        # 接続時に実行される処理を記載
        # ページング設定や、対象機種に正しく接続できたことを判定する処理を記載
        self.disable_paging()

    # ページング設定
    def disable_paging(self, command="original paging command", delay_factor=1):
        # 処理

    # 独自の処理を実行するメソッドを追加することも可能
    def original(self):
        # 処理

    # BaseConnectionに実装されているが使用しないメソッドは、使えないようにする
    def enable(self, *args, **kwargs):
        # 例外を発生させるようにしてもいい
        pass
独自のクラスを定義したら、機種一覧のリストと CLASS_MAPPER辞書に追加します。
機種名(CLASS_MAPPER辞書のキー)には、Telnet接続の場合は「_telnet」を、
シリアルポート接続の場合は「_serial」を付与します。
BaseConnectionが機器に接続する時、機種名に「_telnet」が含まれていればTelnet接続、
「_serial」が含まれていればシリアルポート接続、どちらも含まれていなければSSH接続を実施します。
from netmiko.ssh_dispatcher import platforms, CLASS_MAPPER

# 機種一覧に追加
platforms.append('original_telnet')
# マッピング辞書に追加
CLASS_MAPPER['original_telnet'] = OriginalConnection
クラスの作成と追加が出来たら、ConnectHandlerの引数 device_typeに独自の機種名を指定し、接続します。

4. まとめ

netmikoでは、リモート機器への接続を実施し、機器の操作補助を行うことが出来ます。
netmikoに標準では実装されていない機種でも、BaseConnectionを継承した独自のクラスを追加することで、
netmikoの機能を使用することが可能です。
リモート機器への接続自体は、下記Pythonライブラリで実施しています。
・SSH接続 :paramiko
・Telnet接続 :telnetlib
・シリアルポート接続:pyserial

投稿者: G.S