CML遠隔構築支援システム ツールマニュアル
1. 概要
このツール群は、Cisco Modeling Labsのラボ作成、トポロジ編集、設定投入、状態取得、CLI検証を小さな単機能コマンドとして実行するためのものです。
1つのツールは1つの目的に集中し、結果は依頼フォルダ内の results/ と logs/ に保存します。
ラボ作成、ノード追加、リンク追加、状態取得などを分けて実行します。
実行結果はJSON、ログはJSON Lines形式で保存します。
依頼フォルダと設定ファイルを中心に、同じ操作を追跡できます。
2. 共通の実行形式
ほとんどのツールは、最初の引数に依頼フォルダを指定します。 CMLへ接続するツールは、実行時にユーザー名とパスワードを入力します。
.\.venv\Scripts\python.exe .\tools\<TOOL_NAME>.py .\requests\<REQUEST_FOLDER> [options]
| 共通引数 | 対象 | 説明 |
|---|---|---|
folder |
多くのツール | 依頼フォルダのパス。例: .\requests\20260712_pair_router_lab |
--username |
CML API / SSH接続ツール | CMLユーザー名。省略すると入力プロンプトが表示されます。 |
--use-env |
CML API / SSH接続ツール | 環境変数から認証情報を読む場合に指定します。通常利用では省略できます。 |
--username-env / --password-env |
CML API / SSH接続ツール | --use-env 使用時に参照する環境変数名を指定します。 |
--insecure |
CML API接続ツール | TLS証明書検証を無効化します。検証環境など、自己署名証明書の場合に使います。 |
--timeout |
CML API / SSH接続ツール | 接続タイムアウト秒数。既定値は多くのツールで10秒です。 |
<CML_HOST>、<USERNAME>、<LAB_ID>、<NODE_ID>、<INTERFACE_ID> は実行時に実値へ置き換えてください。
3. 依頼フォルダ管理ツール
| ツール | 機能 | 主要引数 | 出力 |
|---|---|---|---|
create_request_folder.py |
依頼フォルダのひな形を作成します。 | slug、--title、--summary、--cml-host、--requests-dir、--date |
request.md、metadata.yaml、cml-lab.yaml、backups/、logs/、results/ |
validate_request_folder.py |
依頼フォルダの構成と主要項目を検証します。 | folder |
標準出力に検証結果を表示します。 |
link_existing_lab.py |
既存CMLラボを依頼フォルダへ紐付けます。 | folder、--lab-id または --lab-title |
metadata.yaml と cml-lab.yaml のラボ情報を更新します。 |
.\.venv\Scripts\python.exe .\tools\create_request_folder.py pair_router_lab --title pair_router_lab --summary "Two-router point-to-point lab." --cml-host <CML_HOST>
4. CML接続・参照ツール
| ツール | 機能 | 主要引数 | 出力先 |
|---|---|---|---|
check_cml_connection.py |
CML Controllerへ認証し、接続可能かを確認します。 | folder、--endpoint、共通認証引数 |
results/cml_connection.json、logs/cml_connection.jsonl |
list_cml_labs.py |
見えるラボの一覧を取得します。 | folder、--show-all、--no-details、共通認証引数 |
results/cml_labs.json、logs/cml_labs.jsonl |
get_cml_resources.py |
CMLのライセンスやリソース利用状況を取得します。 | folder、共通認証引数 |
results/cml_resources.json、logs/cml_resources.jsonl |
list_node_definitions.py |
利用可能なノード定義とイメージ定義を取得します。 | folder、共通認証引数 |
results/cml_node_definitions.json、logs/cml_node_definitions.jsonl |
5. ラボ操作ツール
| ツール | 機能 | 主要引数 | 出力先 |
|---|---|---|---|
create_lab.py |
依頼フォルダに対応するCMLラボを新規作成します。 | folder、--notes、共通認証引数 |
results/created_lab.json、logs/created_lab.jsonl |
start_lab.py |
紐付け済みラボを起動します。 | folder、--wait、--max-wait-seconds、共通認証引数 |
results/started_lab.json、logs/started_lab.jsonl |
stop_lab.py |
紐付け済みラボを停止します。 | folder、共通認証引数 |
results/stopped_lab.json、logs/stopped_lab.jsonl |
delete_lab.py |
紐付け済みラボを削除します。 | folder、--confirm-title、共通認証引数 |
results/deleted_lab.json、logs/deleted_lab.jsonl |
delete_lab.py は破壊的操作です。--confirm-title には、削除対象ラボのタイトルを完全一致で指定する必要があります。
6. トポロジ編集ツール
| ツール | 機能 | 主要引数 | 出力先 |
|---|---|---|---|
add_node.py |
ラボにノードを1台追加します。 | --label、--node-definition、--image-definition、--x、--y、--ram、--cpus、--cpu-limit、--tag、--config-file |
results/added_node_<LABEL>.json、logs/added_nodes.jsonl |
add_interface.py |
ノードにインターフェースを1つ追加します。 | --node-id、--slot、--mac-address |
results/added_interface_<INTERFACE_ID>.json、logs/added_interfaces.jsonl |
add_link.py |
2つのインターフェース間にリンクを1本作成します。 | --src-interface-id、--dst-interface-id |
results/added_link_<LINK_ID>.json、logs/added_links.jsonl |
delete_node.py |
ノードを1台削除します。 | --node-id、--confirm-node-id |
results/deleted_node_<NODE_ID>.json、logs/deleted_nodes.jsonl |
add_interface.py や add_link.py では、直前の結果JSONからノードIDやインターフェースIDを確認して次のコマンドへ渡します。
7. 設定投入・CLI検証ツール
| ツール | 機能 | 主要引数 | 出力先 |
|---|---|---|---|
set_node_config.py |
ノードへ起動時コンフィグを設定します。 | --node-id、--config-file |
results/set_node_config_<NODE_ID>.json、logs/set_node_config.jsonl |
run_console_command.py |
CML SSHコンソールサーバー経由でノード上のコマンドを1つ実行します。 | --node-label、--line、--command、--host、--port、--enable、--enable-password |
results/console_*.json、logs/console_commands.jsonl |
get_pyats_testbed.py |
CMLが生成するpyATS testbed YAMLを保存します。 | --hostname、共通認証引数 |
results/pyats_testbed.yaml、logs/pyats_testbed.jsonl |
write_verification_report.py |
検証レポートをJSONとMarkdownで作成します。 | folder |
results/verification_report.json、results/verification_report.md |
run_console_command.py の並列実行は、コンソール出力が混ざることがあります。同一ノードのCLI確認は直列実行を推奨します。
8. 状態取得ツール
| ツール | 機能 | 主要引数 | 出力先 |
|---|---|---|---|
get_lab_status.py |
ラボの起動状態を取得します。 | folder、共通認証引数 |
results/cml_lab_status.json、logs/cml_lab_status.jsonl |
get_lab_topology.py |
ノード、リンク、インターフェースを含むトポロジを取得します。 | folder、共通認証引数 |
results/cml_lab_topology.json、logs/cml_lab_topology.jsonl |
get_lab_element_state.py |
ラボ内要素の状態を取得します。 | folder、共通認証引数 |
results/cml_lab_element_state.json、logs/cml_lab_element_state.jsonl |
get_lab_events.py |
ラボイベントを取得します。 | folder、共通認証引数 |
results/cml_lab_events.json、logs/cml_lab_events.jsonl |
get_l3_addresses.py |
CMLが認識しているL3アドレスを取得します。 | folder、共通認証引数 |
results/cml_l3_addresses.json、logs/cml_l3_addresses.jsonl |
get_node.py |
指定ノードの詳細を取得します。 | --node-id、共通認証引数 |
results/cml_node_<NODE_ID>.json、logs/cml_nodes.jsonl |
9. ワークフロー補助ツール
| ツール | 機能 | 主要引数 | 出力先 |
|---|---|---|---|
run_workflow.py |
cml-lab.yaml の operations を読み、実行予定を表示・保存します。 |
folder、--all、--dry-run、--run-auto-safe |
results/workflow_plan.json、results/workflow_run.json、logs/workflow.jsonl |
cml_common.py |
認証、API呼び出し、JSON保存、ログ追記などの共通処理を提供します。 | 直接実行しません。 | 各ツールから利用されます。 |
.\.venv\Scripts\python.exe .\tools\run_workflow.py .\requests\<REQUEST_FOLDER> --dry-run
10. チュートリアル: 1対向ルーターの新規ラボを作成する
このチュートリアルでは、R1とR2を1本のリンクで接続し、R1からR2へpingできる新規ラボを作成します。 ノード定義やイメージ定義は利用環境に合わせて置き換えてください。
10.1 完成イメージ
| 項目 | 値 |
|---|---|
| ラボ名 | pair_router_lab |
| ノード | R1、R2 |
| リンク | R1 Ethernet0/0 - R2 Ethernet0/0 |
| IPアドレス | R1: 10.0.12.1/30、R2: 10.0.12.2/30 |
| 確認 | R1 から 10.0.12.2 へping |
10.2 依頼フォルダを作成する
.\.venv\Scripts\python.exe .\tools\create_request_folder.py pair_router_lab --title pair_router_lab --summary "Two routers connected point-to-point." --cml-host <CML_HOST>
作成されたフォルダを以後 .\requests\<DATE>_pair_router_lab と表記します。
| 表記 | 意味 | 例 |
|---|---|---|
<DATE> |
依頼フォルダ名の先頭に付く作成日です。create_request_folder.py 実行時に表示される folder: の値で確認します。 |
20260712 |
<CML_HOST> |
CML Controllerのホスト名またはIPアドレスです。利用環境の値を指定します。 | cml.example.local |
.\.venv\Scripts\python.exe .\tools\validate_request_folder.py .\requests\<DATE>_pair_router_lab
10.3 CML接続と利用可能イメージを確認する
.\.venv\Scripts\python.exe .\tools\check_cml_connection.py .\requests\<DATE>_pair_router_lab --insecure
.\.venv\Scripts\python.exe .\tools\list_node_definitions.py .\requests\<DATE>_pair_router_lab --insecure
list_node_definitions.py の結果から、利用する --node-definition と --image-definition を決めます。
| 指定値 | 意味 | 確認方法 | 指定例 |
|---|---|---|---|
<NODE_DEFINITION> |
CML上の機器種別です。ルーター、スイッチ、サーバーなど、どの種類のノードを作るかを指定します。 | results/cml_node_definitions.json のノード定義名から選びます。 |
iol-xe |
<IMAGE_DEFINITION> |
そのノードで起動するOSイメージです。指定したノード定義に対応するイメージを選びます。 | results/cml_node_definitions.json のイメージ定義名から選びます。 |
iol-xe-17-16-01a |
iol-xe と iol-xe-17-16-01a がある環境では、この組み合わせを使用できます。
別のルーターイメージを使う場合は、list_node_definitions.py の結果に表示された値へ置き換えてください。
10.4 コンフィグを用意する
configs/ フォルダを作成し、R1/R2の設定ファイルを配置します。
.\requests\<DATE>_pair_router_lab\configs\R1.cfg
hostname R1
!
interface Ethernet0/0
ip address 10.0.12.1 255.255.255.252
no shutdown
!
line vty 0 4
login local
transport input ssh
!
end
.\requests\<DATE>_pair_router_lab\configs\R2.cfg
hostname R2
!
interface Ethernet0/0
ip address 10.0.12.2 255.255.255.252
no shutdown
!
line vty 0 4
login local
transport input ssh
!
end
10.5 CMLラボを作成する
.\.venv\Scripts\python.exe .\tools\create_lab.py .\requests\<DATE>_pair_router_lab --insecure
実行後、results/created_lab.json にラボIDが保存され、metadata.yaml と cml-lab.yaml に紐付け情報が反映されます。
10.6 R1とR2を追加する
<NODE_DEFINITION> には機器種別、<IMAGE_DEFINITION> にはOSイメージ名を入れます。
例として iol-xe / iol-xe-17-16-01a を使う場合は、次のように指定します。
.\.venv\Scripts\python.exe .\tools\add_node.py .\requests\<DATE>_pair_router_lab --insecure --label R1 --node-definition <NODE_DEFINITION> --image-definition <IMAGE_DEFINITION> --x -150 --y 0
.\.venv\Scripts\python.exe .\tools\add_node.py .\requests\<DATE>_pair_router_lab --insecure --label R2 --node-definition <NODE_DEFINITION> --image-definition <IMAGE_DEFINITION> --x 150 --y 0
.\.venv\Scripts\python.exe .\tools\add_node.py .\requests\<DATE>_pair_router_lab --insecure --label R1 --node-definition iol-xe --image-definition iol-xe-17-16-01a --x -150 --y 0
.\.venv\Scripts\python.exe .\tools\add_node.py .\requests\<DATE>_pair_router_lab --insecure --label R2 --node-definition iol-xe --image-definition iol-xe-17-16-01a --x 150 --y 0
results/added_node_R1.json と results/added_node_R2.json から、それぞれの node_id を確認します。
| 表記 | 取得元 | 見る項目 | 例 |
|---|---|---|---|
<R1_NODE_ID> |
results/added_node_R1.json |
response.id |
11111111-1111-4111-8111-111111111111 |
<R2_NODE_ID> |
results/added_node_R2.json |
response.id |
22222222-2222-4222-8222-222222222222 |
たとえば added_node_R1.json は次のような形です。この場合、response の中の id を <R1_NODE_ID> として使います。
{
"label": "R1",
"response": {
"id": "11111111-1111-4111-8111-111111111111"
}
}
10.7 インターフェースを追加する
.\.venv\Scripts\python.exe .\tools\add_interface.py .\requests\<DATE>_pair_router_lab --insecure --node-id <R1_NODE_ID> --slot 0
.\.venv\Scripts\python.exe .\tools\add_interface.py .\requests\<DATE>_pair_router_lab --insecure --node-id <R2_NODE_ID> --slot 0
各コマンドの結果JSONから interface_id を確認します。
| 表記 | 取得元 | 見る項目 | 例 |
|---|---|---|---|
<R1_INTERFACE_ID> |
R1に対する results/added_interface_*.json |
interfaces[0].id |
aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa |
<R2_INTERFACE_ID> |
R2に対する results/added_interface_*.json |
interfaces[0].id |
bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb |
たとえば added_interface_*.json は次のような形です。この場合、interfaces 配列の先頭にある id をリンク作成時に使います。
{
"node_id": "11111111-1111-4111-8111-111111111111",
"interfaces": [
{
"id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
"label": "Ethernet0/0",
"slot": 0
}
]
}
10.8 R1とR2をリンクで接続する
10.7で確認した <R1_INTERFACE_ID> と <R2_INTERFACE_ID> を指定して、2つのインターフェースを接続します。
.\.venv\Scripts\python.exe .\tools\add_link.py .\requests\<DATE>_pair_router_lab --insecure --src-interface-id <R1_INTERFACE_ID> --dst-interface-id <R2_INTERFACE_ID>
.\.venv\Scripts\python.exe .\tools\add_link.py .\requests\<DATE>_pair_router_lab --insecure --src-interface-id aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa --dst-interface-id bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb
10.9 コンフィグを投入する
10.6で確認した <R1_NODE_ID> と <R2_NODE_ID> を使って、各ノードへ対応するコンフィグを投入します。
.\.venv\Scripts\python.exe .\tools\set_node_config.py .\requests\<DATE>_pair_router_lab --insecure --node-id <R1_NODE_ID> --config-file .\requests\<DATE>_pair_router_lab\configs\R1.cfg
.\.venv\Scripts\python.exe .\tools\set_node_config.py .\requests\<DATE>_pair_router_lab --insecure --node-id <R2_NODE_ID> --config-file .\requests\<DATE>_pair_router_lab\configs\R2.cfg
.\.venv\Scripts\python.exe .\tools\set_node_config.py .\requests\<DATE>_pair_router_lab --insecure --node-id 11111111-1111-4111-8111-111111111111 --config-file .\requests\<DATE>_pair_router_lab\configs\R1.cfg
.\.venv\Scripts\python.exe .\tools\set_node_config.py .\requests\<DATE>_pair_router_lab --insecure --node-id 22222222-2222-4222-8222-222222222222 --config-file .\requests\<DATE>_pair_router_lab\configs\R2.cfg
10.10 ラボを起動する
.\.venv\Scripts\python.exe .\tools\start_lab.py .\requests\<DATE>_pair_router_lab --insecure --wait
起動後、get_lab_status.py、get_lab_topology.py、get_l3_addresses.py で状態を保存します。
さらに、10.12の検証レポートでR1/R2の起動状態を判定するため、get_node.py で各ノードの詳細も保存します。
.\.venv\Scripts\python.exe .\tools\get_lab_status.py .\requests\<DATE>_pair_router_lab --insecure
.\.venv\Scripts\python.exe .\tools\get_lab_topology.py .\requests\<DATE>_pair_router_lab --insecure
.\.venv\Scripts\python.exe .\tools\get_l3_addresses.py .\requests\<DATE>_pair_router_lab --insecure
.\.venv\Scripts\python.exe .\tools\get_node.py .\requests\<DATE>_pair_router_lab --insecure --node-id <R1_NODE_ID>
.\.venv\Scripts\python.exe .\tools\get_node.py .\requests\<DATE>_pair_router_lab --insecure --node-id <R2_NODE_ID>
.\.venv\Scripts\python.exe .\tools\get_node.py .\requests\<DATE>_pair_router_lab --insecure --node-id 11111111-1111-4111-8111-111111111111
.\.venv\Scripts\python.exe .\tools\get_node.py .\requests\<DATE>_pair_router_lab --insecure --node-id 22222222-2222-4222-8222-222222222222
10.11 CLIで疎通を確認する
<CML_HOST> には10.2で指定したCML Controllerのホスト名またはIPアドレスを入れます。
--node-label R1 はノード追加時に指定したラベルです。
.\.venv\Scripts\python.exe .\tools\run_console_command.py .\requests\<DATE>_pair_router_lab --host <CML_HOST> --node-label R1 --command "show ip interface brief"
.\.venv\Scripts\python.exe .\tools\run_console_command.py .\requests\<DATE>_pair_router_lab --host <CML_HOST> --node-label R1 --command "ping 10.0.12.2 repeat 5"
結果は results/console_R1_show_ip_interface_brief.json や results/console_R1_ping_10.0.12.2_repeat_5.json に保存されます。
10.12 結果をまとめる
write_verification_report.py は、10.10と10.11で保存した結果ファイルを読み込んで判定します。
特に r1_booted と r2_booted は、get_node.py の結果である results/cml_node_*.json が必要です。
.\.venv\Scripts\python.exe .\tools\write_verification_report.py .\requests\<DATE>_pair_router_lab
レポートは results/verification_report.md と results/verification_report.json に保存されます。
11. よくある確認ポイント
| 状況 | 確認するファイル・ツール |
|---|---|
| ラボIDが分からない | metadata.yaml、cml-lab.yaml、results/created_lab.json |
| ノードIDが分からない | results/added_node_*.json、または get_lab_topology.py |
| インターフェースIDが分からない | results/added_interface_*.json、または get_lab_topology.py |
| 起動状態を確認したい | get_lab_status.py、get_lab_element_state.py |
| 疎通確認したい | run_console_command.py でpingやtracerouteを実行します。 |
| 削除したい | delete_lab.py を使います。必ず削除対象がテスト用ラボであることを確認してください。 |