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

脱CLI!Pythonでネットワーク機器をAPI制御:RESTConf/NETConf入門

Tags: Python, ネットワーク自動化, API, RESTConf, NETConf

システムエンジニアやインフラエンジニアの皆様にとって、サーバーやクラウドインフラの自動化は日常的なタスクになっていることと思います。Pythonや各種ツールを用いて効率化を進める中で、ネットワーク機器の設定や状態取得についても自動化のニーズを感じていらっしゃるかもしれません。

しかし、ネットワーク機器の操作はSSH経由のCLIが主流であり、これは開発者にとって必ずしも親しみやすいインターフェースではないかもしれません。コマンドの多様性や機種ごとの差異がハードルとなる場合もあります。

本記事では、このような課題に対し、ネットワーク機器が提供するAPI(RESTConf、NETConf)を利用してPythonから自動化を行う方法を紹介します。CLI操作に比べてより構造的でプログラムから扱いやすいAPIを活用することで、Pythonスキルをネットワーク自動化にスムーズに活かすことが可能です。

ネットワーク機器APIとは?(RESTConf/NETConfの基本)

近年のネットワーク機器は、SSH/CLIだけでなく、APIインターフェースを提供するようになっています。代表的なものにRESTConfとNETConfがあります。これらは、ネットワーク機器の設定や運用情報をプログラムから取得・変更するための標準化されたプロトコルです。

これらのAPIは、YANG(Yet Another Next Generation)というデータモデリング言語で定義されたデータ構造に基づいて操作を行います。YANGは、設定データや運用データの構造を標準的に記述するための言語です。APIを利用する際は、対象機器がサポートしているYANGモデルを理解することが重要になります。

CLI操作はテキストベースの非構造データですが、RESTConf/NETConfは構造化されたデータ(XMLやJSON)を扱います。これにより、プログラムでのパースや操作が容易になり、自動化スクリプトの信頼性や保守性が向上します。

PythonでRESTConfを試す

RESTConfはHTTP/HTTPS上で動作するため、Python標準ライブラリのurllibや、より高機能なサードパーティライブラリであるrequestsを使って簡単に操作できます。ここではrequestsライブラリを使用した基本的な例を紹介します。

前提: * 対象のネットワーク機器がRESTConfを有効にしており、適切な認証情報(ユーザー名、パスワードなど)とAPIエンドポイントのURL(通常は /restconf パス以下)が分かっていること。 * requestsライブラリがインストールされていること (pip install requests)。

import requests
import json
import urllib3

# 警告の非表示 (検証環境などで証明書エラーを無視する場合。本番環境では適切に証明書を設定してください)
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# 接続情報
DEVICE_IP = "your_device_ip"
USERNAME = "your_username"
PASSWORD = "your_password"
RESTCONF_PORT = 443 # または 80 など機器による
BASE_URL = f"https://{DEVICE_IP}:{RESTCONF_PORT}/restconf" # HTTPSの場合

# ヘッダー情報
HEADERS = {
    "Content-Type": "application/yang-data+json", # または application/yang-data+xml
    "Accept": "application/yang-data+json" # または application/yang-data+xml
}

### 例1: インタフェース情報の取得 (GETリクエスト)
# 対象リソースのURIはYANGモデルと機器の実装に依存します
# 例: OpenConfigモデルのインタフェースリストを取得する場合
interface_list_uri = f"{BASE_URL}/data/openconfig-interfaces:interfaces"

try:
    response = requests.get(
        interface_list_uri,
        headers=HEADERS,
        auth=(USERNAME, PASSWORD),
        verify=False # SSL証明書検証を無効化 (検証用途のみ)
    )

    # レスポンスステータスコードの確認
    response.raise_for_status() # 200番台以外の場合は例外発生

    # 取得したデータをJSONとしてパース
    interface_data = response.json()
    print("--- インタフェース情報 ---")
    print(json.dumps(interface_data, indent=2))

except requests.exceptions.RequestException as e:
    print(f"APIリクエストエラー: {e}")

### 例2: インタフェースの説明文を変更 (PATCHリクエスト)
# 変更したい特定のインタフェースリソースのURIと変更内容(JSONまたはXML)を指定
# 例: GigabitEthernet1の説明文を変更する場合 (URIとデータ構造は例です)
interface_name = "GigabitEthernet1"
interface_config_uri = f"{BASE_URL}/data/openconfig-interfaces:interfaces/interface={interface_name}/config"

# 変更内容をJSON形式で定義 (YANGモデルに従う必要があります)
# 例: {"openconfig-interfaces:description": "Managed by Python Script"}
update_payload = {
    "openconfig-interfaces:description": "Managed by Python Script via RESTConf"
}

try:
    response = requests.patch(
        interface_config_uri,
        headers=HEADERS,
        auth=(USERNAME, PASSWORD),
        data=json.dumps(update_payload),
        verify=False # SSL証明書検証を無効化 (検証用途のみ)
    )

    response.raise_for_status()

    print(f"\n--- インタフェース {interface_name} の説明文変更 ---")
    if response.status_code == 204: # 変更成功時はNo Content (204) が返る場合が多い
        print("設定が正常に変更されました。")
    else:
        print(f"設定変更リクエスト成功。ステータスコード: {response.status_code}")
        # 必要に応じてレスポンスボディを確認
        # print("レスポンスボディ:", response.text)

except requests.exceptions.RequestException as e:
    print(f"APIリクエストエラー: {e}")

この例では、requests.getで情報を取得し、requests.patchで設定の一部を変更しています。HTTPメソッドとURI、そして適切なヘッダーとボディを用意すれば、多くの操作が可能です。重要なのは、対象機器のRESTConfドキュメントやYANGモデルを参照し、正しいURIとデータ構造を把握することです。

PythonでNETConfを試す

NETConfをPythonから扱うには、ncclientのようなライブラリを利用するのが一般的です。ncclientはSSH接続の確立から、NETConfメッセージの送受信、XMLのパースまでを抽象化してくれます。

前提: * 対象のネットワーク機器がNETConfを有効にしており、適切な認証情報(ユーザー名、パスワード)が分かっていること。 * ncclientライブラリがインストールされていること (pip install ncclient)。

from ncclient import manager
import xml.dom.minidom

# 接続情報
DEVICE_IP = "your_device_ip"
USERNAME = "your_username"
PASSWORD = "your_password"
NETCONF_PORT = 830 # NETConfの標準ポート

### 例3: running-configの取得 (get-config RPC)
try:
    # NETConfセッションの確立
    # host, port, username, passwordを指定
    # device_params={'name':'default'} または 'cisco_iosxe', 'huawei' など機器に合わせて指定
    with manager.connect(
        host=DEVICE_IP,
        port=NETCONF_PORT,
        username=USERNAME,
        password=PASSWORD,
        device_params={'name':'default'}, # 適切なデバイスタイプを指定
        allow_agent=False,
        look_for_keys=False
    ) as m:

        print("--- NETConfセッション確立 ---")

        # get-config RPCの実行
        # source='running' でrunning-configを取得
        result = m.get_config(source='running')

        # 結果はXMLオブジェクトとして返されるため、文字列に変換して整形表示
        xml_output = xml.dom.minidom.parseString(result.xml)
        print("--- running-config ---")
        print(xml_output.toprettyxml(indent="  "))

except Exception as e:
    print(f"NETConf操作エラー: {e}")

### 例4: 簡単な設定変更 (edit-config RPC)
# 変更内容をNETConf形式のXMLで定義
# 例: 特定のNTPサーバーを設定する場合 (XML構造は例です)
config_payload = """
<config>
  <system xmlns="urn:ietf:params:xml:ns:yang:ietf-system">
    <ntp>
      <server>
        <name>pool.ntp.org</name>
        <address>pool.ntp.org</address>
        <prefer>true</prefer>
      </server>
    </ntp>
  </system>
</config>
"""

try:
    with manager.connect(
        host=DEVICE_IP,
        port=NETCONF_PORT,
        username=USERNAME,
        password=PASSWORD,
        device_params={'name':'default'}, # 適切なデバイスタイプを指定
        allow_agent=False,
        look_for_keys=False
    ) as m:

        print("\n--- 設定変更リクエスト ---")

        # edit-config RPCの実行
        # target='running' でrunning-configを変更
        # config=config_payload で変更内容を指定
        result = m.edit_config(target='running', config=config_payload)

        print("設定変更結果:", result) # 結果はOKレスポンスなど

except Exception as e:
    print(f"NETConf操作エラー: {e}")

ncclientを使うことで、NETConfのXMLメッセージの組み立てや送受信をPythonコードで行えます。get-configedit-configといった標準的なRPC呼び出しに加え、特定の機器が提供するカスタムRPCを呼び出すことも可能です。NETConfではXMLとYANGモデルの理解がRESTConf以上に重要になります。

実践的な考慮事項

APIによるネットワーク自動化を現場で活用する際には、いくつかの考慮事項があります。

インフラ自動化全体の文脈におけるネットワークAPI自動化

ネットワーク機器のAPI自動化は、サーバーやクラウドを含めたインフラ自動化全体のワークフローに組み込むことで真価を発揮します。

このように、ネットワークAPI自動化は、Pythonスキルを持つエンジニアがインフラ全体の自動化に貢献するための強力な手段となります。

まとめ

本記事では、Pythonを使ってネットワーク機器をCLIではなくAPI(RESTConf/NETConf)で自動化する基本的なアプローチを紹介しました。requestsncclientといったライブラリを活用することで、Pythonが得意な構造化データの処理やWeb APIとの連携といったスキルをそのまま活かし、ネットワーク機器の操作を自動化できることをご理解いただけたかと思います。

CLI操作では難しかった複雑な設定の適用や、機器からの詳細な状態取得も、APIと適切なデータモデル(YANG)を使うことで、よりプログラムフレンドリーに実現可能です。

もちろん、実際の機器ではベンダー固有の実装差異やYANGモデルへの対応状況など、様々な考慮が必要になります。しかし、標準化されたAPIを活用することは、機種やベンダーに依存しない共通の自動化基盤を構築するための一歩となります。

まずは簡単な状態取得から試してみて、APIによるネットワーク自動化の世界に触れてみてはいかがでしょうか。