0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Genie Apisで実現できるネットワーク機器への様々なアクション

Last updated at Posted at 2021-08-31

初めに

DevNet Sandboxを使って簡単にpyATS/Genieを試すことができる非常に良い記事があるので、その記事を参考にしながらGenieのApisをCML2で稼働させているネットワーク機器で試してみました。

(参考記事)
- DevNet Sandboxを使ってpyATS/XPRESSOをCML2と始めよう

Genieとは

Genieとは、pyATSフレームワークのモジュラーアーキテクチャにバンドルされているネットワークテスト自動化に必要なすべてのツールを含むPyATS用のPythonライブラリ。

Genie Apis

Genieには、デバイス上でconfig、verify、get、analyzeなどのさまざまなアクションを実行するための一連の組み込みAPI関数があります。 これらは、device.apisメソッドを使用して直接アクセスできます。 こちらにOS毎にサポートされているAPIが掲載されているので、必要なAPI名を見つけて、device.api.api_name(args_1、args_2、....)のように引数を指定してAPIを呼び出します。

testbed.yamlファイル

DevNet Sandboxの「Cisco pyATS XPRESSO」の環境でデモを実行します。
GenieのParsers、Models、Apisなどの各ライブラリを使用するためには、testbedというネットワーク構成を記載したyamlファイルが必要です。参考記事にもあるようにSandbox内にtestbed.yamlは準備されています。
また、前回記事にも掲載しています。
- Genie Parsersで実現するDevices’ outputsの構造化

Apisを使用したデモの概要

Genie Apisのshut_interfaceでCML2内ルータのインターフェースをshutdownget_interfaces_statusでインターフェースステータスを確認しつつ冗長ルートへ経路変更したことを確認し、unshut_interfaceでルータのインターフェースをno shutdown状態に戻す。

デモの手順

① Api実行前に「dist-sw01」から「internet-rtr01」までの経路をtracerouteで確認。
② __genie_apis_shut_int.py__を実行し、IOS-XE用のAPIであるshut_interfaceを使って、CML2内の「dist-rtr01」と「dist-rtr02」のインターフェースをshutdownし、get_interfaces_statusを使ってステータスを確認。
③ 再度「dist-sw01」でtracerouteを実行しルートが変わったことを確認。
④ __genie_apis_unshut_int.py__を実行し、unshut_interfaceを使って、CML2内の「dist-rtr01」と「dist-rtr02」のインターフェースをno shutdownし、get_interfaces_statusを使ってステータスを確認。
⑤ tracerouteで経路が戻ったことを確認。

デモの実行

事前準備:
genie_apis_shut_int.py、__genie_apis_unshut_int.py__をDevBoxの__testbed.yaml__と同じディレクトリにコピーします。

Sandbox内のGenieではget_interfaces_statusは未対応だったので、こちらのGenie Apiのソースコードからコピーし、関数として追加しています。

genie_apis_shut_int.py
# !user/bin/python

from genie import testbed
import pprint
import time


def get_interfaces_status(device):
    """Get up/down status of all interfaces
    Args:
        device (obj): device object
    """

    try:
        out = device.parse('show ip interface brief')
    except SchemaEmptyParserError as e:
        log.error('No interface information found')
        return None

    # {'interface': {'GigabitEthernet1': {'interface_is_ok': 'YES',
    #           'ip_address': '172.16.1.210',
    #           'method': 'DHCP',
    #           'protocol': 'up',
    #           'status': 'up'},

    return {key: val.get('status') for key, val in out.get('interface', {}).items()}


testbed = testbed.load('testbed.yaml')
xe01 = testbed.devices['xe01']
xe02 = testbed.devices['xe02']

# unicon接続
xe01.connect()
xe02.connect()

# インターフェースのステータスを事前取得
xe01_before_shut_status = get_interfaces_status(xe01)
xe02_before_shut_status = get_interfaces_status(xe02)

# 事前取得したステータスを表示
print('-------xe01 interface status before shutdown-------')
pprint.pprint(xe01_before_shut_status)
print('---------------------------------------------------')
print('-------xe02 interface status before shutdown-------')
pprint.pprint(xe02_before_shut_status)
print('---------------------------------------------------')

# Apisを使ってxe01、xe02のインターフェースをshutdown
xe01.api.shut_interface(interface='GigabitEthernet4')
xe02.api.shut_interface(interface='GigabitEthernet2')
xe02.api.shut_interface(interface='GigabitEthernet3')

# ステータスがアップデートされるまでスリープ
time.sleep(10)

# インターフェースのステータスを事後取得
xe01_after_shut_status = get_interfaces_status(xe01)
xe02_after_shut_status = get_interfaces_status(xe02)

# 事後取得したステータスを表示
print('-------xe01 interface status after shutdown--------')
pprint.pprint(xe01_after_shut_status)
print('---------------------------------------------------')
print('-------xe02 interface status after shutdown--------')
pprint.pprint(xe02_after_shut_status)
print('---------------------------------------------------')

# unicon切断
xe01.disconnect()
xe02.disconnect()
genie_apis_unshut_int.py
# !user/bin/python

from genie import testbed
import pprint
import time


def get_interfaces_status(device):
    """Get up/down status of all interfaces
    Args:
        device (obj): device object
    """

    try:
        out = device.parse('show ip interface brief')
    except SchemaEmptyParserError as e:
        log.error('No interface information found')
        return None

    # {'interface': {'GigabitEthernet1': {'interface_is_ok': 'YES',
    #           'ip_address': '172.16.1.210',
    #           'method': 'DHCP',
    #           'protocol': 'up',
    #           'status': 'up'},

    return {key: val.get('status') for key, val in out.get('interface', {}).items()}


testbed = testbed.load('testbed.yaml')
xe01 = testbed.devices['xe01']
xe02 = testbed.devices['xe02']

# unicon接続
xe01.connect()
xe02.connect()

# インターフェースのステータスを事前取得
xe01_after_shut_status = get_interfaces_status(xe01)
xe02_after_shut_status = get_interfaces_status(xe02)

# 事前取得したステータスを表示
print('------xe01 interface status before unshutdown------')
pprint.pprint(xe01_after_shut_status)
print('---------------------------------------------------')
print('------xe02 interface status before unshutdown------')
pprint.pprint(xe02_after_shut_status)
print('---------------------------------------------------')

# Apisを使ってxe01、xe02のインターフェースをunshutdown
xe01.api.unshut_interface(interface='GigabitEthernet4')
xe02.api.unshut_interface(interface='GigabitEthernet2')
xe02.api.unshut_interface(interface='GigabitEthernet3')

# ステータスがアップデートされるまでスリープ
time.sleep(10)

# インターフェースのステータスを事後取得
xe01_after_unshut_status = get_interfaces_status(xe01)
xe02_after_unshut_status = get_interfaces_status(xe02)

# 事後取得したステータスを表示
print('------xe01 interface status after unshutdown-------')
pprint.pprint(xe01_after_unshut_status)
print('---------------------------------------------------')
print('------xe02 interface status after unshutdown-------')
pprint.pprint(xe02_after_unshut_status)
print('---------------------------------------------------')

# unicon切断
xe01.disconnect()
xe02.disconnect()

① 「dist-sw01」で事前にtracerouteを実行しルートを確認します。

dist-sw01# traceroute 172.31.0.1 source 172.16.101.2
traceroute to 172.31.0.1 (172.31.0.1) from 172.16.101.2 (172.16.101.2), 30 hops max, 40 byte packets
 1  172.16.252.6 (172.16.252.6)  4.767 ms  4.296 ms  4.552 ms
 2  172.16.252.34 (172.16.252.34)  4.752 ms  4.038 ms  4.71 ms
 3  172.31.252.1 (172.31.252.1)  17.421 ms *  16.431 ms

dist-rtr02 -> core-rtr02 -> edge-firewall01 -> internet-rtr01のように、distributeレイヤー、coreレイヤー、edgeファイアウォール、と順に経由しています。
(edgeファイアウォールはTTLをdecrementしないのでtraceroute結果には表示されていません。)

② __genie_apis_shut_int.py__を実行します。
このコードは、shut_interfaceで「dist-rtr01」のGig4、「dist-rtr02」のGig2、Gig3をshutdownし、get_interfaces_statusでインターフェースshutdown前後のステータスを確認します。

(py3venv) [developer@devbox ~]$ python genie_apis_shut_int.py

2021-08-30 21:33:58,019: %UNICON-INFO: +++ dist-rtr01 logfile /tmp/dist-rtr01-cli-20210830T213358018.log +++

2021-08-30 21:33:58,019: %UNICON-INFO: +++ Unicon plugin iosxe +++
Trying 10.10.20.175...


2021-08-30 21:33:58,046: %UNICON-INFO: +++ connection to spawn: telnet 10.10.20.175 23, id: 140224549787352 +++

2021-08-30 21:33:58,047: %UNICON-INFO: connection to dist-rtr01
Connected to 10.10.20.175.
Escape character is '^]'.

(以下省略)


2021-08-30 21:34:00,719: %UNICON-INFO: +++ dist-rtr02 logfile /tmp/dist-rtr02-cli-20210830T213400718.log +++

2021-08-30 21:34:00,719: %UNICON-INFO: +++ Unicon plugin iosxe +++
Trying 10.10.20.176...


2021-08-30 21:34:00,729: %UNICON-INFO: +++ connection to spawn: telnet 10.10.20.176 23, id: 140224489678160 +++

2021-08-30 21:34:00,729: %UNICON-INFO: connection to dist-rtr02
Connected to 10.10.20.176.
Escape character is '^]'.

(以下省略)

# ここからget_interfaces_statusの処理と結界の出力

2021-08-30 21:34:04,820: %UNICON-INFO: +++ dist-rtr01: executing command 'show ip interface brief' +++
show ip interface brief
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       10.10.20.175    YES TFTP   up                    up
GigabitEthernet2       172.16.252.21   YES TFTP   up                    up
GigabitEthernet3       172.16.252.25   YES TFTP   up                    up
GigabitEthernet4       172.16.252.2    YES TFTP   up                    up
GigabitEthernet5       172.16.252.10   YES TFTP   up                    up
GigabitEthernet6       172.16.252.17   YES TFTP   up                    up
Loopback0              unassigned      YES unset  administratively down down
dist-rtr01#

2021-08-30 21:34:05,019: %UNICON-INFO: +++ dist-rtr02: executing command 'show ip interface brief' +++
show ip interface brief
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       10.10.20.176    YES TFTP   up                    up
GigabitEthernet2       172.16.252.29   YES TFTP   up                    up
GigabitEthernet3       172.16.252.33   YES TFTP   up                    up
GigabitEthernet4       172.16.252.6    YES TFTP   up                    up
GigabitEthernet5       172.16.252.14   YES TFTP   up                    up
GigabitEthernet6       172.16.252.18   YES TFTP   up                    up
Loopback0              unassigned      YES unset  administratively down down
dist-rtr02#
-------xe01 interface status before shutdown-------
{'GigabitEthernet1': 'up',
 'GigabitEthernet2': 'up',
 'GigabitEthernet3': 'up',
 'GigabitEthernet4': 'up',
 'GigabitEthernet5': 'up',
 'GigabitEthernet6': 'up',
 'Loopback0': 'administratively down'}
---------------------------------------------------
-------xe02 interface status before shutdown-------
{'GigabitEthernet1': 'up',
 'GigabitEthernet2': 'up',
 'GigabitEthernet3': 'up',
 'GigabitEthernet4': 'up',
 'GigabitEthernet5': 'up',
 'GigabitEthernet6': 'up',
 'Loopback0': 'administratively down'}
---------------------------------------------------

# ここからshut_interfaceの処理の出力

2021-08-30 21:34:06,425: %UNICON-INFO: +++ dist-rtr01: configure +++
config term
Enter configuration commands, one per line.  End with CNTL/Z.
dist-rtr01(config)#interface GigabitEthernet4
dist-rtr01(config-if)#shutdown
dist-rtr01(config-if)#end
dist-rtr01#

2021-08-30 21:34:06,659: %UNICON-INFO: +++ dist-rtr02: configure +++
config term
Enter configuration commands, one per line.  End with CNTL/Z.
dist-rtr02(config)#interface GigabitEthernet2
dist-rtr02(config-if)#shutdown
dist-rtr02(config-if)#end
dist-rtr02#

2021-08-30 21:34:06,873: %UNICON-INFO: +++ dist-rtr02: configure +++
config term
Enter configuration commands, one per line.  End with CNTL/Z.
dist-rtr02(config)#interface GigabitEthernet3
dist-rtr02(config-if)#shutdown
dist-rtr02(config-if)#end
dist-rtr02#

# ここからget_interfaces_statusの処理と結界の出力

2021-08-30 21:34:17,048: %UNICON-INFO: +++ dist-rtr01: executing command 'show ip interface brief' +++
show ip interface brief
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       10.10.20.175    YES TFTP   up                    up
GigabitEthernet2       172.16.252.21   YES TFTP   up                    up
GigabitEthernet3       172.16.252.25   YES TFTP   up                    up
GigabitEthernet4       172.16.252.2    YES TFTP   administratively down down
GigabitEthernet5       172.16.252.10   YES TFTP   up                    up
GigabitEthernet6       172.16.252.17   YES TFTP   up                    up
Loopback0              unassigned      YES unset  administratively down down
dist-rtr01#

2021-08-30 21:34:17,301: %UNICON-INFO: +++ dist-rtr02: executing command 'show ip interface brief' +++
show ip interface brief
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       10.10.20.176    YES TFTP   up                    up
GigabitEthernet2       172.16.252.29   YES TFTP   administratively down down
GigabitEthernet3       172.16.252.33   YES TFTP   administratively down down
GigabitEthernet4       172.16.252.6    YES TFTP   up                    up
GigabitEthernet5       172.16.252.14   YES TFTP   up                    up
GigabitEthernet6       172.16.252.18   YES TFTP   up                    up
Loopback0              unassigned      YES unset  administratively down down
dist-rtr02#
-------xe01 interface status after shutdown--------
{'GigabitEthernet1': 'up',
 'GigabitEthernet2': 'up',
 'GigabitEthernet3': 'up',
 'GigabitEthernet4': 'administratively down',
 'GigabitEthernet5': 'up',
 'GigabitEthernet6': 'up',
 'Loopback0': 'administratively down'}
---------------------------------------------------
-------xe02 interface status after shutdown--------
{'GigabitEthernet1': 'up',
 'GigabitEthernet2': 'administratively down',
 'GigabitEthernet3': 'administratively down',
 'GigabitEthernet4': 'up',
 'GigabitEthernet5': 'up',
 'GigabitEthernet6': 'up',
 'Loopback0': 'administratively down'}
---------------------------------------------------
(py3venv) [developer@devbox ~]$

インターフェースがshutdownされ、ステータスも辞書型で取得することができました。

③ 「dist-sw01」でtracerouteを実行しルートを確認します。

dist-sw01# traceroute 172.31.0.1 source 172.16.101.2
traceroute to 172.31.0.1 (172.31.0.1) from 172.16.101.2 (172.16.101.2), 30 hops max, 40 byte packets
 1  172.16.252.6 (172.16.252.6)  4.486 ms  6.374 ms  3.514 ms
 2  172.16.252.17 (172.16.252.17)  11.989 ms  12.718 ms  7.782 ms
 3  172.16.252.22 (172.16.252.22)  9.771 ms  9.83 ms  10.478 ms
 4  172.31.252.1 (172.31.252.1)  19.248 ms *  31.892 ms

dist-rtr02 -> dist-rtr01 -> core-rtr01 -> edge-firewall01 -> internet-rtr01のように、distributeレイヤーの両ルータのどちらも経由しています。これは、両ルータのインターフェースを「shut_interface」Apiでshutdownすることによって経路が変わったからです。

④ __genie_apis_unshut_int.py__を実行します。
このコードは、unshut_interfaceで「dist-rtr01」のGig4、「dist-rtr02」のGig2、Gig3をno shutdownし、get_interfaces_statusでインターフェースno shutdown前後のステータスを確認します。

(py3venv) [developer@devbox ~]$ python genie_apis_unshut_int.py

2021-08-30 21:35:42,454: %UNICON-INFO: +++ dist-rtr01 logfile /tmp/dist-rtr01-cli-20210830T213542453.log +++

2021-08-30 21:35:42,454: %UNICON-INFO: +++ Unicon plugin iosxe +++
Trying 10.10.20.175...


2021-08-30 21:35:42,464: %UNICON-INFO: +++ connection to spawn: telnet 10.10.20.175 23, id: 140625328928640 +++

2021-08-30 21:35:42,464: %UNICON-INFO: connection to dist-rtr01
Connected to 10.10.20.175.
Escape character is '^]'.

(以下省略)

2021-08-30 21:35:43,450: %UNICON-INFO: +++ dist-rtr02 logfile /tmp/dist-rtr02-cli-20210830T213543449.log +++

2021-08-30 21:35:43,450: %UNICON-INFO: +++ Unicon plugin iosxe +++
Trying 10.10.20.176...


2021-08-30 21:35:43,460: %UNICON-INFO: +++ connection to spawn: telnet 10.10.20.176 23, id: 140625268815184 +++

2021-08-30 21:35:43,460: %UNICON-INFO: connection to dist-rtr02
Connected to 10.10.20.176.
Escape character is '^]'.

(以下省略)

# ここからget_interfaces_statusの処理と結界の出力

2021-08-30 21:35:45,409: %UNICON-INFO: +++ dist-rtr01: executing command 'show ip interface brief' +++
show ip interface brief
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       10.10.20.175    YES TFTP   up                    up
GigabitEthernet2       172.16.252.21   YES TFTP   up                    up
GigabitEthernet3       172.16.252.25   YES TFTP   up                    up
GigabitEthernet4       172.16.252.2    YES TFTP   administratively down down
GigabitEthernet5       172.16.252.10   YES TFTP   up                    up
GigabitEthernet6       172.16.252.17   YES TFTP   up                    up
Loopback0              unassigned      YES unset  administratively down down
dist-rtr01#

2021-08-30 21:35:45,589: %UNICON-INFO: +++ dist-rtr02: executing command 'show ip interface brief' +++
show ip interface brief
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       10.10.20.176    YES TFTP   up                    up
GigabitEthernet2       172.16.252.29   YES TFTP   administratively down down
GigabitEthernet3       172.16.252.33   YES TFTP   administratively down down
GigabitEthernet4       172.16.252.6    YES TFTP   up                    up
GigabitEthernet5       172.16.252.14   YES TFTP   up                    up
GigabitEthernet6       172.16.252.18   YES TFTP   up                    up
Loopback0              unassigned      YES unset  administratively down down
dist-rtr02#
------xe01 interface status before unshutdown------
{'GigabitEthernet1': 'up',
 'GigabitEthernet2': 'up',
 'GigabitEthernet3': 'up',
 'GigabitEthernet4': 'administratively down',
 'GigabitEthernet5': 'up',
 'GigabitEthernet6': 'up',
 'Loopback0': 'administratively down'}
---------------------------------------------------
------xe02 interface status before unshutdown------
{'GigabitEthernet1': 'up',
 'GigabitEthernet2': 'administratively down',
 'GigabitEthernet3': 'administratively down',
 'GigabitEthernet4': 'up',
 'GigabitEthernet5': 'up',
 'GigabitEthernet6': 'up',
 'Loopback0': 'administratively down'}
---------------------------------------------------

# ここからunshut_interfaceの処理の出力

2021-08-30 21:35:46,318: %UNICON-INFO: +++ dist-rtr01: configure +++
config term
Enter configuration commands, one per line.  End with CNTL/Z.
dist-rtr01(config)#interface GigabitEthernet4
dist-rtr01(config-if)#no shutdown
dist-rtr01(config-if)#end
dist-rtr01#

2021-08-30 21:35:46,454: %UNICON-INFO: +++ dist-rtr02: configure +++
config term
Enter configuration commands, one per line.  End with CNTL/Z.
dist-rtr02(config)#interface GigabitEthernet2
dist-rtr02(config-if)#no shutdown
dist-rtr02(config-if)#end
dist-rtr02#

2021-08-30 21:35:46,613: %UNICON-INFO: +++ dist-rtr02: configure +++
config term
Enter configuration commands, one per line.  End with CNTL/Z.
dist-rtr02(config)#interface GigabitEthernet3
dist-rtr02(config-if)#no shutdown
dist-rtr02(config-if)#end
dist-rtr02#

# ここからget_interfaces_statusの処理と結界の出力

2021-08-30 21:35:56,804: %UNICON-INFO: +++ dist-rtr01: executing command 'show ip interface brief' +++
show ip interface brief
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       10.10.20.175    YES TFTP   up                    up
GigabitEthernet2       172.16.252.21   YES TFTP   up                    up
GigabitEthernet3       172.16.252.25   YES TFTP   up                    up
GigabitEthernet4       172.16.252.2    YES TFTP   up                    up
GigabitEthernet5       172.16.252.10   YES TFTP   up                    up
GigabitEthernet6       172.16.252.17   YES TFTP   up                    up
Loopback0              unassigned      YES unset  administratively down down
dist-rtr01#

2021-08-30 21:35:56,954: %UNICON-INFO: +++ dist-rtr02: executing command 'show ip interface brief' +++
show ip interface brief
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       10.10.20.176    YES TFTP   up                    up
GigabitEthernet2       172.16.252.29   YES TFTP   up                    up
GigabitEthernet3       172.16.252.33   YES TFTP   up                    up
GigabitEthernet4       172.16.252.6    YES TFTP   up                    up
GigabitEthernet5       172.16.252.14   YES TFTP   up                    up
GigabitEthernet6       172.16.252.18   YES TFTP   up                    up
Loopback0              unassigned      YES unset  administratively down down
dist-rtr02#
------xe01 interface status after unshutdown-------
{'GigabitEthernet1': 'up',
 'GigabitEthernet2': 'up',
 'GigabitEthernet3': 'up',
 'GigabitEthernet4': 'up',
 'GigabitEthernet5': 'up',
 'GigabitEthernet6': 'up',
 'Loopback0': 'administratively down'}
---------------------------------------------------
------xe02 interface status after unshutdown-------
{'GigabitEthernet1': 'up',
 'GigabitEthernet2': 'up',
 'GigabitEthernet3': 'up',
 'GigabitEthernet4': 'up',
 'GigabitEthernet5': 'up',
 'GigabitEthernet6': 'up',
 'Loopback0': 'administratively down'}
---------------------------------------------------

インターフェースがno shutdownされ、ステータスも辞書型で取得することができました。

⑤ 「dist-sw01」でtracerouteを実行しルートを確認します。

dist-sw01# traceroute 172.31.0.1 source 172.16.101.2
traceroute to 172.31.0.1 (172.31.0.1) from 172.16.101.2 (172.16.101.2), 30 hops max, 40 byte packets
 1  172.16.252.6 (172.16.252.6)  8.505 ms  7.229 ms  4.554 ms
 2  172.16.252.30 (172.16.252.30)  13.763 ms  12.658 ms  7.007 ms
 3  172.31.252.1 (172.31.252.1)  33.239 ms *  10.868 ms

dist-rtr02 -> core-rtr01 -> edge-firewall01 -> internet-rtr01のように、「shut_interface」Apiでshutdownしたことで経路がもどりました。

Genie Apisを活用すれば、テスト実行時によく実施する項目を簡単に実行することができます。コードはgithubに公開されているので、参考にしながら新たなApiを作成したり、特定のApiをimportして新たな機能を付加するなども可能です。Apisは順次追加されており、かゆいところに手が届くものが多数ありとても便利です。

参考リンク

- DevNet Sandboxを使ってpyATS/XPRESSOをCML2と始めよう
- Genie Parsersで実現するDevices’ outputsの構造化
- Genie Documentation
- genie-feature-browser

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?