LoginSignup
26
3

More than 1 year has passed since last update.

ラボ環境の自動化に pyATS Clean を活用しよう!

Last updated at Posted at 2022-12-10

この記事はシスコの有志による Cisco Systems Japan Advent Calendar 2021 1枚目の 11 日目として投稿しています。

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

はじめに

pyATS 開発チームに所属していた東村(@tahigash3)です。シスコジャパンではなく、シスコカナダで働いております。最近自分の希望で pyATS チームから異動し、今は開発チームと連携して SRv6 の新機能に対する内容や実装の確認、テストプラン作成やそのテストケースの実装など、社内テストの自動化をメインで行っております(もちろん pyATS を使ってます)。

今回は Cisco が開発しているネットワーク自動化ツール pyATSが提供している pyATS Clean という機能を紹介したいと思います。

過去の記事でも pyATS について書いているので、こちらも合わせて参照ください。

また Cisco Japan の有志が今年のアドベントカレンダーで pyATS について書いてくれている記事もあるので、こちらも是非!

pyATS Clean とは?

pyATS Clean とは名前の通り、クリーニングを行ってくれます。と言っても何かよく分からないと思いますが。。皆さんががラボでテスト環境を作成してテスト行っている時に、どのような悩みがあるでしょうか?テスト自体は pyATS、Ansible、TeraTermのマクロ等で自動化しているかもしれません。
が、下記のような事は手動でやっていたりしませんか?

  • イメージの入れ替え
  • ROMMON に落ちている機器の復旧
  • コンソールが誰かに掴まれており、コンソールサーバに入りセッションを切る

pyATS Clean とは上記のようなことすらも自動化でき、一言で言うと テスト行う前の期待される状況にラボ環境をセットアップしてくれます

pyATS Clean の動作フロー

下記が pyATS Clean の動作フローになります。

61059657-2C02-44CF-AB9B-A20EC010106F.png

簡単に書くと下記のようになります。

1.pyATS Clean の開始
2.Cleanステージの実行
3.デバイスへの接続性のチェック。
4.接続できない場合はコンソールサーバ経由でセッション切断
5.それでも接続できない場合はパワーサイクラーで電源のOFF/ON
6.ROMMON から TFTP サーバ経由でイメージの起動
7.接続に問題がない、接続問題が解消されたら2.へ戻る

Cleanステージとは詳細は後述しますが、接続(connect)再起動(reload)など pyATS Clean の機能毎のステージとなります。

要はクリーニングのステップ(各ステージ)を実行し、接続性の確認を実行、問題があれば復旧し、クリーニングを続行するということになります。

testbed.yaml へサーバやパワーサイクラー等の情報の追加

pyATS Clean ではコンソールサーバでのコンソールセッションの切断やデバイしの再起動などができると書きましたが、残念ながらマジックはありません。その機能を使うためにはラボ環境にコンソールサーバやパワーサイクラーが必要になります。

tftp サーバの追記

testbed.yamltestbed セクションの中に servers セクションを追加し、下記のようにtftpサーバ情報を追加します。

testbed.yaml
testbed:
  name: pyATS-testbed
  servers:
    tftp:
      server: pyats-tftp   # tftpサーバー名
      address: 192.168.1.1 # tftpサーバーアドレス
      path: /auto/path/images/

コンソールサーバ及びパワーサイクラーの追記

次にコンソールサーバ及びパワーサイクラーを testbed.yaml へ追記します。
この2つはデバイス毎に異なる情報となるため、devices セクションのデバイスの配下に peripherals というセクションで追加します。

testbed.yaml
devices:
  asr1000:
    os: iosxe
    (snip)
    peripherals:
      terminal_server:
        pyats-ts-1: [41] # ターミナルサーバ名 `pyats-ts-1`。ポート番号 41
      power_cycler:
        type: dualcomm           # パワーサイクラーのタイプ
        connection_type: snmp    # SNMP 経由での電源OFF/ON
        host: 10.1.1.1           # パワーサイクラーのIPアドレス
        read_community: public   # SNMP コミュニティ for Read-Only
        write_community: public  # SNMP コミュニティ for Read-Write
        outlets: [1, 2]          # デバイスが接続されているOutlet番号  

パワーサイクラーやコンソールサーバ情報が無くても pyATS Clean を実行することはできますが、電源OFF/ONやコンソールセッションの切断などの機能が使えなくなります。

clean.yaml の作成

testbed.yaml の更新が終わったら、次はメインの clean.yaml を作成します。
ただ、最初は難しいと思うので、pyATS チームが作成したサンプルファイルを活用しましょう。

pyATS Clean のサンプルファイルは下記の GitHub にあります。

上記のように色々なプラットフォームの例が用意されています。

今回は ASR1K の例を見ていきたいと思います。

各項目の説明を下記 yaml ファイルの中に記載しています。

clean.yaml
cleaners:                    # devices 以外はお決まりとお覚えください
  DeviceClean:
    module: genie.libs.clean
    devices: [asr1000]       # pyATS Clean の対象デバイスを指定

devices:
  asr1000:
    images:                            # 起動したいイメージの場所を指定
      - /auto/release/path/vmlinux.bin

    device_recovery:                           # デバイスの復旧
      break_count: 5                           # ()
      console_activity_pattern: "\\.\\.\\.\\." # ROMMON に落とすタイミングとなる表示パターンを指定。機種によって調整が必要な場合あり
      timeout: 600                             # デバイス復旧のタイムアウト値
      recovery_password: "%ENC{w5zDmsOD}"      # ()
      golden_image:
        - bootflash:/golden_image.bin          # デバイス上のイメージ指定

    connect:  # デバイスへの接続

    ping_server:               # ping で tftp サーバーへの接続確認
      server: pyats-tftp       # tftp サーバー名
      vrf: Mgmt-intf           # tftp サーバへの接続に VRF 指定が必要な場合

    copy_to_linux:                    # イメージをtftpサーバへコピー
      destination:
        directory: /auto/path/images/ # tftp サーバがアクセスできる場所
      overwrite: True                 # イメージの上書きを許可するか
      copy_attempts: 3                # 試行回数
      append_hostname: True           # イメージ名にホスト名を追加するか

    copy_to_device:               # イメージをデバイスへコピー
      origin:
        hostname: pyats-tftp      # TFTPサーバ名
      destination:
        directory: 'harddisk:/'   # デバイス上のコピー先
      protocol: tftp              # コピーに使用するプロトコル    
      overwrite: True             # 上書きを許可するか
      verify_num_images: False    # イメージ数をチェックするか
      check_file_stability: True  # ファイルが安定しているかのチェック
      min_free_space_percent: 50  # 空きスペースの閾値

    change_boot_variable:         # boot variable の設定

    write_erase:                  # コンフィグの削除

    reload:                       # デバイスのリロード

    apply_configuration:          # 初期設定の追加
      configuration: |            # 初期設定のコンフィグを記述
        hostname asr1000
        enable password banana
        interface GigabitEthernet0
          ip address X.X.X.X 255.255.255.0
          no shut
        line console 0
          exec-timeout 0 0
          logging synchronous
        line vty 0 4
          password lab
      config_timeout: 30          # 設定時のタイムアウト値 
      config_stable_time: 120     # 設定後の待ち時間

    verify_running_image:         # イメージの確認

    order:                        # Clean ステージの実行順序
      - 'connect'
      - 'ping_server'
      - 'copy_to_linux'
      - 'copy_to_device'
      - 'change_boot_variable'
      - 'write_erase'
      - 'reload'
      - 'apply_configuration'
      - 'verify_running_image'

それでは各ステージを簡単に説明していきます。

images

clean.yamlの抜粋
    images:                            # 起動したいイメージの場所を指定
      - /auto/release/path/vmlinux.bin

デバイスを起動させるイメージを指定します。YAML 内では同じレベルにありますが、images は Clean ステージではありません。

device_recovery

clean.yamlの抜粋
    device_recovery:                           # デバイスの復旧
      break_count: 5                           # ()
      console_activity_pattern: "\\.\\.\\.\\." # ROMMON に落とすタイミングとなる表示パターンを指定。機種によって調整が必要な場合あり
      timeout: 600                             # デバイス復旧のタイムアウト値
      recovery_password: "%ENC{w5zDmsOD}"      # ()
      golden_image:
        - bootflash:/golden_image.bin          # デバイス上のイメージ指定

device_recovery も同じく Clean ステージではありません。 device_discovery はデバイスにアクセスできない、電源OFF/ONによる復旧が必要な場合に実行される救済機能となります。
通常は実行されませんが、Clean ステージ実行後にデバイスに接続できないような状況になった場合に実行されます。

connect ステージ

clean.yamlの抜粋
    connect:  # デバイスへの接続

デバイスへ接続します。ただそれだけです。w
通常特にパラメーターは渡さないため、Cleanステージ名のみになります。

デバイスに接続しないと何もできないため、connect ステージは必ず必要になります。

ping_server ステージ

clean.yamlの抜粋
    ping_server:               # ping で tftp サーバーへの接続確認
      server: pyats-tftp       # tftp サーバー名
      vrf: Mgmt-intf           # tftp サーバへの接続に VRF 指定が必要な場合

指定した server へ ping を行い、疎通があることを確認します。これは デバイス <-> TFTP サーバ間の確認となります。TFTP サーバーへの接続に使う Mgmt インタフェースに VRF を設定している場合は、その VRF も指定します。

通常、イメージをコピーするTFTPサーバへの疎通性確認を行いますが、server の指定を変更することでTFTPサーバ以外の疎通確認にも使えます。

copy_to_linux ステージ

clean.yamlの抜粋
    copy_to_linux:                    # イメージをtftpサーバへコピー
      destination:
        directory: /auto/path/images/ # tftp サーバがアクセスできる場所
      overwrite: True                 # イメージの上書きを許可するか
      copy_attempts: 3                # 試行回数
      append_hostname: True           # イメージ名にホスト名を追加するか

イメージファイルが TFTP サーバー上にない場合に使用します。
イメージファイルを destination で指定した TFTP サーバ上のフォルダにコピーします。
overwrite は上書きの有無の指定、copy_attempts はコピーが失敗した場合に何回トライするか、append_hostname はデバイス毎にイメージをユニークに保存しておきたい場合に使います。

イメージファイルが TFTP サーバー上にある、またマウント経由でアクセスできる状況の場合は、このステージは不要です。

copy_to_device ステージ

clean.yamlの抜粋
    copy_to_device:               # イメージをデバイスへコピー
      origin:
        hostname: pyats-tftp      # TFTPサーバ名
      destination:
        directory: 'harddisk:/'   # デバイス上のコピー先
      protocol: tftp              # コピーに使用するプロトコル    
      overwrite: True             # 上書きを許可するか
      verify_num_images: False    # イメージ数をチェックするか
      check_file_stability: True  # ファイルが安定しているかのチェック
      min_free_space_percent: 50  # 空きスペースの閾値

TFTPサーバからデバイスへイメージファイルをコピーします。重要なパラメータは origindestination になり、送信元の TFTP サーバを指定、送信先のデバイス上の場所を指定します。

他には protocol は今回の場合は tftp としていますが、FTP/SCPなども使えます。
check_file_stability はファイルサイズが変動していないか(コピー中じゃないか)を定期的にサイズを確認してチェックします。min_free_space_percent はディスクスペースの空きスペースの閾値を指定します。50% としているので、harddisk: に 50% 以上の空きがない場合はファイルを削除して、サイズを50%以上確保しようとします。

change_boot_variable ステージ

clean.yamlの抜粋
    change_boot_variable:         # boot variable の設定

起動するイメージにて boot statment を変更して次回起動時に指定したイメージで起動する設定を行います。

write_erase ステージ

clean.yamlの抜粋
    write_erase:                  # コンフィグの削除

write erase コマンドで設定を初期化します。pyATS Clean ではデバイスを初期化するのが目的なため、一般的に設定の削除を行います。

reload ステージ

clean.yamlの抜粋
    reload:                       # デバイスのリロード

デバイスを再起動します。設定を初期化するため、新しいイメージで起動するために再起動を行います。

apply_configuration ステージ

clean.yamlの抜粋
    apply_configuration:          # 初期設定の追加
      configuration: |            # 初期設定のコンフィグを記述
        hostname asr1000
        enable password banana
        interface GigabitEthernet0
          ip address X.X.X.X 255.255.255.0
          no shut
        line console 0
          exec-timeout 0 0
          logging synchronous
        line vty 0 4
          password lab
      config_timeout: 30          # 設定時のタイムアウト値 
      config_stable_time: 120     # 設定後の待ち時間

apply_configuration は再起動後に管理インタフェース(Management Interface)を設定するために使用されます。上記のように、ホスト名、Mgmt Interface の設定などを行います。

pyATS Clean の apply_configuration では前述のように Mgmt Interface など管理系の設定のみを行うのが一般的ではありますが、pyATS Clean 後にある程度のコンフィグを持っておきたい場合などにはここに他の設定(OSPFやBGP等)を追加してももちろん OK です。

verify_running_image ステージ

clean.yamlの抜粋
    verify_running_image:         # イメージの確認

verify_running_image では指定したイメージで起動していることを確認します。

order

clean.yamlの抜粋
    order:                        # Clean ステージの実行順序
      - 'connect'
      - 'ping_server'
      - 'copy_to_linux'
      - 'copy_to_device'
      - 'change_boot_variable'
      - 'write_erase'
      - 'reload'
      - 'apply_configuration'
      - 'verify_running_image'

order も Clean ステージではございません。 非常に重要な項目となり、前述した Clean ステージの実行順序を指定します。そのため、上記までの記載の順番は関係なく、ここで記載された順番で実行されます。
order は省略できない必須項目でもあります。また、Cleanステージを記載しつつ、order に入れなかった場合は実行されません。

その他の Clean ステージ

上記は ASR1K のクリーンにおける場合について紹介しましたが、機種やOSの違いによりクリーンアップの手順が異なっている場合があります。そのためにここでは紹介していない Clean ステージもあり、下記の Web ページから Clean ステージを見つけることができます。また各パラメータの詳細も確認できます。

pyATS Clean の実行

実行方法は主に2通りになります。

pyATS Job と一緒に実行

pyATS Job を実行する pyats run job コマンドに --clean-file--invoke-clean というオプションを実行することで pyATS Clean が実行されデバイスが初期化された後に、pyATS Job が実行されます。

$ pyats run job job.py --testbed-file testbed.yaml --clean-file clean.yaml --invoke-clean

上記を実行後に pyats logs view コマンドを実行するとログビューワーが開きログが確認できます。

下記が実行画面になります。色枠にしているところがタブになり、緑枠が pyATS Clean の実行結果 となり、白枠が pyATS Job の実行結果となります。

pyATS Clean を行うことで毎回デバイスが初期化されるため、pyATS Job の実行が 同じ状態のデバイス に対して実行されるということになり、結果の一貫性が保つことができるようになります。
例えば、ラボ機器ですと、知らない間に誰かがイメージを入れ替えていた、設定が微妙に変更されていたというようなことが起こりえるかもしれませんが、pyATS Clean で毎回テスト環境をクリーニングすることで同じ状況でテストを走らせることが可能になります。

pyATS Clean 単体(スタンドアローン)で実行

次は pyATS Clean のみを実行する方法となり、pyats clean コマンドを使います。この場合は --invoke-clean は必要ありません。

$ pyats clean --testbed-file testbed.yaml --clean-file clean.yaml

上記を実行後に pyats logs view コマンドを実行すると pyATS Job と同じような形で pyATS Clean の事項結果を確認できます。但し、タブのところが一つしかなく pyATS Clean の実行結果のみとなります。

例えば、テスト環境をクリーニングアップしたいが、クリーニング後はマニュアルでの検証を行いたいという場合に主に使用されます。

pyATS Clean の便利な使い方

ここまでで pyATS Clean の使い方について説明してきましたが、こういう場合にも使えるよというユースケースを紹介しておきたいと思います。

ライセンスモードを切り替えてリロードしたい

ラボ機材は手配できたが、あれ?設定したい設定が入らない。。というライセンスモードによる問題も pyATS Clean を使えばマニュアル作業を軽減できます!

clean.yaml
cleaners:
  DeviceClean:
    module: genie.libs.clean
    devices: [asr1000]

devices:
  asr1000:
    connect:

    apply_configuration:
      configuration: |
        license boot level network-advantage addon dna-advantage

    reload:

    order:
      - 'connect'
      - 'apply_configuration'
      - 'reload'

clean.yaml は上記のようになり、簡素なのがお分かりかと思います。
connectapply_configurationreload しか使っていません。また自動化したいシナリオに応じて、order で順序を変えて実行しています。

order のところの説明でお気づきの方も多いと思いますが、clean ステージは作業ステップ毎になっており、その組み合わせで色々なシナリオでのクリーンアップが可能になっております。必要でなければ、そのステージを持つ必要はなく、必要なものだけを使用し、また順番も必要に応じて変更可能です。

testbed.yaml の全ての機器に接続できるか確認したい

pyATS Clean を使ってデバイスへの接続性を確認する clean.yaml の例です。
この場合は、全てのデバイスに対して同じステージと、パラメータ(今回パラメータはありませんが)となる場合は、devices の代わりに groups でグルーピングして YAML 内も簡素化できます。

clean.yaml
cleaners:
  DeviceClean:
    module: genie.libs.clean
    groups: [my_group]

groups:
  my_group:
    devices:
      - asr1000-1
      - asr1000-2
      - asr1000-3

    connect:

    order:
      - 'connect'

ステージ1つでも order は必要になりますので、ご注意ください。

あくまで一例であり、同じ事をするなら実際には pyATS Shell から testbed.connect() する方が早いです。w

$ pyats shell --testbed-file testbed.yaml
>>> testbed.connect()

全ての機器へ同じ設定を投入したい

clean.yaml
cleaners:
  DeviceClean:
    module: genie.libs.clean
    groups: [my_group]

groups:
  my_group:
    devices:
      - asr1000-1
      - asr1000-2
      - asr1000-3

    connect:

    apply_configuration:
      configuration: |
        ntp server 10.1.1.1
        no ip domain-lookup
        ip tftp source-interface GigabitEthernet1
        ip tftp block-size 8192

    ping_server:
      server: 10.1.1.1

    order:
      - 'connect'
      - 'apply_configuration'
      - 'ping_server'

NTP サーバや TFTP 関連の設定など、全デバイスで共通しているようなコンフィグを一括で設定したい場合にも pyATS Clean を使うことができます。念のため、NTPサーバへの接続性があるかを ping_server ステージを使って確認しています。

全ての機器の設定を削除したい

clean.yaml
cleaners:
  DeviceClean:
    module: genie.libs.clean
    groups: [my_group]

groups:
  my_group:
    devices:
      - asr1000-1
      - asr1000-2
      - asr1000-3

    connect:

    write_erase:

    reload:

    order:
      - 'connect'
      - 'write_erase'
      - 'reload'

設定のみを指定したデバイスから削除したい場合には上記のように pyATS Clean を実行できます。write_erase 及び reload ステージを使って実現できます。

pyATS 関連の問い合わせ

pyATS の問い合わせ先は下記のメールアドレスまたは Cisco Webex Teams Space(下記のリンクから参加) になります。

また、特定のコンポーネント(pyATS, Genie, Genie Parser, Genie Libs, Unicon)が把握できている場合は、GitHub の Issue を該当のレポジトリでオープンしてもらう形でも問題ありません。

問い合わせは現状では英語のみとなっております。

サポートはコミュニティでというのが前提ですがpyATSチームは積極的に直接サポートを行なっています。ただし、無料ツールとなっているため、SLA などは無いことにご注意ください。

日本語のサポートは現時点では用意されていませんが、Twitter で呟いていただくと、私のアカウント @tahigash3 が反応するかもしれません。

まとめ

今回は pyATS Clean を使ったテスト環境の準備や簡単な作業を自動化することを紹介してみました。pyATS では設定の投入や機能試験などのテスト自体の自動化に話されることが多いですが、pyATS Clean のようにさりげなく、他の自動化ツールが持っていないユニークな機能も持っています。

またイメージしやすいように pyATS Clean が使えるケースも clean.yaml を使って紹介してみました。なんとか使うイメージが分かったり、pyATS Clean の使い方を理解する手助けができたなら幸いです。

pyATS には他にも色々な機能があるので、ぜひ興味がある方は試して使ってみてくださいね!

参考リンク

今回の記事 pyATS Clean に関連したリンク

下記は pyATS の参考になるリンク

免責事項

本サイトおよび対応するコメントにおいて表明される意見は、投稿者本人の個人的意見であり、シスコの意見ではありません。本サイトの内容は、情報の提供のみを目的として掲載されており、シスコや他の関係者による推奨や表明を目的としたものではありません。各利用者は、本Webサイトへの掲載により、投稿、リンクその他の方法でアップロードした全ての情報の内容に対して全責任を負い、本Web サイトの利用に関するあらゆる責任からシスコを免責することに同意したものとします。

26
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
3