GithubHelp home page GithubHelp logo

ciscotestautomation / pyats Goto Github PK

View Code? Open in Web Editor NEW
140.0 21.0 29.0 2.05 MB

Cisco DevNet pyATS Test Framework Bug Tracker

License: Apache License 2.0

cisco automation-framework netdevops pyats devnet infrastructure test-automation-framework network-automation

pyats's People

Contributors

akhosrav avatar bastell avatar dani-maarouf avatar danielgraziano avatar domachad avatar dwapstra avatar eric035 avatar gerriorl avatar jeaubin avatar kamyarziabari avatar lilyholms avatar lsheikal avatar lukasmcclelland avatar omehrabi avatar sclayton1006 avatar simingy avatar sjpatel21 avatar strattner avatar taarini avatar tahigash avatar thomasjryan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyats's Issues

pyats.topology.loader dependency

Please assist.

When creating a testbed file
$ genie create testbed --output yaml/testbed.yml --encode-password

I get following error.
"pyats.topology.loader is a required dependency for this command. 'None' source cannot be found."

Example pyats test case fails to import ats.aetest

Using the latest pyats version (4.1) and running the pyats example code, my test case said it was unable to import ats.aetest ๐Ÿ˜ฎ

$ pip list | grep pyats
pyats (4.1.0)
pyats.aereport (4.1.0)
pyats.aetest (4.1.1)
pyats.async (4.1.0)
pyats.connections (4.1.0)
pyats.datastructures (4.1.0)
pyats.easypy (4.1.0)
pyats.examples (4.1.0)
pyats.kleenex (4.1.0)
pyats.log (4.1.0)
pyats.results (4.1.0)
pyats.tcl (4.1.0)
pyats.templates (4.1.0)
pyats.topology (4.1.0)
pyats.utils (4.1.0)
$ python --version
Python 3.4.7
$ python basic/basic_example_script.py 
Traceback (most recent call last):
  File "basic/basic_example_script.py", line 19, in <module>
    from ats import aetest
  File "/home/zacharyw/.pyenv/versions/3.4.7/lib/python3.4/site-packages/ats/aetest/__init__.py", line 32, in <module>
    from .main import main
ImportError: /home/zacharyw/.pyenv/versions/3.4.7/lib/python3.4/site-packages/ats/aetest/main.cpython-34m.so: wrong ELF class: ELFCLASS32

How to pass parameter to parse() ?

I wrote a parser script and saved it in my pyats tree as:

~/pyats/lib/python3.6/site-packages/genie/libs/parser/sros/show_card_detail.py

My code to call the parser:

from genie.libs.parser.sros.show_card_detail import ShowCardDetail
... # device connection codes
card_info = ShowCardDetail(device=dev).parse()

My question:
Is it possible to pass parameter such as "card_slot = 3" into parse(...) ?

Best regard,
sshuguan

Ping in a VRF is Unsupported on IOS XR

Expected Behavior

User can ping an IP in a VRF on IOS XR.

Actual Behavior

User cannot ping an IP in a VRF on IOS XR.

Test Environment

Python Version

> python --version
Python 3.6.7

pyATS Package Versions

> pip freeze | egrep 'pyats|unicon|genie'
genie==3.1.0
genie.abstract==3.1.0
genie.conf==3.1.0
genie.examples==3.1.1
genie.harness==3.1.4
genie.libs.conf==3.1.3
genie.libs.filetransferutils==3.1.0
genie.libs.ops==3.1.5
genie.libs.parser==3.1.11
genie.libs.robot==3.1.6
genie.libs.sdk==3.1.8
genie.libs.telemetry==3.1.2
genie.metaparser==3.1.0
genie.ops==3.1.3
genie.parsergen==3.1.1
genie.predcore==3.1.0
genie.telemetry==3.1.4
genie.utils==3.1.3
pyats==5.0.1
pyats.aereport==5.0.1
pyats.aetest==5.0.0
pyats.async==5.0.0
pyats.connections==5.0.0
pyats.datastructures==5.0.0
pyats.easypy==5.0.2
pyats.examples==5.0.0
pyats.kleenex==5.0.2
pyats.log==5.0.0
pyats.results==5.0.0
pyats.robot==5.0.0
pyats.tcl==5.0.0
pyats.templates==5.0.0
pyats.topology==5.0.0
pyats.utils==5.0.3
unicon==3.4.3

IOS XR Version

RP/0/0/CPU0:ios#show version brief 
Sat Dec 15 19:14:09.011 UTC

Cisco IOS XR Software, Version 6.0.1[Default]
Copyright (c) 2016 by Cisco Systems, Inc.

ROM: GRUB, Version 1.99(0), DEV RELEASE

ios uptime is 1 week, 1 day, 15 hours, 21 minutes
System image file is "bootflash:disk0/xrvr-os-mbi-6.0.1/mbixrvr-rp.vm"

cisco IOS XRv Series (Pentium Celeron Stepping 3) processor with 3145215K bytes of memory.
Pentium Celeron Stepping 3 processor at 2393MHz, Revision 2.174
IOS XRv Chassis

1 Management Ethernet
3 GigabitEthernet
97070k bytes of non-volatile configuration memory.
866M bytes of hard disk.
2321392k bytes of disk0: (Sector size 512 bytes).
RP/0/0/CPU0:ios#

Steps to Reproduce

Assuming a management IP of 10.0.0.2 with default credentials, configure the IOS XR router as below:

RP/0/0/CPU0:ios#show running-config vrf management 
Sat Dec 15 19:15:01.388 UTC
vrf management
 address-family ipv4 unicast
 !
!

RP/0/0/CPU0:ios#show running-config interface mgmtEth 0/0/CPU0/0 
Sat Dec 15 19:15:08.347 UTC
interface MgmtEth0/0/CPU0/0
 vrf management
 ipv4 address 10.0.0.2 255.255.255.0
!

RP/0/0/CPU0:ios#

Confirm you have a route and forwarding entry:

RP/0/0/CPU0:ios#show route vrf management ipv4 unicast 
Sat Dec 15 19:19:24.200 UTC

Codes: C - connected, S - static, R - RIP, B - BGP, (>) - Diversion path
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2, E - EGP
       i - ISIS, L1 - IS-IS level-1, L2 - IS-IS level-2
       ia - IS-IS inter area, su - IS-IS summary null, * - candidate default
       U - per-user static route, o - ODR, L - local, G  - DAGR, l - LISP
       A - access/subscriber, a - Application route
       M - mobile route, r - RPL, (!) - FRR Backup path

Gateway of last resort is 10.0.0.1 to network 0.0.0.0

S*   0.0.0.0/0 [1/0] via 10.0.0.1, 02:26:25
C    10.0.0.0/24 is directly connected, 02:27:59, MgmtEth0/0/CPU0/0
L    10.0.0.2/32 is directly connected, 02:27:59, MgmtEth0/0/CPU0/0
RP/0/0/CPU0:ios#show cef vrf management 10.0.0.1
Sat Dec 15 19:21:15.532 UTC
0.0.0.0/0, version 3, proxy default, internal 0x1000011 0x0 (ptr 0xa1447674) [1], 0x0 (0x0), 0x0 (0x0)
 Updated Dec 15 16:52:58.551 
 local adjacency 10.0.0.1
 Prefix Len 0, traffic index 0, precedence n/a, priority 3
   via 10.0.0.1/32, 2 dependencies, recursive [flags 0x0]
    path-idx 0 NHID 0x0 [0xa1447c74 0x0]
    next hop 10.0.0.1/32 via 10.0.0.1/32
RP/0/0/CPU0:ios#show cef vrf management 10.0.0.1
Sat Dec 15 19:21:24.641 UTC
10.0.0.1/32, version 0, internal 0x1020001 0x0 (ptr 0xa1447c74) [2], 0x0 (0xa1413488), 0x0 (0x0)
 Updated Dec 15 17:13:24.047 
 local adjacency 10.0.0.1
 Prefix Len 32, traffic index 0, Adjacency-prefix, precedence n/a, priority 15
   via 10.0.0.1/32, MgmtEth0/0/CPU0/0, 6 dependencies, weight 0, class 0 [flags 0x0]
    path-idx 0 NHID 0x0 [0xa0f15250 0x0], Internal 0xa0c8329c
    next hop 10.0.0.1/32
    local adjacency
RP/0/0/CPU0:ios#

Confirm you can ping another IP in that VRF:

RP/0/0/CPU0:ios#ping 10.0.0.1 vrf management 
Sat Dec 15 19:18:46.872 UTC
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.0.0.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/1 ms
RP/0/0/CPU0:ios#

Use the following testbed at /tmp/testbed.yaml:

testbed:
  name: vrftest
  tacacs:
    username: admin
  passwords:
    tacacs: admin

devices:
  nxos:
    os: nxos
    type: nxos
    connections: 
      ssh:
        protocol: ssh
        ip: 10.0.0.1
  xr:
    os: iosxr
    type: iosxr
    connections: 
      ssh:
        protocol: ssh
        ip: 10.0.0.2

NX-OS is here to show that pinging in a VRF works with NX-OS.

Start ipython and enter the following:

from genie.conf import Genie

# Initialize the testbed
Genie.init(testbed='/tmp/testbed.yaml')

# Connect to the XR router
Genie.testbed.devices['xr'].connect()

# Attempt to ping `10.0.0.1`, note that it never passes the `vrf`
Genie.testbed.devices['xr'].ping('10.0.0.1', vrf='management')

Example output:

In [2]: from genie.conf import Genie 
   ...:  
   ...: # Initialize the testbed 
   ...: Genie.init(testbed='/tmp/testbed.yaml') 
   ...:  
   ...: # Connect to the XR router 
   ...: Genie.testbed.devices['xr'].connect() 
   ...:  
   ...: # Attempt to ping `10.0.0.1`, note that it never passes the `vrf` 
   ...: Genie.testbed.devices['xr'].ping('10.0.0.1', vrf='management')                                                                                                                                                                                                                                                                                                             
[2018-12-15 11:27:37,102] +++ xr logfile /tmp/xr-cli-20181215T112737102.log +++
[2018-12-15 11:27:37,102] +++ Unicon plugin iosxr +++
[2018-12-15 11:27:37,114] +++ connection to spawn: ssh -l admin 10.0.0.2 -p 22, id: 140636922789280 +++
[2018-12-15 11:27:37,115] connection to xr
[2018-12-15 11:27:37,109] ssh -l admin 10.0.0.2 -p 22



IMPORTANT:  READ CAREFULLY
Welcome to the Demo Version of Cisco IOS XRv (the "Software").
The Software is subject to and governed by the terms and conditions
of the End User License Agreement and the Supplemental End User
License Agreement accompanying the product, made available at the
time of your order, or posted on the Cisco website at
www.cisco.com/go/terms (collectively, the "Agreement").
As set forth more fully in the Agreement, use of the Software is
strictly limited to internal use in a non-production environment
solely for demonstration and evaluation purposes.  Downloading,
installing, or using the Software constitutes acceptance of the
Agreement, and you are binding yourself and the business entity
that you represent to the Agreement.  If you do not agree to all
of the terms of the Agreement, then Cisco is unwilling to license
the Software to you and (a) you may not download, install or use the
Software, and (b) you may return the Software as more fully set forth
in the Agreement.


Please login with any configured user/password, or cisco/cisco


admin@10.0.0.2's password: 


RP/0/0/CPU0:ios#
[2018-12-15 11:27:37,534] +++ initializing handle +++
[2018-12-15 11:27:37,535] +++ xr: executing command 'terminal length 0' +++
terminal length 0
Sat Dec 15 19:27:34.796 UTC
RP/0/0/CPU0:ios#
[2018-12-15 11:27:37,620] +++ xr: executing command 'terminal width 0' +++
terminal width 0
Sat Dec 15 19:27:34.876 UTC
RP/0/0/CPU0:ios#
[2018-12-15 11:27:37,688] +++ xr: config +++
configure terminal
Sat Dec 15 19:27:34.956 UTC
RP/0/0/CPU0:ios(config)#no logging console
RP/0/0/CPU0:ios(config)#line console
RP/0/0/CPU0:ios(config-line)#exec-timeout 0 0
RP/0/0/CPU0:ios(config-line)#absolute-timeout 0
RP/0/0/CPU0:ios(config-line)#session-timeout 0
RP/0/0/CPU0:ios(config-line)#line default
RP/0/0/CPU0:ios(config-line)#exec-timeout 0 0
RP/0/0/CPU0:ios(config-line)#absolute-timeout 0
RP/0/0/CPU0:ios(config-line)#session-timeout 0
RP/0/0/CPU0:ios(config-line)#end
Uncommitted changes found, commit them before exiting(yes/no/cancel)? [cancel]:yes
RP/0/0/CPU0:ios#
[2018-12-15 11:27:38,870] +++ xr: ping +++
ping
Sat Dec 15 19:27:36.136 UTC
Protocol [ipv4]: 
Target IP address: 10.0.0.1
Repeat count [5]: 
Datagram size [100]: 
Timeout in seconds [2]: 
Interval in milliseconds [10]: 0
Extended commands? [no]: n
Sweep range of sizes? [no]: n
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.0.0.1, timeout is 2 seconds:
UUUUU
Success rate is 0 percent (0/5)
RP/0/0/CPU0:ios#
---------------------------------------------------------------------------
SubCommandFailure                         Traceback (most recent call last)
<ipython-input-2-c597290ef041> in <module>
      8 
      9 # Attempt to ping `10.0.0.1`, note that it never passes the `vrf`
---> 10 Genie.testbed.devices['xr'].ping('10.0.0.1', vrf='management')

~/.virtualenvs/netdevops/lib/python3.6/site-packages/unicon/bases/routers/services.cpython-36m-x86_64-linux-gnu.so in unicon.bases.routers.services.BaseService.__call__()

~/.virtualenvs/netdevops/lib/python3.6/site-packages/unicon/bases/routers/services.cpython-36m-x86_64-linux-gnu.so in unicon.bases.routers.services.BaseService.get_service_result()

SubCommandFailure: ('sub_command failure, patterns matched in the output:', ['Success rate is 0 percent'])

Verify this works with NX-OS:

from genie.conf import Genie

# Initialize the testbed
Genie.init(testbed='/tmp/testbed.yaml')

# Connect to the NXOS switch
Genie.testbed.devices['nxos'].connect()

# Attempt to ping `10.0.0.2`, note that it passes the VRF and the ping is successful
Genie.testbed.devices['nxos'].ping('10.0.0.2', vrf='management')

Example output showing that it works on NXOS:

In [1]: from genie.conf import Genie 
   ...:  
   ...: # Initialize the testbed 
   ...: Genie.init(testbed='/tmp/testbed.yaml') 
   ...:  
   ...: # Connect to the NXOS switch 
   ...: Genie.testbed.devices['nxos'].connect() 
   ...:  
   ...: # Attempt to ping `10.0.0.2`, note that it passes the VRF and the ping is successful 
   ...: Genie.testbed.devices['nxos'].ping('10.0.0.2', vrf='management') 
   ...:                                                                                                                                                                                                                                                                                                                                                                                        
[2018-12-15 11:34:38,998] +++ nxos logfile /tmp/nxos-cli-20181215T113438998.log +++
[2018-12-15 11:34:38,999] +++ Unicon plugin nxos +++
[2018-12-15 11:34:39,005] +++ connection to spawn: ssh -l admin 10.0.0.2 -p 22, id: 139889341296144 +++
[2018-12-15 11:34:39,012] connection to nxos
[2018-12-15 11:34:39,006] ssh -l admin 10.0.0.2 -p 22
User Access Verification
Password: 

Bad terminal type: "xterm-256color". Will assume vt100.
Cisco NX-OS Software
Copyright (c) 2002-2018, Cisco Systems, Inc. All rights reserved.
Nexus 9000v software ("Nexus 9000v Software") and related documentation,
files or other reference materials ("Documentation") are
the proprietary property and confidential information of Cisco
Systems, Inc. ("Cisco") and are protected, without limitation,
pursuant to United States and International copyright and trademark
laws in the applicable jurisdiction which provide civil and criminal
penalties for copying or distribution without Cisco's authorization.

Any use or disclosure, in whole or in part, of the Nexus 9000v Software
or Documentation to any third party for any purposes is expressly
prohibited except as otherwise authorized by Cisco in writing.
The copyrights to certain works contained herein are owned by other
third parties and are used and distributed under license. Some parts
of this software may be covered under the GNU Public License or the
GNU Lesser General Public License. A copy of each such license is
available at
http://www.gnu.org/licenses/gpl.html and
http://www.gnu.org/licenses/lgpl.html
***************************************************************************
*  Nexus 9000v is strictly limited to use for evaluation, demonstration   *
*  and NX-OS education. Any use or disclosure, in whole or in part of     *
*  the Nexus 9000v Software or Documentation to any third party for any   *
*  purposes is expressly prohibited except as otherwise authorized by     *
*  Cisco in writing.                                                      *
***************************************************************************
nxos# 
[2018-12-15 11:34:40,521] +++ initializing handle +++
[2018-12-15 11:34:40,522] +++ nxos: executing command 'term length 0' +++
term length 0
nxos# 
[2018-12-15 11:34:40,535] +++ nxos: executing command 'term width 511' +++
term width 511
nxos# 
[2018-12-15 11:34:40,542] +++ nxos: executing command 'terminal session-timeout 0' +++
terminal session-timeout 0
nxos# 
[2018-12-15 11:34:40,550] +++ nxos: config +++
config term
Enter configuration commands, one per line. End with CNTL/Z.
nxos(config)# no logging console
nxos(config)# line console
nxos(config-console)# exec-timeout 0
nxos(config-console)# terminal width 511
nxos(config-console)# end
nxos# 
[2018-12-15 11:34:40,830] +++ nxos: ping +++
ping
Vrf context to use [default] :management
Target IP address or Hostname: 10.0.0.2
Repeat count [5] : 
Packet-size [56] : 
Timeout in seconds [2] : 
Sending interval in seconds [0] : 
Extended commands [no] : n
Sweep range of sizes [no] : n
Sending 5, 56-bytes ICMP Echos to 10.0.0.2
Timeout is 2 seconds, data pattern is 0xABCD

64 bytes from 10.0.0.2: icmp_seq=0 ttl=254 time=1.085 ms
64 bytes from 10.0.0.2: icmp_seq=1 ttl=254 time=0.821 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=254 time=0.839 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=254 time=0.887 ms
64 bytes from 10.0.0.2: icmp_seq=4 ttl=254 time=0.834 ms

--- 10.0.0.2 ping statistics ---
5 packets transmitted, 5 packets received, 0.00% packet loss
round-trip min/avg/max = 0.821/0.893/1.085 ms
nxos# 
Out[1]: 'ping\r\r\nVrf context to use [default] :management\r\nTarget IP address or Hostname: 10.0.0.2\r\nRepeat count [5] : \r\nPacket-size [56] : \r\nTimeout in seconds [2] : \r\nSending interval in seconds [0] : \r\nExtended commands [no] : n\r\nSweep range of sizes [no] : n\r\nSending 5, 56-bytes ICMP Echos to 10.0.0.2\r\nTimeout is 2 seconds, data pattern is 0xABCD\r\n\r\n64 bytes from 10.0.0.2: icmp_seq=0 ttl=254 time=1.085 ms\r\n64 bytes from 10.0.0.2: icmp_seq=1 ttl=254 time=0.821 ms\r\n64 bytes from 10.0.0.2: icmp_seq=2 ttl=254 time=0.839 ms\r\n64 bytes from 10.0.0.2: icmp_seq=3 ttl=254 time=0.887 ms\r\n64 bytes from 10.0.0.2: icmp_seq=4 ttl=254 time=0.834 ms\r\n\r\n--- 10.0.0.2 ping statistics ---\r\n5 packets transmitted, 5 packets received, 0.00% packet loss\r\nround-trip min/avg/max = 0.821/0.893/1.085 ms\r\n\r'

In [2]:

Regex used to validate device hostname is not strict enough

Hello,

I am using pyats and genie connection client in a python script to parse some commands output of network devices.

I realize that the regex used to validate the device hostname is not strict enough.
In fact when the actual device hostname contains a substring of the hostname parameter the connection succeed but i am expecting it to fail.

For example when the actual device hostname is "demo-vrouter1" and i use con = Device("vrouter1").connect(), I am expecting the connection to fail because vrouter1 does not strictly match demo-vrouter1.

Do i miss a configuraton option to make hostname validation more strict ?

Thanks,

Best regards,

is it possible to use console connection?

Hey there,

i find nothing about the list of protocols which is supported by pyATS for connecting to a device. I want to login a device through the console port, is it possible or i have to write my own connection class for pyATS? I mean something like this [+]

Again,
Thanks in advance, specially @jeaubin โค๏ธ ;)

pyats logs view | --port argumnet is not working

Can not user argumnet --port
clarifying.. this is from inside the pyats docker contaner

# pyats logs view --host localhost --port 8080 -v
or 
# pyats logs view --port 8080 -v

error

Logfile: /root/.pyats/archive/19-Dec/test_job.2019Dec06_12:50:49.819093.zip
Traceback (most recent call last):
  File "src/pyats/cli/base.py", line 202, in pyats.cli.base.Command.main
  File "src/pyats/cli/base.py", line 332, in pyats.cli.base.CommandWithSubcommands.run
  File "src/pyats/log/commands/logs.py", line 136, in pyats.log.commands.logs.ViewSubcommand.run
  File "src/pyats/log/commands/logs.py", line 157, in pyats.log.commands.logs.ViewSubcommand.run
UnboundLocalError: local variable 'displayed_port' referenced before assignment


local variable 'displayed_port' referenced before assignment

RFE: PDF Reports

Easypy can generate both xunit and an HTML log report which is great! Unfortunately, my build system (GitLab) can only render HTML if the repository is public (something I don't want to do) or by an xunit artifact. In my case, though, I'm already generating an xunit artifact for code quality of the Python code itself. The build system can render PDFs inline, though! This is probably a corner case for me, but maybe someone else would appreciate a native PDF report?

Prevent "Cannot find a reference" warnings

There is a pretty simple code:

from ats.topology import loader
cluster = loader.load('./testbeds/test.yaml')

And it works well.

From the other side, this code generates a lot of warnings from IDEs or static analysis. For instance, pylint will generate the following error: E1101: Module 'ats.topology.loader' has no 'load' member (no-member).

I believe this happens as pyATS is distributed via binary format and either pylint or PyCharm are not able to understand the runtime members of a module. As the result, either code completion nor static analysis are working properly.

Looks like a solution is the stub files - https://www.python.org/dev/peps/pep-0484/#stub-files. Maybe there are any other options we can discuss.

Anyway, I'm ready to contribute in this activity some development efforts.

getting error in a simple "show version" scenario

Hi there,

I think my problem is misunderstanding of pyATS, but I read and use sample codes which are available in pyATS repo.

the result of script is:

python test.py --testbed testbed.yaml
2019-01-10T17:17:42: %AETEST-INFO: Starting common setup
2019-01-10T17:17:42: %AETEST-INFO: Starting subsection check_topology
2019-01-10T17:17:42: %AETEST-INFO: The result of subsection check_topology is => PASSED
2019-01-10T17:17:42: %AETEST-INFO: Starting subsection establish_connections
2019-01-10T17:17:42: %AETEST-INFO: STEP 1: Connecting to ios-1
[2019-01-10 17:17:42,221] +++ ios-1 logfile /tmp/ios-1-default-20190110T171742221.log +++
[2019-01-10 17:17:42,221] +++ Unicon plugin ios +++
[2019-01-10 17:17:42,224] +++ connection to spawn: ssh -l admin 192.168.136.150, id: 140255415584080 +++
[2019-01-10 17:17:42,225] connection to ios-1
[2019-01-10 17:17:42,224] ssh -l admin 192.168.136.150
Password:
Password:

R2#

2019-01-10T17:18:53: %AETEST-INFO: STEP 1: Connecting to ios-1 - Errored
2019-01-10T17:18:53: %AETEST-ERROR: Caught exception during execution:
2019-01-10T17:18:53: %AETEST-ERROR: Traceback (most recent call last):
2019-01-10T17:18:53: %AETEST-ERROR:   File "src/unicon/statemachine/statemachine.py", line 683, in unicon.statemachine.statemachine.StateMachine.go_to
2019-01-10T17:18:53: %AETEST-ERROR:   File "src/unicon/statemachine/statetransition.py", line 479, in unicon.statemachine.statetransition.AnyStateTransition.do_transitions
2019-01-10T17:18:53: %AETEST-ERROR:   File "src/unicon/eal/dialogs.py", line 419, in unicon.eal.dialogs.Dialog.process
2019-01-10T17:18:53: %AETEST-ERROR:   File "src/unicon/eal/dialog_processor.py", line 659, in unicon.eal.dialog_processor.AlarmBasedDialogProcessor.process
2019-01-10T17:18:53: %AETEST-ERROR:   File "src/unicon/eal/dialog_processor.py", line 644, in unicon.eal.dialog_processor.AlarmBasedDialogProcessor.process
2019-01-10T17:18:53: %AETEST-ERROR:   File "src/unicon/eal/dialog_processor.py", line 546, in unicon.eal.dialog_processor.AlarmBasedDialogProcessor.expect_eval_statements
2019-01-10T17:18:53: %AETEST-ERROR:   File "src/unicon/eal/backend/pty_backend.py", line 131, in unicon.eal.backend.pty_backend.RawSpawn.read_update_buffer
2019-01-10T17:18:53: %AETEST-ERROR:   File "src/unicon/eal/backend/pty_backend.py", line 360, in unicon.eal.backend.pty_backend.RawPtySpawn.is_readable
2019-01-10T17:18:53: %AETEST-ERROR:   File "src/unicon/eal/backend/pty_backend.py", line 355, in unicon.eal.backend.pty_backend.RawPtySpawn.is_readable
2019-01-10T17:18:53: %AETEST-ERROR:   File "src/unicon/eal/dialog_processor.py", line 604, in unicon.eal.dialog_processor.AlarmBasedDialogProcessor.timeout_handler
2019-01-10T17:18:53: %AETEST-ERROR: TimeoutError: timeout occurred:
2019-01-10T17:18:53: %AETEST-ERROR:                               timeout value: 60
2019-01-10T17:18:53: %AETEST-ERROR:                               last_command: '123\r'
2019-01-10T17:18:53: %AETEST-ERROR:                              pattern: ['^.*?% (Bad passwords|Access denied|Authentication failed)', '^.*Login incorrect', '^.*([Uu]sername|[Ll]ogin): ?$', '^.*User Access Verification', '^.*[Pp]assword( for )?(\\S+)?: ?$', 'Escape character is .*\\n', '^.*RETURN to get started', 'Are you sure you want to continue connecting \\(yes/no\\)', '^.*(Connection refused|Connection reset by peer|Network is down|closed by remote host)', 'Received disconnect from .*:', 'Hit Enter to proceed:', '^(.*?)Press Ctrl\\+x to Exit the session', '^.*?% (Bad passwords|Access denied|Authentication failed)', '^.*([Uu]sername|[Ll]ogin): ?$', '^.*User Access Verification', '^.*[Pp]assword( for )?(\\S+)?: ?$', 'Password OK\\s*$', '^.*[Pp]assword( for )?(\\S+)?: ?$', 'rommon[\\s\\d]*>\\s?$', '^(.*?)(Router|Router-stby|Router-sdby|RouterRP|RouterRP-standby|ios-1-standby|ios-1-sdby|ios-1-stby|(S|s)witch|s(S|s)witch\\(standby\\)|Controller|ios|-Slot[0-9]+|ios-1)(\\(boot\\))*>\\s?$', '^(.*)\\(.*(con|cfg|ipsec-profile)\\S*\\)#\\s?$', '^(.*?)(Router|Router-stby|Router-sdby|RouterRP|RouterRP-standby|ios-1-standby|ios-1\\(standby\\)|ios-1-sdby|ios-1-stby|(S|s)witch|(S|s)witch\\(standby\\)|Controller|ios|-Slot[0-9]+|ios-1)(\\(boot\\))*#\\s?$', '^.*--\\s?[Mm]ore\\s?--.*', '^.*\\[confirm(\\(y/n\\))?\\]', '^.*\\[yes[/,][Nn][Oo]\\]\\s?:?$']
2019-01-10T17:18:53: %AETEST-ERROR:                              buffer:'\r\n\r\nR2#'
2019-01-10T17:18:53: %AETEST-ERROR:
2019-01-10T17:18:53: %AETEST-ERROR: The above exception was the direct cause of the following exception:
2019-01-10T17:18:53: %AETEST-ERROR:
2019-01-10T17:18:53: %AETEST-ERROR: Traceback (most recent call last):
2019-01-10T17:18:53: %AETEST-ERROR:   File "src/unicon/bases/connection.py", line 497, in unicon.bases.connection.Connection.connect
2019-01-10T17:18:53: %AETEST-ERROR:   File "src/unicon/bases/routers/connection_provider.py", line 146, in unicon.bases.routers.connection_provider.BaseSingleRpConnectionProvider.connect
2019-01-10T17:18:53: %AETEST-ERROR:   File "src/unicon/bases/routers/connection_provider.py", line 167, in unicon.bases.routers.connection_provider.BaseSingleRpConnectionProvider.establish_connection
2019-01-10T17:18:53: %AETEST-ERROR:   File "src/unicon/statemachine/statemachine.py", line 686, in unicon.statemachine.statemachine.StateMachine.go_to
2019-01-10T17:18:53: %AETEST-ERROR: unicon.core.errors.StateMachineError: Failed while bringing device to "any" state
2019-01-10T17:18:53: %AETEST-ERROR:
2019-01-10T17:18:53: %AETEST-ERROR: The above exception was the direct cause of the following exception:
2019-01-10T17:18:53: %AETEST-ERROR:
2019-01-10T17:18:53: %AETEST-ERROR: Traceback (most recent call last):
2019-01-10T17:18:53: %AETEST-ERROR:   File "test.py", line 27, in establish_connections
2019-01-10T17:18:53: %AETEST-ERROR:     ios1.connect()
2019-01-10T17:18:53: %AETEST-ERROR:   File "src/pyats/connections/manager.py", line 283, in pyats.connections.manager.ConnectionManager.connect
2019-01-10T17:18:53: %AETEST-ERROR:   File "src/unicon/bases/connection.py", line 501, in unicon.bases.connection.Connection.connect
2019-01-10T17:18:53: %AETEST-ERROR: unicon.core.errors.ConnectionError: failed to connect to ios-1
2019-01-10T17:18:53: %AETEST-INFO: +----------------------------------------------------------+
2019-01-10T17:18:53: %AETEST-INFO: |                       STEPS Report                       |
2019-01-10T17:18:53: %AETEST-INFO: +----------------------------------------------------------+
2019-01-10T17:18:53: %AETEST-INFO: STEP 1 - Connecting to ios-1                         Errored
2019-01-10T17:18:53: %AETEST-INFO: ------------------------------------------------------------
2019-01-10T17:18:53: %AETEST-INFO: The result of subsection establish_connections is => ERRORED
2019-01-10T17:18:53: %AETEST-INFO: The result of common setup is => ERRORED
2019-01-10T17:18:53: %AETEST-INFO: Starting testcase PingTestcase
2019-01-10T17:18:53: %AETEST-INFO: Blocking PingTestcase because common_setup did not pass.
2019-01-10T17:18:53: %AETEST-INFO: The result of testcase PingTestcase is => BLOCKED
2019-01-10T17:18:53: %AETEST-INFO: Starting common cleanup
2019-01-10T17:18:53: %AETEST-INFO: Starting subsection disconnect
2019-01-10T17:18:53: %AETEST-INFO: STEP 1: Disconnecting from ios-1
2019-01-10T17:19:05: %AETEST-INFO: STEP 1: Disconnecting from ios-1 - Passed
2019-01-10T17:19:05: %AETEST-INFO: +----------------------------------------------------------+
2019-01-10T17:19:05: %AETEST-INFO: |                       STEPS Report                       |
2019-01-10T17:19:05: %AETEST-INFO: +----------------------------------------------------------+
2019-01-10T17:19:05: %AETEST-INFO: STEP 1 - Disconnecting from ios-1                     Passed
2019-01-10T17:19:05: %AETEST-INFO: ------------------------------------------------------------
2019-01-10T17:19:05: %AETEST-INFO: The result of subsection disconnect is => PASSED
2019-01-10T17:19:05: %AETEST-INFO: The result of common cleanup is => PASSED
2019-01-10T17:19:05: %AETEST-INFO: +------------------------------------------------------------------------------+
2019-01-10T17:19:05: %AETEST-INFO: |                               Detailed Results                               |
2019-01-10T17:19:05: %AETEST-INFO: +------------------------------------------------------------------------------+
2019-01-10T17:19:05: %AETEST-INFO:  SECTIONS/TESTCASES                                                      RESULT
2019-01-10T17:19:05: %AETEST-INFO: --------------------------------------------------------------------------------
2019-01-10T17:19:05: %AETEST-INFO: .
2019-01-10T17:19:05: %AETEST-INFO: |-- common_setup                                                        ERRORED
2019-01-10T17:19:05: %AETEST-INFO: |   |-- check_topology                                                   PASSED
2019-01-10T17:19:05: %AETEST-INFO: |   `-- establish_connections                                           ERRORED
2019-01-10T17:19:05: %AETEST-INFO: |       `-- Step 1: Connecting to ios-1                                 ERRORED
2019-01-10T17:19:05: %AETEST-INFO: |-- PingTestcase                                                        BLOCKED
2019-01-10T17:19:05: %AETEST-INFO: `-- common_cleanup                                                       PASSED
2019-01-10T17:19:05: %AETEST-INFO:     `-- disconnect                                                       PASSED
2019-01-10T17:19:05: %AETEST-INFO:         `-- Step 1: Disconnecting from ios-1                             PASSED
2019-01-10T17:19:05: %AETEST-INFO: +------------------------------------------------------------------------------+
2019-01-10T17:19:05: %AETEST-INFO: |                                   Summary                                    |
2019-01-10T17:19:05: %AETEST-INFO: +------------------------------------------------------------------------------+
2019-01-10T17:19:05: %AETEST-INFO:  Number of ABORTED                                                            0
2019-01-10T17:19:05: %AETEST-INFO:  Number of BLOCKED                                                            1
2019-01-10T17:19:05: %AETEST-INFO:  Number of ERRORED                                                            1
2019-01-10T17:19:05: %AETEST-INFO:  Number of FAILED                                                             0
2019-01-10T17:19:05: %AETEST-INFO:  Number of PASSED                                                             1
2019-01-10T17:19:05: %AETEST-INFO:  Number of PASSX                                                              0
2019-01-10T17:19:05: %AETEST-INFO:  Number of SKIPPED                                                            0
2019-01-10T17:19:05: %AETEST-INFO: --------------------------------------------------------------------------------

I just want to write a simple test for one router, read the out put of show version command and print/process it, like a Hello World! sample code.

Thanks in advance.

test.zip

running package.module directly under aetest & easypy

I have the following setup:

# files
$ tree fooo/
fooo/
โ”œโ”€โ”€ __init__.py
โ”œโ”€โ”€ alisa.py
โ””โ”€โ”€ foo.py
$ python fooo/alisa.py 
Traceback (most recent call last):
  File "fooo/alisa.py", line 5, in <module>
    from fooo.foo import fooo
ModuleNotFoundError: No module named 'fooo'

$ cat -b  fooo/__init__.py fooo/alisa.py fooo/foo.py 
     1	from ats import aetest

     2	from ats.aetest import test

     3	from fooo.foo import fooo


     4	class Smoke(aetest.Testcase):
     5	    @test
     6	    def test_one(self):
     7	        fooo()
     8	        print('Alisa is fine!')


     9	class Health(aetest.Testcase):
    10	    @test
    11	    def status(self):
    12	        print('Alisa\'s health is fine!')


    13	if __name__ == '__main__':
    14	    aetest.main()
     1	def fooo():
     2	    print('fooo')

Is there a chance to run a test without modifying a sys.path? As alisa.py is within a package, looks like it has to understand the context based packages logic.

Are there any exit_commands?

I are there any property that can be run when i exit/disconnect from a device?

When we connect we can use

devices:
    mydevice:
        connections:
            vty:
                init_config_commands: []
                init_exec_commands: []

Where is TopologyGrapher now?

What happened to ats.topology.grapher.TopologyGrapher? There are some docs that aren't linked from the current docs, but they're still available at /latest if you go looking (though the page indicates it's for 4.0.1). The page for TopologyGrapher is here, but I can't find it referenced in the 5.0.x documentation, and dir(ats.topology) doesn't have grapher listed:

Python 3.6.7 (default, Nov 27 2018, 20:59:50) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.2.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import pyats.topology.grapher
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-1-5ba41f10988a> in <module>
----> 1 import pyats.topology.grapher

ModuleNotFoundError: No module named 'pyats.topology.grapher'

In [2]: import pyats.topology

In [3]: dir(pyats.topology)
Out[3]: 
['Device',
 'DeviceBase',
 'Interface',
 'InterfaceBase',
 'Link',
 'LinkBase',
 'Testbed',
 'TestbedBase',
 '__author__',
 '__builtins__',
 '__cached__',
 '__contact__',
 '__copyright__',
 '__doc__',
 '__file__',
 '__loader__',
 '__name__',
 '__package__',
 '__path__',
 '__spec__',
 '__version__',
 'bases',
 'device',
 'exceptions',
 'interface',
 'link',
 'loader',
 'schema',
 'testbed']

In [4]:

Was it completely removed in 5.0.x? Is there an alternative, or is this functionality that I need to go build myself?

Thanks!

Login fail when unprivileged user log in

When the user provided on the testbed haven't conf privileges the login fails, and by the execution output, I see that the framework tries to configure the device with the following output:

image

Looking at the documentation i haven't found anything about the framework issuing commands without being explicit configured, ie device.configure() or device.execute().
I would like to know if it's possible to block that behavior and use the framework with an unprivileged user

Please fix some other pylint errors

After 5.0.0 pyATS release, some pylint's violations disappear (described in #8). But some of them still exist. Please solve them if possible.

Errors:

  • E1101: Module 'pyats.topology.loader' has no 'load' member (no-member)
  • E0611: No name 'SubCommandFailure' in module 'unicon.core.errors' (no-name-in-module)
  • Module 'pyats.easypy' has no 'run' member (no-member)

Versions:

  • pyats==5.0.1
  • unicon==3.4.0
  • pylint==2.1.1

pyats validate testbed: Raise all errors at the same time

If there are several errors, the only first error is displayed during the validation.
Please check out the sample below:

(pyats) ~/tmp pyats validate testbed  tb.yaml 
Loading testbed file: tb.yaml
--------------------------------------------------------------------------------

devices.vm: Missing keys: ['connections']

(pyats) ~/tmp cat tb.yaml 
devices:
    vm:
      os: 'linux'
      dd:
        f: a
      type: 'linux'
      ddd: ddd
(pyats) ~/tmp 

It will be great if we see all possible errors at the same time.

Deprecation warning "section.id is deprecated and replaced by section.uid"

I downloaded and ran the pyats sample scripts from Cisco's DevNet GitHub repo and noticed that there was a deprecation warning.

DeprecationWarning: Starting v3.0.0, section.id is deprecated and replaced by section.uid. Please modify your scripts. This will be removed next release
  aetest.main()"

It seems that even with the most simple of test scripts (see below), you still get this deprecation warning.

from ats import aetest 

class TestPyats(aetest.Testcase):              
    @aetest.test       
    def test(self):    
        pass           

if __name__ == '__main__':                     
    aetest.main()
$ python --version
Python 3.4.7
$ python test.py
2017-12-14T14:53:03: %AETEST-INFO: Starting testcase TestPyats
test.py:9: DeprecationWarning: Starting v3.0.0, section.id is deprecated and replaced by section.uid. Please modify your scripts. This will be removed next release
  aetest.main()
2017-12-14T14:53:03: %AETEST-INFO: Starting section test
2017-12-14T14:53:03: %AETEST-INFO: The result of section test is => PASSED
2017-12-14T14:53:03: %AETEST-INFO: The result of testcase TestPyats is => PASSED
2017-12-14T14:53:03: %AETEST-INFO: +------------------------------------------------------------------------------+
2017-12-14T14:53:03: %AETEST-INFO: |                               Detailed Results                               |
2017-12-14T14:53:03: %AETEST-INFO: +------------------------------------------------------------------------------+
2017-12-14T14:53:03: %AETEST-INFO:  SECTIONS/TESTCASES                                                      RESULT   
2017-12-14T14:53:03: %AETEST-INFO: --------------------------------------------------------------------------------
2017-12-14T14:53:03: %AETEST-INFO: .
2017-12-14T14:53:03: %AETEST-INFO: `-- TestPyats                                                            PASSED
2017-12-14T14:53:03: %AETEST-INFO:     `-- test                                                             PASSED
2017-12-14T14:53:03: %AETEST-INFO: +------------------------------------------------------------------------------+
2017-12-14T14:53:03: %AETEST-INFO: |                                   Summary                                    |
2017-12-14T14:53:03: %AETEST-INFO: +------------------------------------------------------------------------------+
2017-12-14T14:53:03: %AETEST-INFO:  Number of ABORTED                                                            0 
2017-12-14T14:53:03: %AETEST-INFO:  Number of BLOCKED                                                            0 
2017-12-14T14:53:03: %AETEST-INFO:  Number of ERRORED                                                            0 
2017-12-14T14:53:03: %AETEST-INFO:  Number of FAILED                                                             0 
2017-12-14T14:53:03: %AETEST-INFO:  Number of PASSED                                                             1 
2017-12-14T14:53:03: %AETEST-INFO:  Number of PASSX                                                              0 
2017-12-14T14:53:03: %AETEST-INFO:  Number of SKIPPED                                                            0 
2017-12-14T14:53:03: %AETEST-INFO: --------------------------------------------------------------------------------

Invalid easy_config.yaml input for plugins

I have installed pyATS via pip3. I will get this error when i import aetest:

(pyats)  root ~/pytest_tmp # python3
Python 3.5.1+ (default, Mar 30 2016, 22:46:26)
[GCC 5.3.1 20160330] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from ats import aetest
Traceback (most recent call last):
  File "src/pyats/easypy/config/schema.py", line 43, in pyats.easypy.config.schema.validate_plugins
  File "/usr/lib/python3.5/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 910, in exec_module
  File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
  File "src/pyats/easypy/plugins/kleenex.py", line 13, in init pyats.easypy.plugins.kleenex
ImportError: cannot import name validate_clean_devices

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/hamid/pyats/lib/python3.5/site-packages/pyats/aetest/__init__.py", line 31, in <module>
    from .main import main
  File "src/pyats/aetest/main.py", line 18, in init pyats.aetest.main
  File "src/pyats/aetest/utils/pause.py", line 23, in init pyats.aetest.utils.pause
  File "/home/hamid/pyats/lib/python3.5/site-packages/pyats/easypy/__init__.py", line 7, in <module>
    from .main import _default_runtime, main
  File "src/pyats/easypy/main.py", line 313, in init pyats.easypy.main
  File "src/pyats/easypy/main.py", line 97, in pyats.easypy.main.EasypyRuntime.__init__
  File "src/pyats/easypy/config/manager.py", line 61, in pyats.easypy.config.manager.Configuration.load
  File "src/pyats/utils/yaml/loader.py", line 107, in pyats.utils.yaml.loader.Loader.load
  File "src/pyats/utils/schemaengine.py", line 296, in pyats.utils.schemaengine.Schema.validate
  File "src/pyats/utils/schemaengine.py", line 293, in pyats.utils.schemaengine.Schema.validate
  File "src/pyats/utils/schemaengine.py", line 234, in pyats.utils.schemaengine.Schema.validate
  File "src/pyats/utils/schemaengine.py", line 480, in pyats.utils.schemaengine.Use.validate
  File "src/pyats/utils/schemaengine.py", line 478, in pyats.utils.schemaengine.Use.validate
  File "src/pyats/easypy/config/schema.py", line 51, in pyats.easypy.config.schema.validate_plugins
pyats.utils.exceptions.SchemaError: Invalid easy_config.yaml input for plugins
>>>

also, there is a big question for me, why don't you publish this best automation tools/framework as a public framework ?

Alcatel-Lucent(Nokia) router ssh connect timeout

I tried to use pyats to connect Alcatel-Lucent(Nokia) router but ssh timeouts. What is going wrong ?

my tb.yaml

devices:
    SR1-Services-Leaf2:
        os: sros
        type: sros
        connections:
            cli:
                ip: 135.228.1.225
                protocol: ssh
            netconf:
                ip: 135.228.1.225
                port: 830
        credentials:
            default:
                password: Nokia2018!
                username: admin

my script:

from genie.testbed import load
testbed = load("./tb.yaml")
dev = testbed.devices["SR1-Services-Leaf2"]
dev.connect(log_stdout = True, via="cli")

run log

(pyats) [sshanggu@atims1 bell.ca]$ python ./NokiaCLITest.py 
[2020-02-13 15:25:19,427] +++ SR1-Services-Leaf2 logfile /tmp/SR1-Services-Leaf2-cli-20200213T152519425.log +++
[2020-02-13 15:25:19,427] +++ Unicon plugin sros +++

[email protected]'s password: 
[2020-02-13 15:25:19,496] +++ connection to spawn: ssh -l admin 135.228.1.225, id: 140098714212000 +++
[2020-02-13 15:25:19,497] connection to SR1-Services-Leaf2


[]
A:admin@SR1-Services-Leaf2# 
[2020-02-13 15:25:19,709] +++ initializing handle +++
//
INFO: CLI #2051: Switching to the classic CLI engine
*A:SR1-Services-Leaf2# Traceback (most recent call last):
  File "src/unicon/statemachine/statemachine.py", line 719, in unicon.statemachine.statemachine.StateMachine.go_to
  File "src/unicon/statemachine/statetransition.py", line 217, in unicon.statemachine.statetransition.StateTransition.do_transitions
  File "src/unicon/eal/dialogs.py", line 430, in unicon.eal.dialogs.Dialog.process
  File "src/unicon/eal/dialog_processor.py", line 300, in unicon.eal.dialog_processor.SimpleDialogProcessor.process
  File "src/unicon/eal/dialog_processor.py", line 259, in unicon.eal.dialog_processor.SimpleDialogProcessor.timeout_handler
unicon.core.errors.TimeoutError: timeout occurred:
              timeout value: 60
              last_command: '//\r'
             pattern: ['^A:SR1-Services-Leaf2(>.*)?#\\s?$']
             buffer:'//\r\nINFO: CLI #2051: Switching to the classic CLI engine\r\n*A:SR1-Services-Leaf2# '

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "src/unicon/bases/connection.py", line 623, in unicon.bases.connection.Connection.connect
  File "src/unicon/bases/routers/connection_provider.py", line 146, in unicon.bases.routers.connection_provider.BaseSingleRpConnectionProvider.connect
  File "/home/sshanggu/pyats/lib/python3.7/site-packages/unicon/plugins/sros/connection_provider.py", line 21, in init_handle
    timeout=con.connection_timeout)
  File "src/unicon/statemachine/statemachine.py", line 722, in unicon.statemachine.statemachine.StateMachine.go_to
unicon.core.errors.StateMachineError: Failed while bringing device to "classiccli" state

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "./NokiaCLITest.py", line 7, in <module>
    dev.connect(log_stdout = True, via="cli")
  File "src/genie/conf/base/device.py", line 599, in genie.conf.base.device.Device.connect
  File "src/pyats/connections/manager.py", line 334, in pyats.connections.manager.ConnectionManager.connect
  File "src/unicon/bases/connection.py", line 629, in unicon.bases.connection.Connection.connect
unicon.core.errors.ConnectionError: failed to connect to SR1-Services-Leaf2
Failed while bringing device to "classiccli" state
(pyats) [sshanggu@atims1 bell.ca]$ 

Not able to connect to device through proxy

I tried to connect to a router via a jumphost by following the guideline here:
https://pubhub.devnetcloud.com/media/unicon/docs/user_guide/proxy.html

Here's my script:
from genie.testbed import load
from pyats.topology import loader

tb = load('testbed2.yaml')
pe1 = tb.devices['router1']
pe1.connect()
pe1.execute('show version')

Here's the testbed file:
testbed:
name: JUMPHOST_TESTBED
devices:
linux1:
os: linux
type: linux
credentials:
default:
username: aaaa
password: bbbb
connections:
console:
protocol: ssh
ip: y.y.y.y
port: 2222

router1:
os: iosxr
type: router
credentials:
default:
username: aaaa
password: bbbb
connections:
default:
protocol: telnet
ip: x.x.x.x
port: 23
sshtunnel:
host: linux1

I can connect to the router, but not able to execute any command after.

pyATS offline install via pip install

I'm trying to install pyATS which does not have internet accesss. I hope a have all files need to install pyATS. I used the pip download function .Created a req.txt and try to install it via pip install

pip install --no-cache-dir --no-index --find-links . -r req_pyATS.txt

req_pyATS.txt

aiohttp==3.6.2                                                         
async-timeout==3.0.1                                                   
attrs==19.3.0                                                          
certifi==2019.11.28                                                    
chardet==3.0.4                                                         
dill==0.3.1.1                                                          
distro==1.4.0                                                          
idna==2.9                                                              
Jinja2==2.11.1                                                         
junit-xml==1.9                                                         
MarkupSafe==1.1.1                                                      
multidict==4.7.5                                                       
pathspec==0.7.0                                                        
psutil==5.7.0                                                          
PyYAML==5.3.1                                                          
requests==2.23.0                                                       
six==1.14.0                                                            
unicon==20.2                                                           
unicon.plugins==20.2                                                   
urllib3==1.25.8                                                        
yamllint==1.21.0                                                       
yarl==1.4.2                                                            
pyats==20.2.1                                                          
pyats.aereport==20.2                                                   
pyats.aetest==20.2                                                     
pyats.async==20.2                                                      
pyats.connections==20.2                                                
pyats.datastructures==20.2                                             
pyats.easypy==20.2                                                     
pyats.kleenex==20.2                                                    
pyats.log==20.2                                                        
pyats.reporter==20.2.2                                                 
pyats.results==20.2                                                    
pyats.tcl==20.2                                                        
pyats.topology==20.2                                                   
pyats.utils==20.2                                                      
Looking in links: .
Requirement already satisfied: aiohttp==3.6.2 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages (from -r req_pyATS.txt (line 1)) (3.6.2)
Requirement already satisfied: async-timeout==3.0.1 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages (from -r req_pyATS.txt (line 2)) (3.0.1)
Requirement already satisfied: attrs==19.3.0 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages (from -r req_pyATS.txt (line 3)) (19.3.0)
Requirement already satisfied: certifi==2019.11.28 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages (from -r req_pyATS.txt (line 4)) (2019.11.28)
Requirement already satisfied: chardet==3.0.4 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages (from -r req_pyATS.txt (line 5)) (3.0.4)
Requirement already satisfied: dill==0.3.1.1 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages (from -r req_pyATS.txt (line 6)) (0.3.1.1)
Requirement already satisfied: distro==1.4.0 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages (from -r req_pyATS.txt (line 7)) (1.4.0)
Requirement already satisfied: idna==2.9 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages (from -r req_pyATS.txt (line 8)) (2.9)
Requirement already satisfied: Jinja2==2.11.1 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages/Jinja2-2.11.1-py3.7.egg (from -r req_pyATS.txt (line 9)) (2.11.1)
Requirement already satisfied: junit-xml==1.9 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages (from -r req_pyATS.txt (line 10)) (1.9)
Requirement already satisfied: MarkupSafe==1.1.1 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages/MarkupSafe-1.1.1-py3.7-linux-x86_64.egg (from -r req_pyATS.txt (line 11)) (1.1.1)
Requirement already satisfied: multidict==4.7.5 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages (from -r req_pyATS.txt (line 12)) (4.7.5)
Requirement already satisfied: pathspec==0.7.0 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages (from -r req_pyATS.txt (line 13)) (0.7.0)
Requirement already satisfied: psutil==5.7.0 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages (from -r req_pyATS.txt (line 14)) (5.7.0)
Requirement already satisfied: PyYAML==5.3.1 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages (from -r req_pyATS.txt (line 15)) (5.3.1)
Requirement already satisfied: requests==2.23.0 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages (from -r req_pyATS.txt (line 16)) (2.23.0)
Requirement already satisfied: six==1.14.0 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages (from -r req_pyATS.txt (line 17)) (1.14.0)
Requirement already satisfied: unicon==20.2 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages (from -r req_pyATS.txt (line 18)) (20.2)
Requirement already satisfied: unicon.plugins==20.2 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages (from -r req_pyATS.txt (line 19)) (20.2)
Requirement already satisfied: urllib3==1.25.8 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages (from -r req_pyATS.txt (line 20)) (1.25.8)
Requirement already satisfied: yamllint==1.21.0 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages (from -r req_pyATS.txt (line 21)) (1.21.0)
Requirement already satisfied: yarl==1.4.2 in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages (from -r req_pyATS.txt (line 22)) (1.4.2)
Collecting pyats==20.2.1 (from -r req_pyATS.txt (line 23))
Collecting pyats.aereport==20.2 (from -r req_pyATS.txt (line 24))
Collecting pyats.aetest==20.2 (from -r req_pyATS.txt (line 25))
Collecting pyats.async==20.2 (from -r req_pyATS.txt (line 26))
Collecting pyats.connections==20.2 (from -r req_pyATS.txt (line 27))
Collecting pyats.datastructures==20.2 (from -r req_pyATS.txt (line 28))
Collecting pyats.easypy==20.2 (from -r req_pyATS.txt (line 29))
Collecting pyats.kleenex==20.2 (from -r req_pyATS.txt (line 30))
Collecting pyats.log==20.2 (from -r req_pyATS.txt (line 31))
Collecting pyats.reporter==20.2.2 (from -r req_pyATS.txt (line 32))
Collecting pyats.results==20.2 (from -r req_pyATS.txt (line 33))
Collecting pyats.tcl==20.2 (from -r req_pyATS.txt (line 34))
Collecting pyats.topology==20.2 (from -r req_pyATS.txt (line 35))
Collecting pyats.utils==20.2 (from -r req_pyATS.txt (line 36))
Requirement already satisfied: setuptools in /home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages (from pyats.easypy==20.2->-r req_pyATS.txt (line 29)) (45.2.0)
Installing collected packages: pyats, pyats.results, pyats.datastructures, pyats.log, pyats.aereport, pyats.async, pyats.connections, pyats.topology, pyats.utils, pyats.aetest, pyats.kleenex, pyats.easypy, pyats.reporter, pyats.tcl
ERROR: Exception:
Traceback (most recent call last):
  File "/home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages/pip/_internal/cli/base_command.py", line 188, in main
    status = self.run(options, args)
  File "/home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages/pip/_internal/commands/install.py", line 407, in run
    use_user_site=options.use_user_site,
  File "/home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages/pip/_internal/req/__init__.py", line 58, in install_given_reqs
    **kwargs
  File "/home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages/pip/_internal/req/req_install.py", line 928, in install
    use_user_site=use_user_site, pycompile=pycompile,
  File "/home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages/pip/_internal/req/req_install.py", line 461, in move_wheel_files
    warn_script_location=warn_script_location,
  File "/home/XXX/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages/pip/_internal/wheel.py", line 434, in move_wheel_files
    assert info_dir, "%s .dist-info directory not found" % req

Can someone help me out ?

Failed to load the datafile

When running the 1st example from the Genie docs -- demo1_harness_simple_job.py -- Im getting an error about loading a datafile.

(base) root@9d5025edcdf5:/opt/examples/libraries/harness_simple# pyats run job demo1_harness_simple_job.py --testbed-file eveng-lab-001.yml
.
.
2020-02-26T22:18:18: %EASYPY-ERROR: pyats.aetest.exceptions.DatafileError: Failed to load the datafile '/opt/conda/lib/python3.7/site-packages/genie/libs/sdk/genie_yamls/nxos/trigger_datafile_nxos.yaml'

However I can confirm this file is present.

ls -l /opt/conda/lib/python3.7/site-packages/genie/libs/sdk/genie_yamls/nxos/trigger_datafile_nxos.yaml

Am i missing something simple?

Version Info:

 python
Python 3.7.4 (default, Aug 13 2019, 20:35:49) 
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 
(base) root@9d5025edcdf5:/opt/examples/libraries/harness_simple# pip freeze | grep -E "genie|pyats"
genie==20.2
genie.libs.conf==20.2
genie.libs.filetransferutils==20.2
genie.libs.ops==20.2
genie.libs.parser==20.2
genie.libs.robot==20.2
genie.libs.sdk==20.2
genie.telemetry==20.2
genie.trafficgen==20.2
pyats==20.2
pyats.aereport==20.2
pyats.aetest==20.2
pyats.async==20.2
pyats.connections==20.2
pyats.datastructures==20.2
pyats.easypy==20.2
pyats.kleenex==20.2
pyats.log==20.2
pyats.reporter==20.2
pyats.results==20.2
pyats.robot==20.2
pyats.tcl==20.2
pyats.topology==20.2
pyats.utils==20.2

pyats will not install using python3.8

Requirements state

pyATS currently supports Python 3.4+ on Linux & Mac systems.

python3.8 -m pip install pyats
ERROR: Could not find a version that satisfies the requirement pyats (from versions: none)
ERROR: No matching distribution found for pyats

I expect this to install pyats, or state that it's installed already. Similar to this output for python3.7

python3.7 -m pip install pyats
Requirement already satisfied: pyats in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (19.12)
Requirement already satisfied: pyats.aetest<19.13.0,>=19.12.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats) (19.12)
Requirement already satisfied: pyats.log<19.13.0,>=19.12.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats) (19.12)
Requirement already satisfied: pyats.tcl<19.13.0,>=19.12.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats) (19.12)
Requirement already satisfied: pyats.reporter<19.13.0,>=19.12.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats) (19.12)
Requirement already satisfied: pyats.aereport<19.13.0,>=19.12.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats) (19.12)
Requirement already satisfied: pyats.datastructures<19.13.0,>=19.12.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats) (19.12)
Requirement already satisfied: pyats.topology<19.13.0,>=19.12.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats) (19.12)
Requirement already satisfied: pyats.kleenex<19.13.0,>=19.12.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats) (19.12)
Requirement already satisfied: pyats.async<19.13.0,>=19.12.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats) (19.12)
Requirement already satisfied: pyats.connections<19.13.0,>=19.12.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats) (19.12)
Requirement already satisfied: pyats.easypy<19.13.0,>=19.12.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats) (19.12)
Requirement already satisfied: pyats.results<19.13.0,>=19.12.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats) (19.12)
Requirement already satisfied: pyats.utils<19.13.0,>=19.12.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats) (19.12)
Requirement already satisfied: pyyaml in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats.aetest<19.13.0,>=19.12.0->pyats) (5.1.2)
Requirement already satisfied: jinja2>=2.9 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats.aetest<19.13.0,>=19.12.0->pyats) (2.10.1)
Requirement already satisfied: aiohttp in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats.log<19.13.0,>=19.12.0->pyats) (3.6.2)
Requirement already satisfied: psutil in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats.aereport<19.13.0,>=19.12.0->pyats) (5.6.3)
Requirement already satisfied: junit-xml in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats.aereport<19.13.0,>=19.12.0->pyats) (1.8)
Requirement already satisfied: yamllint in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats.topology<19.13.0,>=19.12.0->pyats) (1.20.0)
Requirement already satisfied: distro in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats.kleenex<19.13.0,>=19.12.0->pyats) (1.4.0)
Requirement already satisfied: requests in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats.kleenex<19.13.0,>=19.12.0->pyats) (2.22.0)
Requirement already satisfied: unicon<19.13.0,>=19.12.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats.connections<19.13.0,>=19.12.0->pyats) (19.12)
Requirement already satisfied: setuptools in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyats.easypy<19.13.0,>=19.12.0->pyats) (41.0.1)
Requirement already satisfied: MarkupSafe>=0.23 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from jinja2>=2.9->pyats.aetest<19.13.0,>=19.12.0->pyats) (1.1.1)
Requirement already satisfied: multidict<5.0,>=4.5 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from aiohttp->pyats.log<19.13.0,>=19.12.0->pyats) (4.7.4)
Requirement already satisfied: async-timeout<4.0,>=3.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from aiohttp->pyats.log<19.13.0,>=19.12.0->pyats) (3.0.1)
Requirement already satisfied: chardet<4.0,>=2.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from aiohttp->pyats.log<19.13.0,>=19.12.0->pyats) (3.0.4)
Requirement already satisfied: attrs>=17.3.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from aiohttp->pyats.log<19.13.0,>=19.12.0->pyats) (19.1.0)
Requirement already satisfied: yarl<2.0,>=1.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from aiohttp->pyats.log<19.13.0,>=19.12.0->pyats) (1.4.2)
Requirement already satisfied: six in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from junit-xml->pyats.aereport<19.13.0,>=19.12.0->pyats) (1.12.0)
Requirement already satisfied: pathspec>=0.5.3 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from yamllint->pyats.topology<19.13.0,>=19.12.0->pyats) (0.7.0)
Requirement already satisfied: certifi>=2017.4.17 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from requests->pyats.kleenex<19.13.0,>=19.12.0->pyats) (2019.6.16)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from requests->pyats.kleenex<19.13.0,>=19.12.0->pyats) (1.24.3)
Requirement already satisfied: idna<2.9,>=2.5 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from requests->pyats.kleenex<19.13.0,>=19.12.0->pyats) (2.8)
Requirement already satisfied: unicon.plugins<19.13.0,>=19.12.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from unicon<19.13.0,>=19.12.0->pyats.connections<19.13.0,>=19.12.0->pyats) (19.12.1)
Requirement already satisfied: dill in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from unicon<19.13.0,>=19.12.0->pyats.connections<19.13.0,>=19.12.0->pyats) (0.3.1.1)

UnboundLocalError: local variable 'vrf_dict' referenced before assignment

Hello,

I am facing an issue when using pyats and genie to parse VRF config on cisco CSR1000v device (iosxe).

pyats : 19.12
genie : 19.12

In fact the issue occurs when the VRF is being deleted by the router.

Below the output of the device of the command show vrf detail

VRF DEMO (VRF Id = 12); default RD 65001:1; default VPNID <not set>; being deleted
  Description: demo
  New CLI format, supports multiple address-families
  Flags: 0x180D
  No interfaces
Address family ipv4 unicast (Table ID = 0xC); being deleted:
  Flags: 0x1
  No Export VPN route-target communities
  No Import VPN route-target communities
  No import route-map
  No global export route-map
  No export route-map
  VRF label distribution protocol: not configured
  VRF label allocation mode: per-prefix
Address family ipv6 unicast not active
Address family ipv4 multicast not active
Address family ipv6 multicast not active


* Being deleted

After analysing the exception raised by the genie parser, i identify the issue is due to the fact that the regex used to parse the VRF details output fails for the first attributes parsing but succeed for the desription line causing an UnboundLocalError on the variable vrf_dict because the variable was not initialzed at the top level of the file.

FInd below the execption raised


            # Description: desc
            m = p12.match(line)
            if m:
                groups = m.groupdict()
>               vrf_dict.update({'description': groups['desc']})
E               UnboundLocalError: local variable 'vrf_dict' referenced before assignment

../../../.virtualenvs/.../lib/python3.6/site-packages/genie/libs/parser/iosxe/show_vrf.py:464: UnboundLocalError

Is it possible to review the parser to consider cases when Cisco output VRF being deleted like in my scenario.

In fact, the VRF parser should not try to retrieve the description if it fails to get the VRF name or the vrf_dict variable should be initialized at the top level of the file.

Any suggestion ?

Thanks,

Best regards,

Cannot learn config for ios device

'# pyats learn config --testbed-file my.yaml'
Learning '['config']' on devices '['S1']'
0%| | 0/1 [00:00<?, ?it/s]

Could not find the API under ios, and common'

pdb.set_trace() throws exception when "pyats run job ..."

pdb.set_trace() in my_tests.py file results in exception when it is invoked by pyats run job my_job.py --testbed-file ./my_tb.yaml.

my_job.py:

  import os
  mypath = os.path.dirname(__file__)
  def main(runtime):
     script = os.path.join(mypath, 'my_tests.py')
     runtime.tasks.run(script)

my_tests.py:

from pyats import aetest
from genie.testbed import load
class CommonSetup(aetest.CommonSetup):
    @aetest.subsection
    def connect_tb_devices(self, testbed):
        self.parent.parameters['testbed'] = testbed = load(testbed)
        **pdb.set_trace()**

        # connect testbed devices
        for dev in testbed.devices.values():
            dev.connect()
            dev.mdcli_execute("environment more false")

Exception:

-> for dev in testbed.devices.values():
(Pdb) 
2020-03-11T09:44:45: %AETEST-ERROR: Caught an exception while executing subsection connect_tb_devices:
2020-03-11T09:44:45: %AETEST-ERROR: Traceback (most recent call last):
2020-03-11T09:44:45: %AETEST-ERROR:   File "/home/sshanggu/bell.ca/my_tests.py", line 37, in connect_tb_devices
2020-03-11T09:44:45: %AETEST-ERROR:     for dev in testbed.devices.values():
2020-03-11T09:44:45: %AETEST-ERROR:   File "/home/sshanggu/bell.ca/my_tests.py", line 37, in connect_tb_devices
2020-03-11T09:44:45: %AETEST-ERROR:     for dev in testbed.devices.values():
2020-03-11T09:44:45: %AETEST-ERROR:   File "/usr/local/lib/python3.7/bdb.py", line 88, in trace_dispatch
2020-03-11T09:44:45: %AETEST-ERROR:     return self.dispatch_line(frame)
2020-03-11T09:44:45: %AETEST-ERROR:   File "/usr/local/lib/python3.7/bdb.py", line 113, in dispatch_line
2020-03-11T09:44:45: %AETEST-ERROR:     if self.quitting: raise BdbQuit
2020-03-11T09:44:45: %AETEST-ERROR: bdb.BdbQuit
2020-03-11T09:44:45: %AETEST-INFO: The result of subsection connect_tb_devices is => ERRORED
2020-03-11T09:44:45: %AETEST-INFO: The result of common setup is => ERRORED

Support of "idrac" os connection

Hello everyone! I want to execute some ssh commands on idrac (integrated dell remote access controller) os but neither of available connections help me so far.

According to unicon official docs https://pubhub.devnetcloud.com/media/pyats-packages/docs/unicon/user_guide/introduction.html#supported-platforms it does not support the idrac platform.

Do we have support of idrac os somewhere (maybe in other packages)? Or is it planning to be introduced in the future? Thanks!

Run Time format

What have happen to the "Run Time format" in the HTML report?

i use easypy test_job.py -html_logs html_folder to generate the report.

Now the format is in seconds.milliseconds
Before h:mm:ss

runtime_fromat

Login fails when the device hostname differs from testbed file

When the device hostname differs greatly from the device name on the testbed file the framework fails to recognize the login.
In the trace that follows its possible to see that the connection succeeds, but the library fails to recognize the login, because the regex pattern doesn't match a different hostname
Follow the error trace:

`Python 3.6.8 (default, Jan 14 2019, 11:02:34)
[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]] on linux
Type "help", "copyright", "credits" or "license" for more information.

from pyats.topology import loader
testbed = loader.load('testbed.yaml')
testbed.devices['R1'].connect()
[2019-06-25 19:12:54,493] +++ R1 logfile /tmp/R1-default-20190625T191254492.log +++
[2019-06-25 19:12:54,493] +++ Unicon plugin iosxe +++
Trying 10.1.1.1...

[2019-06-25 19:12:54,502] +++ connection to spawn: telnet 10.1.1.1 23, id: 140033124293880 +++
[2019-06-25 19:12:54,502] connection to R1
Connected to 10.1.1.1.
Escape character is '^]'.
C

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

  •                                                                       +
    
  •              ATTENTION: AUTHORIZED PERSONAL ONLY!                   +
    
  •                IF YOU ARE NOT AUTHORIZED PERSONAL                   +
    
  •                     DISCONNECT IMMEDIATELY.                         +
    
  •                                                                     +
    

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

User Access Verification

Username: ****
Password:
C

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

  •                                                                     +
    
  •          CONNECTED ON VTY#2 OF avocado.            +
    
  •                                                                     +
    

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

avocado#Traceback (most recent call last):
File "src/unicon/statemachine/statemachine.py", line 697, in unicon.statemachine.statemachine.StateMachine.go_to
File "src/unicon/statemachine/statetransition.py", line 479, in unicon.statemachine.statetransition.AnyStateTransition.do_transitions
File "src/unicon/eal/dialogs.py", line 419, in unicon.eal.dialogs.Dialog.process
File "src/unicon/eal/dialog_processor.py", line 660, in unicon.eal.dialog_processor.AlarmBasedDialogProcessor.process
File "src/unicon/eal/dialog_processor.py", line 645, in unicon.eal.dialog_processor.AlarmBasedDialogProcessor.process
File "src/unicon/eal/dialog_processor.py", line 547, in unicon.eal.dialog_processor.AlarmBasedDialogProcessor.expect_eval_statements
File "src/unicon/eal/backend/pty_backend.py", line 153, in unicon.eal.backend.pty_backend.RawSpawn.read_update_buffer
File "src/unicon/eal/dialog_processor.py", line 605, in unicon.eal.dialog_processor.AlarmBasedDialogProcessor.timeout_handler
unicon.core.errors.TimeoutError: timeout occurred:
timeout value: 60
last_command: '*****\r'
pattern: ['^.?% (Bad passwords|Access denied|Authentication failed)', '^.Login incorrect', '^.([Uu]sername|[Ll]ogin): ?$', '^.User Access Verification', '^.[Pp]assword( for )?(\S+)?: ?$', '^(.)Kerberos: No default realm defined for Kerberos!', '^.(initial|basic) configuration dialog ?\?? ((\[yes.\])|(\(yes/no\))|(\(yes/no\) (\[y\]))):', 'Would you like to enter basic management setup\? \[yes/no\]:', 'Escape character is .\n', '^.RETURN to get started', 'Are you sure you want to continue connecting \(yes/no\)', '^.(Connection refused|Connection reset by peer|Network is down|closed by remote host)', 'Received disconnect from .:', 'Hit Enter to proceed:', '^(.?)Press Ctrl\+x to Exit the session', '^(.?)Connected.', '^.[Pp]assword( for )?(\S+)?: ?$', '^.?% (Bad passwords|Access denied|Authentication failed)', '^.System config(uration)? has been modified\. Save\?.$', '^.Are you sure you want to reset the system \(y\/n\)\?', '^.Reload node \? \[no,yes\]\s?$', '^.Proceed( with reload)?\? \[confirm\]', '^.Press RETURN to get started.$', '^.User Access Verification', '^(.)Uncommitted changes found.?', '^.(initial|basic) configuration dialog ?\?? ((\[yes.\])|(\(yes/no\))|(\(yes/no\) (\[y\]))):', '^(.)Would you like to terminate autoinstall\? ?\[yes\]: $', '^.Do you want to reload the internal AP\s?\? ((\[yes/no\]\??)|(\[y/n\]\??)):?\s?$', '^.Do you want to save the configuration of the AP\s?\? ((\[yes/no\]\??)|(\[y/n\]\??)):?\s?$', '^(.)This command will reboot the system. \(y\/n\)\? \[n\]\s?$', '^.Do you want to enforce secure password standard(\?)? \(yes\/no\)( \[[yn]\])?\: ?', '^.(Enter|Confirm) the password for .admin', 'Abort( Power On)? Auto Provisioning .:', '^.([Uu]sername|[Ll]ogin): ?$', '^.[Pp]assword( for )?(\S+)?: ?$', '^.?% (Bad passwords|Access denied|Authentication failed)', '^.Login incorrect', '^.([Uu]sername|[Ll]ogin): ?$', '^.User Access Verification', '^.[Pp]assword( for )?(\S+)?: ?$', '^(.)Kerberos: No default realm defined for Kerberos!', '^.(initial|basic) configuration dialog ?\?? ((\[yes.\])|(\(yes/no\))|(\(yes/no\) (\[y\]))):', 'Would you like to enter basic management setup\? \[yes/no\]:', 'Escape character is .\n', '^.RETURN to get started', 'Are you sure you want to continue connecting \(yes/no\)', '^.(Connection refused|Connection reset by peer|Network is down|closed by remote host)', 'Received disconnect from .:', 'Hit Enter to proceed:', '^(.?)Press Ctrl\+x to Exit the session', '^(.?)Connected.', '^(.)Please reset', '^(.)(rommon(.))+>', '^.(Enter|Confirm) the password for .admin', '^.(initial|basic) configuration dialog.\s?', '^(.)Would you like to terminate autoinstall\? ?\[yes\]: $', '^.Are you sure you want to continue\? \[y/n\]\s?', '^(.?)\[R1.\]\$\s?$', 'rommon[\s\d]>\s?$', '^(.)\(.(con|cfg|ipsec-profile)\S\)#\s?$', '^(.?)(Router|Switch|ios|switch|R1)(\(standby\))?(-stby)?(\(boot\))?#\s?$', '^(.?)(Router|Switch|ios|switch|R1)(\(standby\))?(-stby)?(\(boot\))?>\s?$', '^.--\s?[Mm]ore\s?--.']
buffer:'\r\nC\r\n\r\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n+ +\r\n+ CONNECTED ON VTY#2 OF avocado. +\r\n+ +\r\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n\r\n\r\navocado#'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "src/unicon/bases/connection.py", line 526, in unicon.bases.connection.Connection.connect
File "src/unicon/bases/routers/connection_provider.py", line 146, in unicon.bases.routers.connection_provider.BaseSingleRpConnectionProvider.connect
File "src/unicon/bases/routers/connection_provider.py", line 169, in unicon.bases.routers.connection_provider.BaseSingleRpConnectionProvider.establish_connection
File "src/unicon/statemachine/statemachine.py", line 700, in unicon.statemachine.statemachine.StateMachine.go_to
unicon.core.errors.StateMachineError: Failed while bringing device to "any" state

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "", line 1, in
File "src/pyats/connections/manager.py", line 305, in pyats.connections.manager.ConnectionManager.connect
File "src/unicon/bases/connection.py", line 532, in unicon.bases.connection.Connection.connect
unicon.core.errors.ConnectionError: failed to connect to R1

`

AttributeError: 'AttrDict' object has no attribute 'username'

I am traying to createing my own Testbed object. I am fill following the steps in the page
https://pubhub.devnetcloud.com/media/pyats/docs/topology/creation.html#manual-creation

but when i tray to connect. i get an error

----> 1 device.connect()

/usr/local/lib64/python3.7/site-packages/pyats/connections/manager.cpython-37m-x86_64-linux-gnu.so in pyats.connections.manager.ConnectionManager.connect()

/usr/local/lib64/python3.7/site-packages/pyats/connections/manager.cpython-37m-x86_64-linux-gnu.so in pyats.connections.manager.ConnectionManager.instantiate()

/usr/local/lib64/python3.7/site-packages/unicon/adapters/topology.cpython-37m-x86_64-linux-gnu.so in unicon.adapters.topology.Unicon()

AttributeError: 'AttrDict' object has no attribute 'username'

admin_redundancy_force_switchover_now does not work on CPM B

pyATS parser "admin_redundancy_force_switchover_now" works on Nokia CPM A but not on CPM B.

Below pyats output shows the "pyats run job" hanging after connection into the first
device in the testbed.yaml file(nokia_tb.yaml)

(pyats) [jcoulter@covengcescripts3 bell_nokia]$ pyats run job ./nokia_suite.py -t ./nokia_tb.yaml
2020-04-13T14:44:57: %EASYPY-INFO: Starting job run: nokia_suite
2020-04-13T14:44:57: %EASYPY-INFO: Runinfo directory: /home/jcoulter/.pyats/runinfo/nokia_suite.2020Apr13_14:44:56.881467
2020-04-13T14:44:57: %EASYPY-INFO: --------------------------------------------------------------------------------
2020-04-13T14:44:57: %EASYPY-INFO: Testbed file ./nokia_tb.yaml exists and is readable.
2020-04-13T14:45:00: %EASYPY-INFO: Starting task execution: Task-1
2020-04-13T14:45:00: %EASYPY-INFO: test harness = pyats.aetest
2020-04-13T14:45:00: %EASYPY-INFO: testscript = /home/jcoulter/pyats_tests/bell_nokia/nokia_tests.py
2020-04-13T14:45:00: %AETEST-INFO: +------------------------------------------------------------------------------+
2020-04-13T14:45:00: %AETEST-INFO: | Starting common setup |
2020-04-13T14:45:00: %AETEST-INFO: +------------------------------------------------------------------------------+
2020-04-13T14:45:00: %AETEST-INFO: +------------------------------------------------------------------------------+
2020-04-13T14:45:00: %AETEST-INFO: | Starting subsection connect_tb_devices |
2020-04-13T14:45:00: %AETEST-INFO: +------------------------------------------------------------------------------+
[2020-04-13 14:45:00,583] +++ CR01-Nokia-NGCore logfile /home/jcoulter/.pyats/runinfo/nokia_suite.2020Apr13_14:44:56.881467/CR01-Nokia-NGCore-cli-1586803500.log +++
[2020-04-13 14:45:00,584] +++ Unicon plugin sros +++
WARNING: THIS IS A PRIVATE SYSTEM ANY UNAUTHORIZED ACCESS WILL LEAD TO PROSECUTION. IF YOU ARE NOT AN AUTHORIZED USER, DO NOT ATTEMPT TO LOG IN. CECI EST UN SYSTEME PRIVEE. TOUT ACCES NON AUTORISE PEUT ENTRAINER DES POURSUITES . SI VOUS N'ETES PAS UN USAGER AUTORISE, N'ESSAYEZ PAS D'Y ACCEDER

[2020-04-13 14:45:00,771] +++ connection to spawn: ssh -l NokiaTest 172.16.18.2, id: 139973235204616 +++
[2020-04-13 14:45:00,772] connection to CR01-Nokia-NGCore
[email protected]'s password:

[]
B:NokiaTest@CR01-Nokia-NGCore#

pyATS Ping function seems not work properly.

Hi.

I'm trying to develop the ping testcase between ios devices using script following below but it seems work incorrectly.
This script return the result with "Failed reason: Ping 172.20.0.22 from device r1 failed with error: 'r1'" BUT pinging to 172.20.0.22 from device r1 is reachable in actual status.

Could someone please give me some solutions or advises?

Thanks.

connection_check.py

# Example
# -------
#
#   connectivity_check.py

from pyats import aetest

class CommonSetup(aetest.CommonSetup):

    @aetest.subsection
    def check_topology(self,
                       testbed,
                       ios1_name = 'r1',
                       ios2_name = 'r2'):
        ios1 = testbed.devices[ios1_name]
        ios2 = testbed.devices[ios2_name]

        # add them to testscript parameters
        self.parent.parameters.update(ios1 = ios1, ios2 = ios2)

        # get corresponding links
        links = ios1.find_links(ios2)

        assert len(links) >= 1, 'require one link between ios1 and ios2'


    @aetest.subsection
    def establish_connections(self, steps, ios1, ios2):
        with steps.start('Connecting to %s' % ios1.name):
            ios1.connect()

        with steps.start('Connecting to %s' % ios1.name):
            ios2.connect()

@aetest.loop(device = ('r1', 'r2'))
class PingTestcase(aetest.Testcase):

    @aetest.test.loop(destination = ('172.20.0.22', '172.20.0.21'))
    def ping(self, device, destination):
        try:
            result = self.parameters[device].ping(destination)

        except Exception as e:
            self.failed('Ping {} from device {} failed with error: {}'.format(
                                destination,
                                device,
                                str(e),
                            ),
                        goto = ['exit'])
        else:
            match = re.search(r'Success rate is (?P<rate>\d+) percent', result)
            success_rate = match.group('rate')

            logger.info('Ping {} with success rate of {}%'.format(
                                        destination,
                                        success_rate,
                                    )
                               )
(snip)

testbed.yaml

testbed:
  name: pyATS_IOS_Example_Testbed
devices:
  r1:
    alias: r1
    os: iosxe
    type: router
    connections:
      defaults:
        class: 'unicon.Unicon'
      ssh:
        protocol: ssh
        ip: 172.20.0.21
        port: 22
    credentials:
      default:
        username: cisco
        password: cisco
        enable: cisco

  r2:
    alias: r2
    os: iosxe
    type: router
    connections:
      defaults:
        class: 'unicon.Unicon'
      ssh:
        protocol: ssh
        ip: 172.20.0.22
        port: 22
    credentials:
      default:
        username: cisco
        password: cisco
        enable: cisco
topology:
  r1:
    interfaces:
      GigabitEthernet2:
        ipv4: 172.20.0.21/16
        link: link
        type: gigabitethernet
      Loopback0:
        ipv4: 192.168.254.1/32
        link: ios1_Loopback0
        type: loopback
  r2:
    interfaces:
      GigabitEthernet2:
        ipv4: 172.20.0.22/16
        link: link
        type: gigabitethernet
      Loopback0:
        ipv4: 192.168.254.2/32
        link: ios2_Loopback0
        type: loopback


no switchport and ip address on IOS XE

Hi,
I'm trying to configure a switch based on the demo code to make pyats working in my lab.
I see that when I configure my interfaces on the switch ( 3850 ), I have to make sure the interface is in no switchport state
. But, when I change it, pyats always try to add the ip address statement BEFORE the switchport command, and it make it fail everytime . Is there something I can do ?

            for link in links:
                for intf in link.interfaces:

                    intf.switchport_enable = False
                    # Configuring the interface with its attribute
                    intf.shutdown = False
                    intf.layer = interface.Layer.L3
                    
                    # Assigning Ipv4 addresses to the intervace
                    #intf.ipv4 = next(ipv4rng)
                    ipv4s.append(intf.ipv4.ip)

                    # Build interface config and apply it to the device
                    intf.build_config()

thanks for the help :)

RFE: Reason column on the detailed results

It would be great to have a fail reason column on the detailed results, and that column would be filled with the self.failed description.
That way on the exception handling process the coder could give precise output error without the need of going back on all lines of test results

Add ability to use custom validations for a testbed file

Since pyATS 5.0.0 we have the ability to validate a testbed file structure with pyats validate testbed my-testbed.yaml.

It will be great to have the ability to add custom rules for testbed validation. Use case: let's assume there is an additional keyword in a device's custom section. So, I want to provide validation options for this keyword to make sure it is specified correctly by someone who configures the testbed file. This allows me to validate data before running actual tests (and don't repeat some validations in the code again and again).

Aetest processor for failed assertions

Hello folks,
I have set of tests with various assertions. After each test execution, we get a TestResult object that contains info about result code, name, tims. But there is no info about error/fail reason in case of test failure.
I have found a temporary workaround using @aetest.processor feature (https://pubhub.devnetcloud.com/media/pyats/docs/aetest/processors.html?highlight=processors). But it has one drawback - it catches only exceptions. That means that I have to replace all assert statements with a custom implementation of the Exception class and raise exceptions in case some condition was not met. That is nasty and wrong approach.
So my question is - how can I get a failed assertion message in a more friendly way?
Maybe I'm missing something obvious?

Only 2 tests result is displayed in the -html_logs

Hi, I have a 4 testrscript in my jobb file.

def main(runtime):

    runtime.job.name = 'ios-infrastructure-tests'
    # Find the location of the script in relation to the job file
    run(testscript='test_main.py', runtime=runtime)
    run(testscript='test_interface.py', runtime=runtime)
    run(testscript='test_spantree_bpdu_block.py', runtime=runtime)
    run(testscript='test_auto_qos.py', runtime=runtime)

after test is done, i can not see all the result in html_log file.
result from the first 2 testscript is there but not the rest.

need help to understand way?!

Unable to run easily on Mac 10.13.6 (17G65)

I have configured a simple test and a job to run this test. When I run it with easypy, I have socket.gaierror: [Errno 8] nodename nor servname provided, or not known error and the test is not executed.

Environment setup:

  • python 3.6.5
  • pyats 4.1.0

Pip log:

pip list
Package              Version  
-------------------- ---------
asynctest            0.12.2   
blinker              1.4      
certifi              2018.8.13
chardet              3.0.4    
graphviz             0.9      
httplib2             0.11.3   
idna                 2.7      
Jinja2               2.10     
junit-xml            1.8      
MarkupSafe           1.0      
pip                  18.0     
psutil               5.4.7    
pyats                4.1.0    
pyats.aereport       4.1.0    
pyats.aetest         4.1.3    
pyats.async          4.1.0    
pyats.connections    4.1.0    
pyats.datastructures 4.1.0    
pyats.easypy         4.1.10   
pyats.examples       4.1.0    
pyats.kleenex        4.1.0    
pyats.log            4.1.0    
pyats.results        4.1.0    
pyats.tcl            4.1.1    
pyats.templates      4.1.0    
pyats.topology       4.1.2    
pyats.utils          4.1.4    
PyYAML               3.13     
requests             2.19.1   
setproctitle         1.1.10   
setuptools           40.2.0   
six                  1.11.0   
unicon               3.2.0    
urllib3              1.23     
wheel                0.31.1   

The tests:

# smoke_test.py
from ats import aetest

from ats.aetest import test


class Smoke(aetest.Testcase):
    @test
    def test_one(self):
        print('Smoke test is passed')
# smore_job.py
import os
from ats import easypy


def main():
    script_path = os.path.dirname(os.path.abspath(__file__))
    testscript = os.path.join(script_path, 'smoke_test.py')
    easypy.run(testscript=testscript)

Execution log:

$ easypy smoke_job.py 
Process ForkProcess-2:
Traceback (most recent call last):
  File "/python/3.6.5/lib/python3.6/multiprocessing/process.py", line 258, in _bootstrap
    self.run()
  File "/python/3.6.5/lib/python3.6/multiprocessing/process.py", line 93, in run
    self._target(*self._args, **self._kwargs)
  File "src/ats/aereport/toplevel/decorators.py", line 43, in ats.aereport.toplevel.decorators.log_it.inner
  File "src/ats/aereport/toplevel/decorators.py", line 36, in ats.aereport.toplevel.decorators.log_it.inner
  File "src/ats/aereport/aerunner.py", line 5336, in ats.aereport.aerunner.AERunner.run_server
  File "src/ats/aereport/aerunner.py", line 5933, in ats.aereport.aerunner.OrphanFreeSimpleXMLRPCServer.__init__
  File "/python/3.6.5/lib/python3.6/xmlrpc/server.py", line 598, in __init__
    socketserver.TCPServer.__init__(self, addr, requestHandler, bind_and_activate)
  File "/python/3.6.5/lib/python3.6/socketserver.py", line 453, in __init__
    self.server_bind()
  File "/python/3.6.5/lib/python3.6/socketserver.py", line 467, in server_bind
    self.socket.bind(self.server_address)
socket.gaierror: [Errno 8] nodename nor servname provided, or not known
2018-08-22T12:44:49: %EASYPY-ERROR: !!! an unhandled exception has interrupted execution !!!
2018-08-22T12:44:49: %EASYPY-ERROR: 
2018-08-22T12:44:49: %EASYPY-ERROR: This may be caused by:
2018-08-22T12:44:49: %EASYPY-ERROR:     - keyboard interrupts (ctrl+c)
2018-08-22T12:44:49: %EASYPY-ERROR:     - job file issues
2018-08-22T12:44:49: %EASYPY-ERROR:     - unexpected exceptions from your plugins
2018-08-22T12:44:49: %EASYPY-ERROR: 
2018-08-22T12:44:49: %EASYPY-ERROR: As a consequence:
2018-08-22T12:44:49: %EASYPY-ERROR:     - execution crashed and the environment may not be cleaned up
2018-08-22T12:44:49: %EASYPY-ERROR:     - TRADE/TIMS uploading will likely not occur
2018-08-22T12:44:49: %EASYPY-ERROR: 
2018-08-22T12:44:49: %EASYPY-ERROR: Please investigate the traceback below before raising issue to pyats-support.
2018-08-22T12:44:49: %EASYPY-ERROR: 
2018-08-22T12:44:49: %EASYPY-ERROR: --------------------------------------------------------------------------------
2018-08-22T12:44:49: %EASYPY-ERROR: 
2018-08-22T12:44:49: %EASYPY-ERROR: pyATS Instance   : /python/3.6.5/envs/pyats
2018-08-22T12:44:49: %EASYPY-ERROR: Python Version   : cpython-3.6.5 (64bit)
2018-08-22T12:44:49: %EASYPY-ERROR: CLI Arguments    : /python/pyats/bin/easypy smoke_job.py
2018-08-22T12:44:49: %EASYPY-ERROR: User             : user
2018-08-22T12:44:49: %EASYPY-ERROR: Host Server      : mac
2018-08-22T12:44:49: %EASYPY-ERROR: Host OS Version  : Mac OSX 10.13.6 (x86_64)
2018-08-22T12:44:49: %EASYPY-ERROR: 
2018-08-22T12:44:49: %EASYPY-ERROR: Traceback (most recent call last):
2018-08-22T12:44:49: %EASYPY-ERROR:   File "src/ats/easypy/reporter/ae.py", line 114, in ats.easypy.reporter.ae.AEReporter.start
2018-08-22T12:44:49: %EASYPY-ERROR:   File "src/ats/aereport/aerunner.py", line 5256, in ats.aereport.aerunner.AERunner.start_server
2018-08-22T12:44:49: %EASYPY-ERROR: ats.aereport.exceptions.aereport_errors.ServerNotStarted: 'Server could not be started. AEReport server will not be started'
2018-08-22T12:44:49: %EASYPY-INFO: No SMTP server information configured, ignoring sending notification email.
2018-08-22T12:44:49: %EASYPY-INFO: Done!

"Genie and PyATS are not installed" exception after upgrade

Hello,

I have a python script that uses the genie parser to collect information from some devices. This was working correctly yesterday. This morning I upgraded pyats and genie. Since upgrading, my script exits with the following exception:

"getrouteddeviceinfo - error at show version for device x.x.x.x =
Genie and PyATS are not installed. Please PIP install both Genie and PyATS:
pip install genie
pip install pyats"

The line of code throwing this error looks like this:
routerdict['showver']= net_connect.send_command("show version",use_genie=True,expect_string=prompt)

genie and pyats both show up in the output from 'pip3 list' (attached).

I am running python 3.6.8 on Ubuntu 18.04.3 LTS. I believe I upgraded to version 19.12 of genie/pyats (based on output from pip3 list). I didn't think to check the version pre-upgrade, best guess would be 19.9

I didn't carry out any other changes or upgrades apart from the upgrades to genie/pyats (and a reboot of the device)

Any help would be greatly appreciated

pip3list.txt

Help to view and print html logs

Hello!
I have an issue with viewing log results in browser.
Result column overlaps Section column and I can not see details of test result
Also it prevent me for print out readable pdf report from this page.
Can you add possibility to move or hide columns in html result page?
pyats log viewer

Need Help. Timeout after 1 hour

I am running a rather big test, on approximately 250 access switches / devices.

The collection process of gathering the test data takes more the 1 hour to finish .
So the test is ERRORED. and i only 2/3 of the devices have data collected for the next test case.

+------------------------------------------------------------------------------+
|             Gahter parst data from stjipswi019 | show interfaces             |
+------------------------------------------------------------------------------+
+++ stjipswi019: executing command 'show interfaces' +++
Connection to 10.144.56.29 closed by remote host.
Connection to 10.144.56.29 closed.
show interfaces
 Caught an exception while executing TestSection 'collect_interface_data':
 Traceback (most recent call last):
   File "src/unicon/eal/backend/pty_backend.py", line 452, in unicon.eal.backend.pty_backend.RawPtySpawn._read
 OSError: [Errno 5] Input/output error
 
 The above exception was the direct cause of the following exception:
 
 Traceback (most recent call last):
   File "/pyats/lib/python3.6/site-packages/unicon/plugins/generic/service_implementation.py", line 703, in call_service
:     context=con.context
:   File "src/unicon/eal/dialogs.py", line 430, in unicon.eal.dialogs.Dialog.process
:   File "src/unicon/eal/dialog_processor.py", line 295, in unicon.eal.dialog_processor.SimpleDialogProcessor.process
:   File "src/unicon/eal/dialog_processor.py", line 217, in unicon.eal.dialog_processor.SimpleDialogProcessor.expect_eval_statements
:   File "src/unicon/eal/backend/pty_backend.py", line 133, in unicon.eal.backend.pty_backend.RawSpawn.read_update_buffer
:   File "src/unicon/eal/backend/pty_backend.py", line 118, in unicon.eal.backend.pty_backend.RawSpawn.read
:   File "src/unicon/eal/backend/pty_backend.py", line 455, in unicon.eal.backend.pty_backend.RawPtySpawn._read
: unicon.core.errors.EOF: ('Unable to read. Connection closed or not available', OSError(5, 'Input/output error'))
: 
: The above exception was the direct cause of the following exception:
: 
: Traceback (most recent call last):
:   File "src/genie/metaparser/_metaparser.py", line 271, in genie.metaparser._metaparser.MetaParser.parse
:   File "/pyats/lib/python3.6/site-packages/genie/libs/parser/iosxe/show_interface.py", line 203, in cli
:     out = self.device.execute(cmd)
:   File "src/unicon/bases/routers/services.py", line 190, in unicon.bases.routers.services.BaseService.__call__
:   File "/pyats/lib/python3.6/site-packages/unicon/plugins/generic/service_implementation.py", line 712, in call_service
:     raise SubCommandFailure("Command execution failed", err) from err
: unicon.core.errors.SubCommandFailure: ('Command execution failed', EOF('Unable to read. Connection closed or not available', OSError(5, 'Input/output error')))
: 
: The above exception was the direct cause of the following exception:
: 
: Traceback (most recent call last):
:   File "/pyats/test_interface_config.py", line 79, in collect_interface_data
:     interfaces = device.parse("show interfaces")
:   File "src/genie/conf/base/device.py", line 529, in genie.conf.base.device.Device.parse
:   File "src/genie/metaparser/_metaparser.py", line 274, in genie.metaparser._metaparser.MetaParser.parse
: genie.metaparser.util.exceptions.InvalidCommandError: Invalid command has been executed
  The result of section collect_interface_data is => ERRORED

how can i keep the connection open to the device?
or can i reconnect automatic if i lose the connection?

Not able to install pyats locally

(.venv-py36) SHIVSACH-M-F0US:bin shivsach$ pip install pyats
Collecting pyats
Could not find a version that satisfies the requirement pyats (from versions: )
No matching distribution found for pyats

TypeError: argument of type 'module' is not iterable

I'm seeing the below error recently on executing the scripts which had run without hitting any issues before in Ubuntu 14.04.5 LTS.
Traceback (most recent call last):
File "/home/natarar/pyats/bin/easypy", line 7, in
from ats.easypy import main
File "", line 2237, in _find_and_load
File "", line 2226, in _find_and_load_unlocked
File "", line 1193, in _load_unlocked
File "", line 1111, in create
File "src/pyats/utils/import_utils/legacy.py", line 35, in pyats.utils.import_utils.legacy.LegacyLoader.create_module
File "/home/natarar/pyats/lib/python3.4/site-packages/pyats/easypy/init.py", line 7, in
from .main import _default_runtime as runtime, main
File "src/pyats/easypy/main.py", line 8, in init pyats.easypy.main
File "/home/natarar/pyats/lib/python3.4/site-packages/pyats/log/init.py", line 1, in
from .cisco import (ScreenFormatter, ColouredScreenFormatter, ScreenHandler,
File "src/pyats/log/cisco.py", line 17, in init pyats.log.cisco
File "src/pyats/utils/utils.py", line 166, in init pyats.utils.utils
File "src/pyats/utils/import_utils/misc.py", line 16, in pyats.utils.import_utils.misc.on_import
File "src/pyats/utils/utils.py", line 168, in pyats.utils.utils._on_import_set_get_time
TypeError: argument of type 'module' is not iterable

Missing dependency for "aetest" package

If I install aetest with pip install pyats.aetest, I'll have the following error while executing a test:

$ python smoke_test.py 
Traceback (most recent call last):
  File "smoke_test.py", line 1, in <module>
    from ats import aetest
  File "..../versions/pyats/lib/python3.6/site-packages/ats/aetest/__init__.py", line 32, in <module>
    from .main import main
  File "src/ats/aetest/main.py", line 15, in init ats.aetest.main
  File "..../versions/pyats/lib/python3.6/site-packages/ats/aetest/loader/__init__.py", line 3, in <module>
    from .implementation import AEtestLoader
  File "src/ats/aetest/loader/implementation.py", line 7, in init ats.aetest.loader.implementation
  File "..../versions/pyats/lib/python3.6/site-packages/ats/aetest/reporter/__init__.py", line 4, in <module>
    from .aereport import AEReporter
  File "src/ats/aetest/reporter/aereport.py", line 2, in init ats.aetest.reporter.aereport
ModuleNotFoundError: No module named 'yaml'

File content starts with

from ats import aetest                                                                                                                                                        
from ats.aetest import setup, subsection, test, cleanup

class Instal(aetest.CommonSetup):
     @subsection
     def step_1(self):
         print('Download a ....')

Ping in a VRF unsupported in IOS?

unicon==19.6

Working with an older Catalyst 6500, it appears that IOS plugin does not support the "vrf" keyword.

Switching the device type to "iosxe" allows the command to succeed but I'm not sure how this may affect further interaction with the device

Is `vrf` a reserved key in `topology` in a testbed definition?

I couldn't find documentation on the vrf key, but it looks like either pyATS or Genie want to do something special with it. I was attempting to use it as a custom key.

A snippet of my testbed example topology:

topology:                    
  spine1:                
    interfaces:              
      Ethernet1/1:       
        ipv4: 10.3.1.0/31    
        link: spine1-to-leaf1
        type: ethernet       
      Ethernet1/2:        
        ipv4: 10.4.1.0/31 
        link: spine1-to-leaf2
        type: ethernet        
      Ethernet1/3:    
        ipv4: 10.1.1.1/31
        link: border1-to-spine1
        type: ethernet       
      Ethernet1/4:           
        ipv4: 10.2.1.1/31
        link: border2-to-spine1
        type: ethernet    
      mgmt0:                 
        ipv4: 192.168.1.51    
        link: spine1-mgmt0     
        type: ethernet
        vrf: management

This results in the following error:

2018-12-17T13:43:07: %AETEST-ERROR: Caught exception during execution:                                             
2018-12-17T13:43:07: %AETEST-ERROR: Traceback (most recent call last):                                               
2018-12-17T13:43:07: %AETEST-ERROR:   File "/home/tyler/nfs/Projects/netdevops/pyats/example.py", line 40, in genie_init
2018-12-17T13:43:07: %AETEST-ERROR:     Genie.init(testbed=testbed)                                                                                        
2018-12-17T13:43:07: %AETEST-ERROR:   File "src/genie/conf/main.py", line 90, in genie.conf.main.Genie.init        
2018-12-17T13:43:07: %AETEST-ERROR:   File "src/genie/conf/utils/converter.py", line 60, in genie.conf.utils.converter.Converter.convert_tb
2018-12-17T13:43:07: %AETEST-ERROR:   File "src/genie/conf/utils/converter.py", line 164, in genie.conf.utils.converter.Converter.convert_device       
2018-12-17T13:43:07: %AETEST-ERROR:   File "src/genie/conf/utils/converter.py", line 231, in genie.conf.utils.converter.Converter.convert_interface
2018-12-17T13:43:07: %AETEST-ERROR:   File "src/genie/decorator.py", line 1168, in genie.decorator.managedattribute.__set__
2018-12-17T13:43:07: %AETEST-ERROR:   File "src/genie/decorator.py", line 781, in genie.decorator.managedattribute._default_setter                          
2018-12-17T13:43:07: %AETEST-ERROR:   File "src/genie/decorator.py", line 704, in genie.decorator.managedattribute._transform
2018-12-17T13:43:07: %AETEST-ERROR: ValueError: management: Not None. Not an instance of Vrf.         

I tried to find this in the pyATS documentation for the topology schema here, but I came up with nothing. I could go code spelunking, but I'd also like to know if this is a bug, an intended feature, or if I'm just doing it wrong.

For now, I've worked around this by making the key custom_vrf and updating my code accordingly.

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.