実践ネット自動化スクリプト集

構造化データでネットワーク状態をチェック:Python/NAPALM実践入門

Tags: Python, ネットワーク自動化, NAPALM, 構造化データ, 状態検証

はじめに:なぜネットワーク機器の状態チェックを自動化するのか

システムやインフラの運用において、ネットワーク機器の状態はサービス提供の安定性に直結します。しかし、多くのネットワーク機器は、その状態確認にCLI(Command Line Interface)操作を必要とします。CLI操作は対話的で直感的である反面、自動化や大規模な運用には向きません。手動での確認は時間と手間がかかり、ヒューマンエラーの原因にもなり得ます。

特に、開発ライフサイクルやインフラ自動化の文脈でインフラに関わるエンジニアにとって、ネットワーク機器のCLI操作は必ずしも得意分野ではないかもしれません。しかし、CI/CDパイプラインにネットワークの変更を組み込んだり、デプロイ後のネットワーク状態を自動で検証したりといったニーズは高まっています。

ここでPythonの出番です。Pythonは豊富なライブラリによって、様々なネットワーク機器との連携を自動化する手段を提供します。NetmikoのようなライブラリはCLI操作を自動化するのに役立ちますが、取得したテキストデータを自分でパースする必要があります。これに対し、NAPALMはネットワーク機器から構造化されたデータ(通常はJSON形式)を取得することに特化したライブラリです。構造化データであれば、Pythonでの処理や検証が容易になります。

本記事では、PythonライブラリNAPALMを使用して、ネットワーク機器から構造化データを取得し、そのデータを利用してネットワークの状態を自動的に検証する基本的な手法について解説します。

NAPALMとは:構造化データ取得に特化したライブラリ

NAPALM (Network Automation and Programmability Abstraction Layer with Multivendor support) は、異なるネットワーク機器ベンダーに対して、共通のPythonオブジェクトインターフェースを提供するライブラリです。主な目的は、機器の状態を標準化された方法で取得すること、そして設定の読み込みや差分表示を行うことです。

NAPALMの重要な特徴は以下の通りです。

Netmikoが「仮想的なターミナルを開いてコマンドを打ち、その出力を受け取る」イメージだとすれば、NAPALMは「機器に対して『状態を教えて』と尋ね、定義された形式で回答を受け取る」イメージです。ネットワーク機器のコマンド構文に詳しくなくても、Pythonのデータ構造として情報を扱えるため、開発者にとっては馴染みやすいアプローチと言えます。

環境準備と基本的な接続

NAPALMを利用するための環境準備は比較的容易です。Pythonがインストールされている環境で、pipを使ってNAPALMと対象ベンダーのドライバー、そして依存するライブラリ(多くの場合Netmikoなど)をインストールします。

pip install napalm napalm-ios # 例: Cisco IOSXE/IOS向け
pip install napalm napalm-junos # 例: Juniper Junos向け
# 必要に応じて他のベンダー向けドライバーもインストール

インストールが完了したら、機器への基本的な接続を確認してみましょう。以下のコードは、Cisco IOSXE機器に接続し、ファクト情報を取得する例です。

from napalm import get_network_driver
import json

# 接続設定
hostname = "YOUR_DEVICE_IP_OR_HOSTNAME"
username = "YOUR_USERNAME"
password = "YOUR_PASSWORD"
optional_args = {} # 必要に応じてSSHポートなどを指定することも可能

# デバイスタイプを指定 (例: ios, junos, eos, nxosなど)
driver = get_network_driver("ios")

try:
    # 機器に接続
    device = driver(hostname=hostname, username=username, password=password, optional_args=optional_args)
    print(f"Connecting to {hostname}...")
    device.open()
    print("Connection successful.")

    # ファクト情報を取得
    # get_facts()は機器の基本的な情報(ホスト名、OSバージョン、シリアル番号など)を返します
    facts = device.get_facts()

    # 取得した構造化データを表示 (見やすくするためにJSON形式で出力)
    print("\n--- Device Facts ---")
    print(json.dumps(facts, indent=2))

    # その他の情報を取得することも可能 (例: インターフェース情報)
    # interfaces = device.get_interfaces()
    # print("\n--- Interfaces ---")
    # print(json.dumps(interfaces, indent=2))

except Exception as e:
    print(f"An error occurred: {e}")

finally:
    # 接続を閉じる
    if 'device' in locals() and device.is_open():
        device.close()
        print("Connection closed.")

このコードを実行すると、指定した機器にSSHで接続し、get_facts()というNAPALMの共通メソッドを使って情報を取得できます。取得されるデータはPythonの辞書形式であり、非常に扱いやすい形式であることがわかります。

ネットワーク状態の構造化データ取得

NAPALMには、機器の様々な状態を取得するための多くの「getter」メソッドが用意されています。これらのメソッドは、ベンダーに関わらず共通の名前と、(可能な限り)共通の出力データ構造を持っています。

状態検証に役立つ代表的なgetterメソッドには以下のようなものがあります。

これらのメソッドは、それぞれ定義された構造でデータを返します。例えば、get_interfaces()はインターフェース名をキーとする辞書を返し、各インターフェースの値はさらに詳細な情報を含む辞書となっています。

# get_interfaces() の出力例 (一部抜粋、実際の出力はベンダーにより若干異なる可能性があります)
{
  "GigabitEthernet1": {
    "is_up": true,
    "is_enabled": true,
    "description": "To Server Farm",
    "last_flapped": 1678886400.0,
    "speed": 1000,
    "mtu": 1500,
    "mac_address": "AABB.CCDD.EEFF",
    "physical_address": "AABB.CCDD.EEFF",
    "type": "ethernet",
    "speed": 1000,
    "counters": {
      "tx_bytes": 1000000000,
      "rx_bytes": 2000000000,
      "tx_unicast_packets": 1000000,
      "rx_unicast_packets": 2000000,
      "tx_multicast_packets": 10000,
      "rx_multicast_packets": 20000,
      "tx_broadcast_packets": 1000,
      "rx_broadcast_packets": 2000,
      "tx_discards": 0,
      "rx_discards": 0,
      "tx_errors": 0,
      "rx_errors": 0
    }
  },
  "Loopback0": {
    "is_up": true,
    "is_enabled": true,
    "description": "Router ID",
    "last_flapped": -1.0, # -1 はフラップなしを示すことが多い
    "speed": -1.0,
    "mtu": 1514,
    "mac_address": "", # LoopbackインターフェースにはMACアドレスがない
    "physical_address": "",
    "type": "software_loopback",
    "counters": { ... } # カウンター情報
  }
}

このような構造化データが得られれば、特定のインターフェースの状態(is_up, is_enabled)や統計情報(counters)を簡単に参照できます。

取得した構造化データを用いた状態検証

取得した構造化データをPythonの辞書やリストとして扱うことで、様々な状態検証ロジックを実装できます。例えば、「特定のインターフェースがUPしているか」「すべてのBGPネイバーがEstablished状態になっているか」「特定のルートがルーティングテーブルに存在するか」といったチェックを行うスクリプトを作成できます。

以下は、get_interfaces()で取得したデータを使って、特定のインターフェースが物理的・論理的にUPしているかを確認する例です。

# 前提: device = driver(...) として接続済みのNAPALMデバイスオブジェクトが存在する

try:
    interfaces = device.get_interfaces()
    print(json.dumps(interfaces, indent=2)) # 取得データを確認

    # 検証したいインターフェース名と期待する状態
    target_interface = "GigabitEthernet1" # 例
    expected_state = {"is_up": True, "is_enabled": True}

    if target_interface in interfaces:
        interface_state = interfaces[target_interface]
        print(f"\n--- Verifying state for {target_interface} ---")

        is_ok = True
        for key, expected_value in expected_state.items():
            actual_value = interface_state.get(key)
            if actual_value is not expected_value:
                print(f"  FAIL: {target_interface} {key} is {actual_value}, expected {expected_value}")
                is_ok = False
            else:
                 print(f"  PASS: {target_interface} {key} is {actual_value}")

        if is_ok:
            print(f"Verification successful for {target_interface}.")
        else:
            print(f"Verification failed for {target_interface}.")

    else:
        print(f"Error: Interface '{target_interface}' not found on the device.")

except Exception as e:
    print(f"An error occurred during verification: {e}")

このように、Pythonの標準的なデータ構造操作や条件分岐を使って、簡単に検証ロジックを記述できます。

さらに進んで、pytestのようなテストフレームワークと連携させることで、より体系的な状態検証テストスイートを構築することも可能です。ネットワークの状態をコードとして定義し、CI/CDパイプラインの一部として自動実行することで、デプロイや設定変更後のネットワークの状態を保証できます。

実践的な考慮点

NAPALMを使ったネットワーク自動化を現場で活用する際には、いくつかの考慮点があります。

まとめ

本記事では、PythonライブラリNAPALMを用いたネットワーク機器の状態検証自動化の基本的な手法について解説しました。NAPALMを利用することで、CLIコマンドの出力をパースする手間なく、ベンダーに依存しない統一的な方法でネットワーク機器の情報を構造化データとして取得できます。

取得した構造化データはPythonでの処理が容易であり、これにより「特定のインターフェースがUPしているか」「BGPネイバーが確立しているか」といった様々な状態チェックを自動化できます。これは、インフラ自動化やIaCの文脈で、ネットワークの状態をプログラム可能な形で管理し、検証するための強力な手段となります。

手動での確認に依存しているネットワーク機器の状態管理を、PythonとNAPALMを使って自動化することで、運用効率の向上、ミスの削減、そしてより信頼性の高いシステム運用を実現することが期待できます。ぜひ、ご自身の環境でNAPALMを試してみて、ネットワーク状態の自動検証を実践してみてください。