脱CLI!Pythonでネットワーク機器をAPI制御:RESTConf/NETConf入門
システムエンジニアやインフラエンジニアの皆様にとって、サーバーやクラウドインフラの自動化は日常的なタスクになっていることと思います。Pythonや各種ツールを用いて効率化を進める中で、ネットワーク機器の設定や状態取得についても自動化のニーズを感じていらっしゃるかもしれません。
しかし、ネットワーク機器の操作はSSH経由のCLIが主流であり、これは開発者にとって必ずしも親しみやすいインターフェースではないかもしれません。コマンドの多様性や機種ごとの差異がハードルとなる場合もあります。
本記事では、このような課題に対し、ネットワーク機器が提供するAPI(RESTConf、NETConf)を利用してPythonから自動化を行う方法を紹介します。CLI操作に比べてより構造的でプログラムから扱いやすいAPIを活用することで、Pythonスキルをネットワーク自動化にスムーズに活かすことが可能です。
ネットワーク機器APIとは?(RESTConf/NETConfの基本)
近年のネットワーク機器は、SSH/CLIだけでなく、APIインターフェースを提供するようになっています。代表的なものにRESTConfとNETConfがあります。これらは、ネットワーク機器の設定や運用情報をプログラムから取得・変更するための標準化されたプロトコルです。
-
NETConf (Network Configuration Protocol): XMLベースのプロトコルで、SSH上で動作することが一般的です。設定データの取得(get-config)、設定の編集(edit-config)、RPC呼び出し(operation)など、様々な操作を構造化された形式で行えます。冪等性(操作を何度行っても同じ結果になる性質)を考慮した設計がされており、自動化に向いています。
-
RESTConf: HTTP/HTTPS上で動作し、RESTfulな設計思想に基づいています。データ形式はJSONまたはXMLを使用します。Web APIに慣れている方にとっては、より直感的に扱えるかもしれません。URIでリソース(設定や状態)を指定し、GET, POST, PUT, PATCH, DELETEといったHTTPメソッドで操作を行います。
これらの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-config
やedit-config
といった標準的なRPC呼び出しに加え、特定の機器が提供するカスタムRPCを呼び出すことも可能です。NETConfではXMLとYANGモデルの理解がRESTConf以上に重要になります。
実践的な考慮事項
APIによるネットワーク自動化を現場で活用する際には、いくつかの考慮事項があります。
- エラーハンドリング: APIリクエストが失敗した場合(接続エラー、認証エラー、API固有のエラーコードなど)に適切に対応するコードが必要です。
requests
やncclient
は例外機構を提供しているため、これらを活用して堅牢なスクリプトを作成することが重要です。 - 認証情報の管理: スクリプト内に認証情報を直接記述するのではなく、環境変数や安全な設定管理システムから読み込むようにしてください。
- 冪等性:
PATCH
やedit-config
のような操作は冪等性を考慮して設計されていますが、POST
(リソース作成)や特定のRPC呼び出しは冪等でない場合があります。自動化ワークフロー全体で冪等性を担保するためには、操作の設計や実装に注意が必要です。例えば、設定を追加する前に存在確認を行うなどが考えられます。 - YANGモデルの理解: 対象機器がどのYANGモデルをサポートしているか、そのモデルの構造はどうなっているかを把握することが、正しいURIやXML/JSONペイロードを作成する上で不可欠です。機器のドキュメントを参照してください。
- API有効化とアクセス制御: ネットワーク機器側でRESTConf/NETConfが有効になっているか、またファイアウォール等で適切なポート(RESTConfは80/443、NETConfは830など)へのアクセスが許可されているか確認が必要です。
インフラ自動化全体の文脈におけるネットワークAPI自動化
ネットワーク機器のAPI自動化は、サーバーやクラウドを含めたインフラ自動化全体のワークフローに組み込むことで真価を発揮します。
- IaCツールとの連携: Ansible, Terraform, Chef, PuppetといったIaCツールから、Pythonスクリプトを呼び出す形でネットワーク設定を自動化できます。例えば、新しいサーバーをデプロイした際に、そのサーバーのIPアドレスに基づいてネットワーク機器のファイアウォール設定をAPI経由で自動追加する、といった連携が考えられます。AnsibleにはNETConfやRESTConfを直接操作するためのモジュールも存在します。
- CI/CDパイプラインへの組み込み: アプリケーションやインフラの変更をデプロイするCI/CDパイプラインに、ネットワーク設定の変更や状態チェックを自動化ステップとして組み込むことができます。
- 監視システムとの連携: ネットワーク機器からAPI経由で運用データを取得し、監視システムやログ分析基盤に取り込むことで、より高度な可視化や異常検知が可能になります。
このように、ネットワークAPI自動化は、Pythonスキルを持つエンジニアがインフラ全体の自動化に貢献するための強力な手段となります。
まとめ
本記事では、Pythonを使ってネットワーク機器をCLIではなくAPI(RESTConf/NETConf)で自動化する基本的なアプローチを紹介しました。requests
やncclient
といったライブラリを活用することで、Pythonが得意な構造化データの処理やWeb APIとの連携といったスキルをそのまま活かし、ネットワーク機器の操作を自動化できることをご理解いただけたかと思います。
CLI操作では難しかった複雑な設定の適用や、機器からの詳細な状態取得も、APIと適切なデータモデル(YANG)を使うことで、よりプログラムフレンドリーに実現可能です。
もちろん、実際の機器ではベンダー固有の実装差異やYANGモデルへの対応状況など、様々な考慮が必要になります。しかし、標準化されたAPIを活用することは、機種やベンダーに依存しない共通の自動化基盤を構築するための一歩となります。
まずは簡単な状態取得から試してみて、APIによるネットワーク自動化の世界に触れてみてはいかがでしょうか。