この記事はシスコの有志による Cisco Systems Japan Advent Calendar 2024 一枚目の 5 日目として投稿しています。
過去のアドベントカレンダーも是非覗いてみてください。
2023年版: https://qiita.com/advent-calendar/2023/cisco
2022年版: https://qiita.com/advent-calendar/2022/cisco
2021年版: https://qiita.com/advent-calendar/2021/cisco
2021年版(2枚目): https://https://qiita.com/advent-calendar/2021/cisco2
2020年版: https://qiita.com/advent-calendar/2020/cisco
2020年版(2枚目): https://qiita.com/advent-calendar/2020/cisco2
2019年版: https://qiita.com/advent-calendar/2019/cisco
2018年版: https://qiita.com/advent-calendar/2018/cisco
2017年版: https://qiita.com/advent-calendar/2017/cisco
はじめに
今回の記事は2019年に書いた下記記事の最新版になります。当初の pyATS Blitz から進化を遂げ、実装変更により内容が古くなってしまっていたので、書き直すことにしました。
内容が少し pyATS を知っている前提になっているため、私の下記過去記事もぜひ参考にしてください。
pyATS Blitzとは?
ネットワーク運用の効率化や運用投入前の事前テストなどは、タスクの自動化によって大きく前進します。pyATS Blitz
は、Cisco Systems
が提供するネットワークテストおよび自動化フレームワーク pyATS
の一部であり、柔軟性と直感的な記述を両立した自動化ツールです。
pyATS Blitzの特徴
以下に、pyATS Blitz
の主な特徴を簡潔にまとめました:
- YAMLベースの簡潔な構文: 読みやすく学習コストが低い
- 幅広い操作性: CLI実行、API呼び出し、設定適用、トラブルシューティングが可能
- 構造化データ解析: Cisco Genieライブラリを利用してCLI出力を簡単に処理
-
条件付き処理: 問題発生時に追加アクションを自動実行(
run_condition
) - 並列処理とループ: 大規模ネットワークでも効率的な操作が可能
-
柔軟な条件判断:
include
/exclude
で文字列、正規表現、Dq
を使った細かい条件判断が可能 -
対話的プロンプト対応: 自動応答で完全な自動化を実現(
reply
) - ログ保存: すべての結果が自動で記録される
- スケーラブル: 小規模から大規模ネットワークまで対応可能
これらの特徴により、pyATS Blitz
はネットワーク自動化と効率化を強力にサポートします。
この記事の目標
-
pyATS Blitz
の基本操作とアクションを詳しく解説 - 現場での運用に役立つ応用シナリオを紹介
pyATS Blitzの概要
pyATS Blitz
は、以下の主要な構成要素で動作します
- testbed: 操作対象のネットワークデバイス情報を記載
- action: 実行する操作の指示
- include/exclude: アクション結果の判定条件
Testbedの記述方法
pyATS Blitz
を実行するためには、ネットワークデバイスの接続情報を記載した testbed
ファイルが必要です。
testbed.yaml の基本例:
devices:
switch1:
os: ios
connections:
cli:
protocol: ssh
ip: 10.0.0.1
credentials:
default:
username: admin
password: adminpass
構成のポイント:
- devices: テスト対象のデバイスをリスト化
- connections: CLI接続の詳細(SSH/Telnetなど)
- credentials: デバイスへの認証情報
testbed
ファイルはpyaTS Blitz
スクリプトの全アクションに対する基盤として機能します。
アクションの使い方
pyATS Blitz
は、execute
や parse
など、複数のアクションをサポートしており、これらを組み合わせてテストや自動化タスクを記述できます。
本記事では代表的なアクションのみを紹介しております。実際にはもっと多くのアクションが用意されているので、ドキュメントも参照してください。
execute: コマンドの実行
execute
はCLIコマンドを直接実行するための基本アクションです。
例: インターフェース情報の取得。
test_sections:
- check_interface
- execute:
device: PE1
command: "show ip interface brief"
alias: "interface_status"
解説:
- command: 実行するCLIコマンド
- alias: 結果にラベルを付けて後続のアクションで使用可能
parse: 結果の解析
parse
は、CLIコマンドの出力を構造化データとして解析します。pyATS
の genieparser
ライブラリを使用して、結果を簡単に扱える形式(Python Dictionary)に変換します。
例: バージョン情報の解析。
test_sections:
- check_version
- parse:
device: PE1
command: "show version"
alias: "version_output"
include:
- "17.12"
ポイント:
- include: 結果に特定の文字列が含まれているか確認
- alias: 結果を後続のアクションに渡すための識別子
pyATS の parser は Cisco 社内及び社外からライブラリに追加されており、数千の parser が存在します。こちらのページにて parse アクションで使用できる parser を確認することができます。
configure: 設定の適用
configureは、ネットワークデバイスに新しい設定を適用します。
例: VLAN設定の追加。
test_sections:
- configure_vlan:
- configure:
device: PE1
commands:
- "vlan 200"
- "name Accounting"
上記は設定の各行をリストで記載していますが、下記のように書くこともできます。私はこちらの方を好んで使います。
test_sections:
- configure_vlan:
- configure:
device: PE1
commands: |
vlan 200
name Accounting
利点:
- CLIで設定を直接送信
- 設定履歴を自動的にログに保存
api: デバイスAPIの呼び出し
apiを使用することで、デバイスのAPIを呼び出し、CLIよりも効率的な操作が可能です。
例: BGPネイバー情報の取得。
test_sections:
- get_bgp_neighbors
- api:
device: PE1
function: "get_bgp_neighbors"
alias: "bgp_neighbors"
特徴:
- 効率的なデータ取得
- CLIを直接介さずに構造化データを直接取得可能
pyATS のデバイスAPIは Cisco 社内及び社外からライブラリに追加されており、数千のAPIが存在します。こちらのページにて用意されているAPIを確認することができます。
include/excludeでの結果判定
Blitzの include
/ exclude
は execute
, parse
, api
アクションの結果を判定するのに使います。
execute
, parse
, api
アクションで include
/ exclude
を使っていない場合、意図しないエラーが発生した場合を除き、結果判定条件がないとして、デフォルトで結果は passed
となります。
includeとexcludeによる絞り込み
- include: 結果に含める文字列を指定
- exclude: 結果から除外する文字列を指定
例: インターフェースの状態を確認。
test_sections:
- check_interface
- execute:
device: PE1
command: "show ip interface brief"
alias: "interface_status"
include:
- "up"
exclude:
- "down"
上記の例だと、show ip interface brief
コマンドの出力に up
が含まれており、down
が含まれない場合のみ、結果は passed
となり、それ以外では failed
となります。
また、execute
アクションで show コマンドを実行して結果を include
/ exclude
で判断する場合には、出力は単一の文字列となるため、下記のようにその行の全体を include
に書く以外、特定のインタフェースのみを確認するといったことが困難です。
include:
- "Ethernet0/2 unassigned YES unset up up"
そのため、parser
が用意されている限り、通常は parse
アクションと Dq を使った条件判断が推奨されます。
test_sections:
- check_interface
- parse:
device: PE1
command: "show ip interface brief"
alias: "interface_status"
include:
- contains_key_value('interface', 'Ethernet0/2').contains_key_value('protocol', 'up')
- contains_key_value('interface', 'Ethernet0/2').contains_key_value('status', 'up')
上記のように parse
を使うと show コマンドの結果が構造化された Python Dictionary となるため、構造体に沿って、Dq を用いて特定のインタフェースに対して、特定のキーに対する値を厳格にチェックすることができます。
高度なアクション
複雑でスケールして自動化を実現するために高度なアクションも用意されています。
parallel: 並列処理
複数のアクションを並列実行し、処理時間を短縮します。
例: 複数コマンドの同時実行。
test_sections:
- run_show_command_in_parallel:
- parallel:
- execute:
device: PE1
command: "show ip interface brief"
- execute:
device: PE2
command: "show ip interface brief"
通常はデバイスへのコネクションは1つとなるため、異なるデバイスに対して並列実行を行います。
loop: 繰り返し処理
複数対象に対して同じアクションを実行します。
例: インターフェースごとのコンフィグを確認。
test_sections:
- check_interface_config
- loop:
loop_variable_name: interface
value:
- "GigabitEthernet0/0"
- "GigabitEthernet0/1"
actions:
execute:
device: PE1
command: "show running-config interface %VARIABLES{interface}"
run_condition: 条件付き処理
前のアクション結果に基づいて次のアクションを制御します。
例: 問題発生時の詳細なトラブルシューティング。
test_sections:
- verify_interface_up
- parse:
command: "show ip interface brief"
alias: "cli"
include:
- contains_key_value('interface', 'Ethernet0/2').contains_key_value('protocol', 'up')
- contains_key_value('interface', 'Ethernet0/2').contains_key_value('status', 'up')
- run_condition:
if: "%VARIABLES{cli} == passed"
actions:
- execute:
device: PE1
command: "show logging"
- execute:
device: PE1
command: "show running-config interface GigabitEthernet0/2"
Ethernet0/2
が down
だった場合(parseアクションがfailed
だった場合)にのみ show loggin
, show running-config interface GigabitEthernet0/2
を実行する。
繰り返し処理: max_timeとcheck_interval
繰り返し処理の目的
max_time
とcheck_interval
は、アクションを繰り返し実行し、特定の条件(include
/exclude
)が満たされるまで待機する仕組みです。この機能により、動的なネットワーク環境における状態変化を監視し、効率的に対応できます。
パラメータの詳細
- max_time: 最大待機時間(秒単位)
- check_interval: 繰り返し間隔(秒単位)
- include/exclude: 結果の条件フィルタリング
実用例: インターフェース状態の監視
目的: インターフェースがup状態になるまで繰り返し確認。
test_sections:
- verify_interface_status
- parse:
device: PE1
command: "show ip interface brief"
max_time: 60
check_interval: 5
include:
- contains_key_value('interface', 'Ethernet0/2').contains_key_value('protocol', 'up')
- contains_key_value('interface', 'Ethernet0/2').contains_key_value('status', 'up')
動作:
- show ip interface briefを実行
- Ethernet0/2 が up か確認
- 含まれない場合は5秒間隔で再試行
- 最大60秒間待機し、条件が満たされない場合は
failed
とする
応用例: BGPネイバーの確立監視
目的: BGPネイバーがEstablished状態になるまで監視。
test_sections:
- verify_bgp_neighbor
- parse:
command: "show bgp all neighbors"
max_time: 90
check_interval: 15
include:
- contains_key_value('neighbor', '10.1.11.1').contains_key_value('session_state', 'Established')
この例では、BGPネイバーが確立するまで最大90秒間監視し、15秒ごとに状態をチェックします。
状態の変化を待つための sleep
アクションも用意されていますが、可能な限り早く検知し、テストを進めるために sleep
アクションではなく max_time
/check_interval
の使用を推奨します。
デフォルトでは max_time
/check_interval
は設定されないので、最初の試行で条件が満たされないと結果は failed
になります。
Reply機能の活用
Reply機能とは?
CLIで対話的なプロンプトが表示される場合、reply機能を使用して自動応答を送信できます。この機能により、ユーザー介入なしで操作を完了できます。
使用例: 再起動時の確認プロンプトへの応答
test_sections:
- device_reload
- execute:
device: PE1
command: "reload"
reply:
- pattern: "Proceed with reload? [confirm]"
action: sendline() # Enterキーを送信
解説:
- reloadコマンドを実行
- "Proceed with reload?"のプロンプトが表示された場合に自動でEnterを送信
- 対話的操作を自動化
ここでは上記 reload
コマンドを execute
アクションで実行する例としていますが、実際には同様のアクションを行うデバイスAPIが用意されている場合には、API を使うことで reply
などが API 内で処理されており、簡素化できます。そのため、API がある場合はそちらを使うことを推奨します。
test_sections:
- device_reload
- api:
device : PE1
function : execute_reload
応用シナリオ
ここでは、実際のネットワーク運用で役立つ応用例を紹介します。
VLAN設定の一括適用と検証
目的: 複数のスイッチに対してVLANを一括設定し、正しく適用されているかを検証。
test_sections:
- configure_vlan
- loop:
loop_variable_name: device_name
value:
- PE1
- PE2
actions:
- configure:
device: "%VARIABLES{device_name}"
commands: |
vlan 100
name Marketing
- parse:
device: "%VARIABLES{device_name}"
command: "show vlan brief"
include:
- contains_key_value('vlan', 'vlan101').contains_key_value('vlan_name', 'Marketing')
動作:
- 各デバイスにVLAN 100を作成
- show vlan briefで設定を確認
- VLAN 100が存在し、適切な名前が含まれていない場合はエラーとしてログに記録
BGPネイバーの問題診断
目的: BGPネイバーが非確立の場合、関連情報を収集して原因を診断。
test_sections:
- verify_bgp_neighbor
- parse:
alias: cli
command: "show bgp all neighbors"
max_time: 90
check_interval: 15
include:
- contains_key_value('neighbor', '10.1.11.1').contains_key_value('session_state', 'Established')
- run_condition:
if: "%VARIABLES{cli} == passed"
actions:
- execute:
device: PE1
command: "show logging"
- execute:
device: PE1
command: "show run | sec router bgp"
- execute:
device: PE1
command: "ping 10.1.11.1"
トラブルシューティングとベストプラクティス
よくあるエラーと解決策
エラー1: Testbed構成ミス:
- 問題: IPや認証情報が間違っている
- 解決策: Testbedファイルを事前に検証
エラー2: YAMLフォーマットエラー:
- 問題: インデントミスや構文エラー
- 解決策: YAMLフォーマッタで整形確認
ベストプラクティス
- 小さなスクリプトから始める: 複雑な処理はステップごとにテスト
- ログの活用: アクションごとの結果を記録し、問題発生時にすぐ確認できるようにする
- 柔軟な条件指定: run_conditionやmax_timeを使用して動的に処理を制御
-
柔軟な結果判定:
parse
,include
/exclude
,Dq
を使いこなす
まとめ
pyATS Blitzは、ネットワーク運用を自動化により効率化し、作業効率を向上させるための強力なツールです。本記事で紹介した機能と応用例を参考に、より洗練された自動化を実現してください。
参考リンク
免責事項
本サイトおよび対応するコメントにおいて表明される意見は、投稿者本人の個人的意見であり、シスコの意見ではありません。本サイトの内容は、情報の提供のみを目的として掲載されており、シスコや他の関係者による推奨や表明を目的としたものではありません。各利用者は、本Webサイトへの掲載により、投稿、リンクその他の方法でアップロードした全ての情報の内容に対して全責任を負い、本Web サイトの利用に関するあらゆる責任からシスコを免責することに同意したものとします。