Genie Parsersで実現するDevices’ outputsの構造化


#初めに
DevNet Sandboxを使って簡単にpyATS/Genieを試すことができる非常に良い記事があるので、その記事を参考にしながらGenieのParsersを試してみました。
（参考記事）

[- DevNet Sandboxを使ってpyATS/XPRESSOをCML2と始めよう](https://qiita.com/tahigash/items/753cffdbf6380afa823f "DevNet Sandboxを使ってpyATS/XPRESSOをCML2と始めよう")

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

#デバイスアウトプットの構造化
GenieのParsersを使用すると、showコマンドを構造化（Json / Dictionary）して出力することができます。

#testbed.yamlファイル
DevNet Sandboxの「Cisco pyATS XPRESSO」の環境でデモを実行します。
GenieのParsers、Models、Apisなどの各ライブラリを使用するためには、testbedというネットワーク構成を記載したyamlファイルが必要です。参考記事にもあるようにSandbox内にtestbed.yamlは準備されてますが、デバイスへのアクセスをterminal_server経由ではなく直接アドレスでアクセスするように、また、`series`を`platform`表記へと修正しました。サポートされるPlatformsは[こちら](https://pubhub.devnetcloud.com/media/unicon/docs/user_guide/supported_platforms.html "Full list of supported platform")で確認できます。

```yaml:testbed.yaml
testbed:
  name: 'Multi Platform Network'
  credentials:
    default:
      username: cisco
      password: cisco
devices:
  internet-rtr01:
    os: iosxe
    platform: csr1000v
    alias: uut
    type: router
    connections:
      defaults:
        via: cli
      cli:
        ip: 10.10.20.181
        protocol: telnet
        port: 23
    credentials:
      default:
        username: cisco
        password: cisco
      enable:
        password: cisco
  internet-host01:
    os: linux
    alias: ub01
    type: server
    connections:
      defaults:
        via: cli
      cli:
        ip: 10.10.20.182
        protocol: ssh
    credentials:
      default:
        username: cisco
        password: cisco
  edge-firewall01:
    os: asa
    platform: asav
    alias: asa
    type: firewall
    connections:
      defaults:
        via: cli
      cli:
        ip: 10.10.20.171
        protocol: telnet
        port: 23
    credentials:
      default:
        username: cisco
        password: cisco
      enable:
        password: cisco
  core-rtr01:
    os: iosxr
    platform: iosxrv
    alias: xr01
    type: router
    connections:
      defaults:
        via: cli
      cli:
        ip: 10.10.20.173
        protocol: telnet
        port: 23
    credentials:
      default:
        username: cisco
        password: cisco
      enable:
        password: cisco
  core-rtr02:
    os: iosxr
    platform: iosxrv
    alias: xr02
    type: router
    connections:
      defaults:
        via: cli
      cli:
        ip: 10.10.20.174
        protocol: telnet
        port: 23
    credentials:
      default:
        username: cisco
        password: cisco
      enable:
        password: cisco
  dist-rtr01:
    os: iosxe
    platform: csr1000v
    alias: xe01
    type: router
    connections:
      defaults:
        via: cli
      cli:
        ip: 10.10.20.175
        protocol: telnet
        port: 23
    credentials:
      default:
        username: cisco
        password: cisco
      enable:
        password: cisco
  dist-rtr02:
    os: iosxe
    platform: csr1000v
    alias: xe02
    type: router
    connections:
      defaults:
        via: cli
      cli:
        ip: 10.10.20.176
        protocol: telnet
        port: 23
    credentials:
      default:
        username: cisco
        password: cisco
      enable:
        password: cisco
  dist-sw01:
    os: nxos
    platform: n9k
    alias: nx01
    type: switch
    connections:
      defaults:
        via: cli
      cli:
        ip: 10.10.20.177
        protocol: telnet
        port: 23
    credentials:
      default:
        username: cisco
        password: cisco
      enable:
        password: cisco
  dist-sw02:
    os: nxos
    platform: n9k
    alias: nx02
    type: switch
    connections:
      defaults:
        via: cli
      cli:
        ip: 10.10.20.178
        protocol: telnet
        port: 23
    credentials:
      default:
        username: cisco
        password: cisco
      enable:
        password: cisco
  inside-host01:
    os: linux
    alias: ub02
    type: server
    connections:
      defaults:
        via: cli
      cli:
        ip: 10.10.20.179
        protocol: ssh
    credentials:
      default:
        username: cisco
        password: cisco
  edge-sw01:
    os: ios
    platform: iosv
    alias: sw
    type: switch
    connections:
      defaults:
        via: cli
      cli:
        ip: 10.10.20.172
        protocol: telnet
        port: 23
    credentials:
      default:
        username: cisco
        password: cisco
      enable:
        password: cisco
  inside-host02:
    os: linux
    alias: desktop
    type: server
    connections:
      defaults:
        via: cli
      cli:
        ip: 10.10.20.180
        protocol: ssh
    credentials:
      default:
        username: cisco
        password: cisco
topology:
  internet-rtr01:
    interfaces:
      Loopback0:
        type: loopback
      GigabitEthernet1:
        link: l20
        type: ethernet
      GigabitEthernet2:
        link: l1
        type: ethernet
      GigabitEthernet3:
        link: l0
        type: ethernet
      GigabitEthernet4:
        type: ethernet
  internet-host01:
    interfaces:
      ens3:
        link: l0
        type: ethernet
      enp4:
        type: ethernet
      ens5:
        type: ethernet
      ens6:
        type: ethernet
      ens7:
        type: ethernet
      ens8:
        type: ethernet
      ens9:
        link: l29
        type: ethernet
  edge-firewall01:
    interfaces:
      Management0/0:
        link: l21
        type: ethernet
      GigabitEthernet0/0:
        link: l1
        type: ethernet
      GigabitEthernet0/1:
        link: l2
        type: ethernet
  core-rtr01:
    interfaces:
      Loopback0:
        type: loopback
      MgmtEth0/0/CPU0/0:
        link: l23
        type: ethernet
      GigabitEthernet0/0/0/0:
        link: l3
        type: ethernet
      GigabitEthernet0/0/0/1:
        link: l7
        type: ethernet
      GigabitEthernet0/0/0/2:
        link: l9
        type: ethernet
      GigabitEthernet0/0/0/3:
        link: l10
        type: ethernet
  core-rtr02:
    interfaces:
      Loopback0:
        type: loopback
      MgmtEth0/0/CPU0/0:
        link: l24
        type: ethernet
      GigabitEthernet0/0/0/0:
        link: l3
        type: ethernet
      GigabitEthernet0/0/0/1:
        link: l8
        type: ethernet
      GigabitEthernet0/0/0/2:
        link: l11
        type: ethernet
      GigabitEthernet0/0/0/3:
        link: l12
        type: ethernet
  dist-rtr01:
    interfaces:
      Loopback0:
        type: loopback
      GigabitEthernet1:
        link: l4
        type: ethernet
      GigabitEthernet2:
        link: l9
        type: ethernet
      GigabitEthernet3:
        link: l11
        type: ethernet
      GigabitEthernet4:
        link: l13
        type: ethernet
      GigabitEthernet5:
        link: l14
        type: ethernet
      GigabitEthernet6:
        link: l26
        type: ethernet
  dist-rtr02:
    interfaces:
      Loopback0:
        type: loopback
      GigabitEthernet1:
        link: l25
        type: ethernet
      GigabitEthernet2:
        link: l10
        type: ethernet
      GigabitEthernet3:
        link: l12
        type: ethernet
      GigabitEthernet4:
        link: l15
        type: ethernet
      GigabitEthernet5:
        link: l16
        type: ethernet
      GigabitEthernet6:
        link: l26
        type: ethernet
  dist-sw01:
    interfaces:
      Loopback0:
        type: loopback
      mgmt0:
        link: l27
        type: ethernet
      Ethernet1/1:
        link: l5
        type: ethernet
      Ethernet1/2:
        link: l6
        type: ethernet
      Ethernet1/3:
        link: l13
        type: ethernet
      Ethernet1/4:
        link: l15
        type: ethernet
      Ethernet1/5:
        type: ethernet
      Ethernet1/6:
        type: ethernet
      Ethernet1/7:
        type: ethernet
      Ethernet1/8:
        type: ethernet
      Ethernet1/9:
        type: ethernet
      Ethernet1/10:
        type: ethernet
      Ethernet1/11:
        link: l17
        type: ethernet
  dist-sw02:
    interfaces:
      Loopback0:
        type: loopback
      mgmt0:
        link: l28
        type: ethernet
      Ethernet1/1:
        link: l5
        type: ethernet
      Ethernet1/2:
        link: l6
        type: ethernet
      Ethernet1/3:
        link: l14
        type: ethernet
      Ethernet1/4:
        link: l16
        type: ethernet
      Ethernet1/5:
        type: ethernet
      Ethernet1/6:
        type: ethernet
      Ethernet1/7:
        type: ethernet
      Ethernet1/8:
        type: ethernet
      Ethernet1/9:
        type: ethernet
      Ethernet1/10:
        type: ethernet
      Ethernet1/11:
        link: l18
        type: ethernet
  inside-host01:
    interfaces:
      ens3:
        link: l17
        type: ethernet
      ens4:
        type: ethernet
      ens5:
        type: ethernet
      ens6:
        type: ethernet
      ens7:
        type: ethernet
      ens8:
        type: ethernet
      enp9:
        link: l30
        type: ethernet
  edge-sw01:
    interfaces:
      Loopback0:
        type: loopback
      GigabitEthernet0/0:
        link: l22
        type: ethernet
      GigabitEthernet0/1:
        link: l2
        type: ethernet
      GigabitEthernet0/2:
        link: l7
        type: ethernet
      GigabitEthernet0/3:
        link: l8
        type: ethernet
  inside-host02:
    interfaces:
      eth0:
        link: l18
        type: ethernet
      eth1:
        link: l31
        type: ethernet
```

testbed.yamlは` pyats validate testbed `で構造に誤りがないか確認することができ、` --connect `オプションを付けることで同時にデバイスへの接続テストも実行することができます。

```shell
(py3venv) [developer@devbox ~]$ pyats validate testbed --connect testbed.yaml
Loading testbed file: testbed.yaml
--------------------------------------------------------------------------------

Testbed Name:
    Multi Platform Network

Testbed Devices:
.
|-- core-rtr01 [router/iosxr/iosxrv]
|   |-- GigabitEthernet0/0/0/0 ----------> l3
|   |-- GigabitEthernet0/0/0/1 ----------> l7
|   |-- GigabitEthernet0/0/0/2 ----------> l9
|   |-- GigabitEthernet0/0/0/3 ----------> l10
|   |-- Loopback0
|   `-- MgmtEth0/0/CPU0/0 ----------> l23
|-- core-rtr02 [router/iosxr/iosxrv]
|   |-- GigabitEthernet0/0/0/0 ----------> l3
|   |-- GigabitEthernet0/0/0/1 ----------> l8
|   |-- GigabitEthernet0/0/0/2 ----------> l11
|   |-- GigabitEthernet0/0/0/3 ----------> l12
|   |-- Loopback0
|   `-- MgmtEth0/0/CPU0/0 ----------> l24
|-- dist-rtr01 [router/iosxe/csr1000v]
|   |-- GigabitEthernet1 ----------> l4
|   |-- GigabitEthernet2 ----------> l9
|   |-- GigabitEthernet3 ----------> l11
|   |-- GigabitEthernet4 ----------> l13
|   |-- GigabitEthernet5 ----------> l14
|   |-- GigabitEthernet6 ----------> l26
|   `-- Loopback0
|-- dist-rtr02 [router/iosxe/csr1000v]
|   |-- GigabitEthernet1 ----------> l25
|   |-- GigabitEthernet2 ----------> l10
|   |-- GigabitEthernet3 ----------> l12
|   |-- GigabitEthernet4 ----------> l15
|   |-- GigabitEthernet5 ----------> l16
|   |-- GigabitEthernet6 ----------> l26
|   `-- Loopback0
|-- dist-sw01 [switch/nxos/n9k]
|   |-- Ethernet1/1 ----------> l5
|   |-- Ethernet1/10
|   |-- Ethernet1/11 ----------> l17
|   |-- Ethernet1/2 ----------> l6
|   |-- Ethernet1/3 ----------> l13
|   |-- Ethernet1/4 ----------> l15
|   |-- Ethernet1/5
|   |-- Ethernet1/6
|   |-- Ethernet1/7
|   |-- Ethernet1/8
|   |-- Ethernet1/9
|   |-- Loopback0
|   `-- mgmt0 ----------> l27
|-- dist-sw02 [switch/nxos/n9k]
|   |-- Ethernet1/1 ----------> l5
|   |-- Ethernet1/10
|   |-- Ethernet1/11 ----------> l18
|   |-- Ethernet1/2 ----------> l6
|   |-- Ethernet1/3 ----------> l14
|   |-- Ethernet1/4 ----------> l16
|   |-- Ethernet1/5
|   |-- Ethernet1/6
|   |-- Ethernet1/7
|   |-- Ethernet1/8
|   |-- Ethernet1/9
|   |-- Loopback0
|   `-- mgmt0 ----------> l28
|-- edge-firewall01 [firewall/asa/asav]
|   |-- GigabitEthernet0/0 ----------> l1
|   |-- GigabitEthernet0/1 ----------> l2
|   `-- Management0/0 ----------> l21
|-- edge-sw01 [switch/ios/iosv]
|   |-- GigabitEthernet0/0 ----------> l22
|   |-- GigabitEthernet0/1 ----------> l2
|   |-- GigabitEthernet0/2 ----------> l7
|   |-- GigabitEthernet0/3 ----------> l8
|   `-- Loopback0
|-- inside-host01 [server/linux]
|   |-- enp9 ----------> l30
|   |-- ens3 ----------> l17
|   |-- ens4
|   |-- ens5
|   |-- ens6
|   |-- ens7
|   `-- ens8
|-- inside-host02 [server/linux]
|   |-- eth0 ----------> l18
|   `-- eth1 ----------> l31
|-- internet-host01 [server/linux]
|   |-- enp4
|   |-- ens3 ----------> l0
|   |-- ens5
|   |-- ens6
|   |-- ens7
|   |-- ens8
|   `-- ens9 ----------> l29
`-- internet-rtr01 [router/iosxe/csr1000v]
    |-- GigabitEthernet1 ----------> l20
    |-- GigabitEthernet2 ----------> l1
    |-- GigabitEthernet3 ----------> l0
    |-- GigabitEthernet4
    `-- Loopback0

YAML Lint Messages
------------------

Connection Check
----------------

    note that connection checks are not 100% accurate - it does not take
    into account that connection implementations may choose to interpret
    the entire connection block differently.

    For example - Unicon autouses A/B console/standby, but does not allow
    explicit connection to B.

 - internet-rtr01/cli                                                 [PASSED]
 - internet-host01/cli                                                [PASSED]
 - edge-firewall01/cli                                                [PASSED]
 - core-rtr01/cli                                                     [PASSED]
 - core-rtr02/cli                                                     [PASSED]
 - dist-rtr01/cli                                                     [PASSED]
 - dist-rtr02/cli                                                     [PASSED]
 - dist-sw01/cli                                                      [PASSED]
 - dist-sw02/cli                                                      [PASSED]
 - inside-host01/cli                                                  [PASSED]
 - edge-sw01/cli                                                      [PASSED]
 - inside-host02/cli                                                  [PASSED]

Warning Messages
----------------
 - Device 'inside-host01' missing 'platform' definition
 - Device 'inside-host02' missing 'platform' definition
 - Device 'internet-host01' missing 'platform' definition

(py3venv) [developer@devbox ~]$
```

#pythonでの` 'show version'`の構造化
CML2内の「internet-rtr01」で` show version`をpythonでparseしてみます。

```python
(py3venv) [developer@devbox ~]$ python
Python 3.6.8 (default, Sep 14 2019, 14:33:46)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-36)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from genie import testbed
>>> testbed = testbed.load('testbed.yaml')
>>> router_xe = testbed.devices['uut']
>>> router_xe.connect()

2021-08-26 15:47:09,290: %UNICON-INFO: +++ internet-rtr01 logfile /tmp/internet-rtr01-cli-20210826T154709289.log +++

2021-08-26 15:47:09,290: %UNICON-INFO: +++ Unicon plugin iosxe +++
Trying 10.10.20.181...


2021-08-26 15:47:09,317: %UNICON-INFO: +++ connection to spawn: telnet 10.10.20.181 23, id: 140486312744888 +++

2021-08-26 15:47:09,318: %UNICON-INFO: connection to internet-rtr01
Connected to 10.10.20.181.
Escape character is '^]'.


User Access Verification

Username: cisco
Password:
internet-rtr01#

2021-08-26 15:47:10,584: %UNICON-INFO: +++ initializing handle +++

2021-08-26 15:47:10,585: %UNICON-INFO: +++ internet-rtr01: executing command 'term length 0' +++
term length 0
internet-rtr01#

2021-08-26 15:47:10,747: %UNICON-INFO: +++ internet-rtr01: executing command 'term width 0' +++
term width 0
internet-rtr01#

2021-08-26 15:47:10,885: %UNICON-INFO: +++ internet-rtr01: executing command 'show version' +++
show version
Cisco IOS XE Software, Version 16.11.01b
Cisco IOS Software [Gibraltar], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.11.1b, RELEASE SOFTWARE (fc2)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2019 by Cisco Systems, Inc.
Compiled Tue 28-May-19 12:45 by mcpre


Cisco IOS-XE software, Copyright (c) 2005-2019 by cisco Systems, Inc.
All rights reserved.  Certain components of Cisco IOS-XE software are
licensed under the GNU General Public License ("GPL") Version 2.0.  The
software code licensed under GPL Version 2.0 is free software that comes
with ABSOLUTELY NO WARRANTY.  You can redistribute and/or modify such
GPL code under the terms of GPL Version 2.0.  For more details, see the
documentation or "License Notice" file accompanying the IOS-XE software,
or the applicable URL provided on the flyer accompanying the IOS-XE
software.


ROM: IOS-XE ROMMON

internet-rtr01 uptime is 13 minutes
Uptime for this control processor is 14 minutes
System returned to ROM by reload
System image file is "bootflash:packages.conf"
Last reload reason: Unknown reason



This product contains cryptographic features and is subject to United
States and local country laws governing import, export, transfer and
use. Delivery of Cisco cryptographic products does not imply
third-party authority to import, export, distribute or use encryption.
Importers, exporters, distributors and users are responsible for
compliance with U.S. and local country laws. By using this product you
agree to comply with applicable laws and regulations. If you are unable
to comply with U.S. and local laws, return this product immediately.

A summary of U.S. laws governing Cisco cryptographic products may be found at:
http://www.cisco.com/wwl/export/crypto/tool/stqrg.html

If you require further assistance please contact us by sending email to
export@cisco.com.

License Level: ax
License Type: N/A(Smart License Enabled)
Next reload license Level: ax


Smart Licensing Status: UNREGISTERED/No Licenses in Use

cisco CSR1000V (VXE) processor (revision VXE) with 2167316K/3075K bytes of memory.
Processor board ID 9CR4CCWS6O2
4 Gigabit Ethernet interfaces
32768K bytes of non-volatile configuration memory.
3984308K bytes of physical memory.
16162815K bytes of virtual hard disk at bootflash:.
0K bytes of WebUI ODM Files at webui:.

Configuration register is 0x2102

internet-rtr01#

2021-08-26 15:47:11,032: %UNICON-INFO: +++ internet-rtr01: configure +++
config term
Enter configuration commands, one per line.  End with CNTL/Z.
internet-rtr01(config)#no logging console
internet-rtr01(config)#line console 0
internet-rtr01(config-line)#exec-timeout 0
internet-rtr01(config-line)#end
internet-rtr01#
>>>
>>>
>>> output = router_xe.parse("show version")

2021-08-26 15:47:23,679: %UNICON-INFO: +++ internet-rtr01: executing command 'show version' +++
show version
Cisco IOS XE Software, Version 16.11.01b
Cisco IOS Software [Gibraltar], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.11.1b, RELEASE SOFTWARE (fc2)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2019 by Cisco Systems, Inc.
Compiled Tue 28-May-19 12:45 by mcpre


Cisco IOS-XE software, Copyright (c) 2005-2019 by cisco Systems, Inc.
All rights reserved.  Certain components of Cisco IOS-XE software are
licensed under the GNU General Public License ("GPL") Version 2.0.  The
software code licensed under GPL Version 2.0 is free software that comes
with ABSOLUTELY NO WARRANTY.  You can redistribute and/or modify such
GPL code under the terms of GPL Version 2.0.  For more details, see the
documentation or "License Notice" file accompanying the IOS-XE software,
or the applicable URL provided on the flyer accompanying the IOS-XE
software.


ROM: IOS-XE ROMMON

internet-rtr01 uptime is 13 minutes
Uptime for this control processor is 14 minutes
System returned to ROM by reload
System image file is "bootflash:packages.conf"
Last reload reason: Unknown reason



This product contains cryptographic features and is subject to United
States and local country laws governing import, export, transfer and
use. Delivery of Cisco cryptographic products does not imply
third-party authority to import, export, distribute or use encryption.
Importers, exporters, distributors and users are responsible for
compliance with U.S. and local country laws. By using this product you
agree to comply with applicable laws and regulations. If you are unable
to comply with U.S. and local laws, return this product immediately.

A summary of U.S. laws governing Cisco cryptographic products may be found at:
http://www.cisco.com/wwl/export/crypto/tool/stqrg.html

If you require further assistance please contact us by sending email to
export@cisco.com.

License Level: ax
License Type: N/A(Smart License Enabled)
Next reload license Level: ax


Smart Licensing Status: UNREGISTERED/No Licenses in Use

cisco CSR1000V (VXE) processor (revision VXE) with 2167316K/3075K bytes of memory.
Processor board ID 9CR4CCWS6O2
4 Gigabit Ethernet interfaces
32768K bytes of non-volatile configuration memory.
3984308K bytes of physical memory.
16162815K bytes of virtual hard disk at bootflash:.
0K bytes of WebUI ODM Files at webui:.

Configuration register is 0x2102

internet-rtr01#
>>>
>>>
>>> import pprint
>>> pprint.pprint(output)
{'version': {'chassis': 'CSR1000V',
             'chassis_sn': '9CR4CCWS6O2',
             'compiled_by': 'mcpre',
             'compiled_date': 'Tue 28-May-19 12:45',
             'curr_config_register': '0x2102',
             'disks': {'bootflash:.': {'disk_size': '16162815',
                                       'type_of_disk': 'virtual hard disk'},
                       'webui:.': {'disk_size': '0',
                                   'type_of_disk': 'WebUI ODM Files'}},
             'hostname': 'internet-rtr01',
             'image_id': 'X86_64_LINUX_IOSD-UNIVERSALK9-M',
             'image_type': 'production image',
             'last_reload_reason': 'Unknown reason',
             'license_level': 'ax',
             'license_type': 'N/A(Smart License Enabled)',
             'main_mem': '2167316',
             'mem_size': {'non-volatile configuration': '32768',
                          'physical': '3984308'},
             'next_reload_license_level': 'ax',
             'number_of_intfs': {'Gigabit Ethernet': '4'},
             'os': 'IOS-XE',
             'platform': 'Virtual XE',
             'processor_type': 'VXE',
             'returned_to_rom_by': 'reload',
             'rom': 'IOS-XE ROMMON',
             'rtr_type': 'CSR1000V',
             'system_image': 'bootflash:packages.conf',
             'uptime': '13 minutes',
             'uptime_this_cp': '14 minutes',
             'version': '16.11.1b',
             'version_short': '16.11'}}
>>>
```

` show version`のアウトプットが辞書型に構造化されました。
このようにデバイスアウトプットが構造化されることで、人の目には認識しにくくなりますが、プログラミング時に欲しい情報を簡単に取り出すことができ扱いやすくなります。
なお、OS毎にサポートされているParsersは[こちら](https://pubhub.devnetcloud.com/media/genie-feature-browser/docs/#/)です。

![nail.001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834983/5c56337b-6fb7-f5a5-813e-6e6cce01f397.png)

#参考リンク
[- DevNet Sandboxを使ってpyATS/XPRESSOをCML2と始めよう](https://qiita.com/tahigash/items/753cffdbf6380afa823f "DevNet Sandboxを使ってpyATS/XPRESSOをCML2と始めよう")
[- Genie Documentation](https://pubhub.devnetcloud.com/media/genie-docs/docs/index.html "Genie Documentation")
[- Unicon: The Connection Library](https://pubhub.devnetcloud.com/media/unicon/docs/index.html "Unicon: The Connection Library")
[- genie-feature-browser](https://pubhub.devnetcloud.com/media/genie-feature-browser/docs/#/ "genie-feature-browser")