Giter Club home page Giter Club logo

virl2-client's Introduction

CI

VIRL 2 Client Library

Note: The product has been renamed from VIRL to Cisco Modeling Labs / CML 2. References to VIRL still exist in the product documentation and within code or examples.

The name of the package itself has not been changed. Throughout the documentation it is referred to as "virl2_client", "Python Client Library" or "PCL".

Introduction

This is the client library for the Cisco Modeling Labs Platform (virl2_client). It provides a Python package to programmatically create, edit, delete and control network simulations on a CML 2 controller.

It is a pure Python implementation that requires Python 3. We've tested and written the package with Python 3.8.10.

The status of the package can be considered stable. Issues with the software should be raised via the GitHub issue tracker.

Use Case Description

The client library provides a convenient interface to control the life-cycle of a network simulation. This can be used for automation scripts directly in Python but also for third party integrations / plugins which need to integrate with a simulated network. Examples already existing are an Ansible plugin.

Installation

The package comes in form of a wheel that is downloadable from the CML 2 controller. The package can be installed either from PyPI using

pip3 install virl2_client

If you want to interact with devices via the client library, you need to also install the pyATS library. This can be achieved in one go using

pip3 install "virl2_client[pyats]"

Note that this does not pull in the full pyATS package... See below how that is achieved.

or, alternatively, the version that is bundled with the CML 2 controller can be downloaded to the local filesystem and then directly installed via

pip3 install ./virl2_client-*.whl

The bundled version is available on the index site of the docs when viewed directly on the CML 2 controller.

Ensure to replace and/or use the correct file name, replacing the wildcard with the proper version/build information. For example

pip3 install virl2_client-2.0.0b10-py3-none-any.whl

We recommend the use of a virtual environment for installation.

If you require the full version of the pyATS library including things like Genie then you need to do this in a subsequent step like shown here:

pip3 install "pyats[full]"

IMPORTANT: The version of the Python client library must be compatible with the version of the controller. If you are running an older controller version then it's likely that the latest client library version from PyPI can not be used. In this case, you need to either use the version available from the controller itself or by specifying a version constraint.

Example: When on a controller version 2.2.x, then you'd need to install with pip3 install "virl2-client<2.3.0". This will ensure that the version installed is compatible with 2.2.x.

Usage

The package itself is fairly well documented using docstrings. In addition, the documentation is available in HTML format on the controller itself, via the "Tools -> Client Library" menu.

Compatibility

This package and the used API is specific to CML 2. It is not backwards compatible with VIRL 1.x and therefore can not be used with VIRL 1.x. If you are looking for a convenient tool to interface with the VIRL 1 API then the CML Utils tool is recommended.

Known Issues

There are no major known issues at this point. See the comment in the Introduction section. Also, see the Issues section in GitHub to learn about known issues or raise new ones, if needed. Also see CHANGES.

Getting Help

If you have questions, concerns, bug reports, etc., please create an issue against the repository on GitHub

Getting Involved

We welcome contributions. Whether you fixed a bug, added a new feature or corrected a typo, all contributions are welcome. General instructions on how to contribute can be found in the CONTRIBUTING file.

Licensing Info

This code is licensed under the Apache 2.0 License. See LICENSE for details.

References

This package is part of the CML 2 Network Simulation platform. For details, go to https://developer.cisco.com/modeling-labs. Additional documentation for the product is available at https://developer.cisco.com/docs/modeling-labs

virl2-client's People

Contributors

christopherjhart avatar exjobo avatar nsthompson avatar rschmied avatar tmikuska 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

Watchers

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

virl2-client's Issues

CML Image Not Ready

I have installed CML and can get everything to work except for the images included with the environment. I have tried re-download the refplat and attaching the new one in case something got corrupted along the way, but that didn't work. I am at a loss currently, this is the first time I have worked with CML but I am a networking professional in a cisco environment. Any help would be awesome, the screen shot below depicts the issue. Cheers!

Screenshot 2024-03-04 215929

unable to execute run_pyats_command on node

Hello, I am trying to run a command 'Show run' on a node, here's the sample code.
Code is very basic using the virl2_client module:
client = ClientLibary(server, username, password, ssl_verify=False)
client.wait_for_lld_connected()
lab = client.create_lab(‘testlab’)
r1 = lab.create_node(‘r1’, ‘iosv’, 50, 100)
r1.config = ‘hostname testing’
lab.start()
lab.wait_until_lab_converged()
cmd = r1.run_pyats_command(‘show run’)

then I get an AttributeError: ‘NoneType’ object has no attribute ‘devices’ on the cmd line above

CA_BUNDLE and CML_VERIFY_CERT should be converted to bool

There seems to be a bug with the way CA_BUNDLE and CML_VERIFY_CERT are handled, the docstring says:

:param ssl_verify: Path of the SSL controller certificate, or True to load
from ``CA_BUNDLE`` or ``CML_VERIFY_CERT`` environment variable,
or False to disable.

For example, with the following .virlrc:

VIRL_HOST=cml-04
VIRL_USERNAME=user
VIRL_PASSWORD=password
CML_VERIFY_CERT=True
CA_BUNDLE=False   

I get the following exception:

from virl2_client import ClientLibrary
client = ClientLibrary()
<snip>
OSError: Could not find a suitable TLS CA certificate bundle, invalid path: False

It appears that we get the strings "False" or "True" and they should be converted to a bool, ideally case insensitive.

    138     if ssl_verify is True:
    139         breakpoint()
--> 140         ssl_verify = _get_prop("CA_BUNDLE") or _get_prop("CML_VERIFY_CERT")
    141
    142     return host, username, password, ssl_verify

ipdb> interact
*interactive*
In [1]: _get_prop("CA_BUNDLE") or _get_prop("CML_VERIFY_CERT")
Out[1]: 'False'

In [2]: _get_prop("CA_BUNDLE")
Out[2]: 'False'

In [3]: _get_prop("CML_VERIFY_CERT")
Out[3]: 'True'

In [4]: _get_prop("CA_BUNDLE") or _get_prop("CML_VERIFY_CERT")
Out[4]: 'False'

Do we need two options for setting ssl_verify? I initially thought it was for backward compatibility, but it seems this is a relatively new addition (#40).

My concern is that this could lead to unexpected behavior in certain cases. For example, if a path is set with CA_BUNDLE and CML_VERIFY_CERT is set to False, one might expect ssl_verify will be set to False but CA_BUNDLE takes precedence.

In [6]: _get_prop("CA_BUNDLE") or False
Out[6]: '/tmp/blah'

Note the use of a bool here and not a str

CA_BUNDLE set to True and CML_VERIFY_CERT to a path could also lead to unexpected behavior:

In [7]: True or "/tmp/path"
Out[7]: True

Could we reconsider the need for both options to avoid potential confusion and ensure consistent/simpler behavior?
I understand it might be too late for this, in this case we should probably clarify in the doc.

Maybe not too late for #104 ?

ClientLibrary(ssl_verify=False) does not disable SSL cert verification

Hi,

It looks like disabling SSL verification in the library does not work. Here's my setup:

❯ python --version
Python 3.10.8

poetry show virl2_client
name : virl2-client
version : 2.4.1
description : VIRL2 Client Library

dependencies

  • requests >=2,<3
  • requests-toolbelt >=0.9.1,<0.10.0
  • urllib3 >=1.26.9,<2.0.0
from pathlib import Path

from virl2_client import ClientLibrary

client = ClientLibrary("https://x.x.x.x", "user", "password", ssl_verify=False)

# this lab name exists on CML system
lab = client.find_labs_by_title("My lab")[0]

I get the following output when I run the above script:

❯ python src/main.py      
SSL Verification disabled
Traceback (most recent call last):
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/urllib3/connectionpool.py", line 703, in urlopen
    httplib_response = self._make_request(
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/urllib3/connectionpool.py", line 386, in _make_request
    self._validate_conn(conn)
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/urllib3/connectionpool.py", line 1042, in _validate_conn
    conn.connect()
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/urllib3/connection.py", line 414, in connect
    self.sock = ssl_wrap_socket(
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/urllib3/util/ssl_.py", line 453, in ssl_wrap_socket
    ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls)
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/urllib3/util/ssl_.py", line 495, in _ssl_wrap_socket_impl
    return ssl_context.wrap_socket(sock)
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/ssl.py", line 513, in wrap_socket
    return self.sslsocket_class._create(
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/ssl.py", line 1071, in _create
    self.do_handshake()
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/ssl.py", line 1342, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:997)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/requests/adapters.py", line 489, in send
    resp = conn.urlopen(
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/urllib3/connectionpool.py", line 787, in urlopen
    retries = retries.increment(
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/urllib3/util/retry.py", line 592, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='x.x.x.x', port=443): Max retries exceeded with url: /api/v0/system_information (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:997)')))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/gethdav/git/naas/virt-lab-man/src/main.py", line 9, in <module>
    client = ClientLibrary("https://x.x.x.x", "user", "password", ssl_verify=False)
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/virl2_client/virl2_client.py", line 254, in __init__
    self.check_controller_version()
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/virl2_client/virl2_client.py", line 427, in check_controller_version
    controller_version or self.system_info().get("version", "").split("-")[0]
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/virl2_client/virl2_client.py", line 411, in system_info
    response = self.session.get(urljoin(self._base_url, "system_information"))
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/requests/sessions.py", line 600, in get
    return self.request("GET", url, **kwargs)
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/requests/sessions.py", line 587, in request
    resp = self.send(prep, **send_kwargs)
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/requests/sessions.py", line 701, in send
    r = adapter.send(request, **kwargs)
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/requests/adapters.py", line 563, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='x.x.x.x', port=443): Max retries exceeded with url: /api/v0/system_information (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:997)')))

I had a look through the source code. I think the problem is that while the ssl_verify argument is "set" on the session object it is not actually used by the session. For example:

>>> import requests
>>> s = requests.Session()
>>> s.verify = False
>>> s.get("https://x.x.x.x")Traceback (most recent call last):
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/urllib3/connectionpool.py", line 703, in urlopen
    httplib_response = self._make_request(
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/urllib3/connectionpool.py", line 386, in _make_request
    self._validate_conn(conn)
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/urllib3/connectionpool.py", line 1042, in _validate_conn
    conn.connect()
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/urllib3/connection.py", line 414, in connect
    self.sock = ssl_wrap_socket(
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/urllib3/util/ssl_.py", line 453, in ssl_wrap_socket
    ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls)
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/urllib3/util/ssl_.py", line 495, in _ssl_wrap_socket_impl
    return ssl_context.wrap_socket(sock)
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/ssl.py", line 513, in wrap_socket
    return self.sslsocket_class._create(
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/ssl.py", line 1071, in _create
    self.do_handshake()
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/ssl.py", line 1342, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:997)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/requests/adapters.py", line 489, in send
    resp = conn.urlopen(
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/urllib3/connectionpool.py", line 787, in urlopen
    retries = retries.increment(
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/urllib3/util/retry.py", line 592, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='x.x.x.x', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:997)')))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/requests/sessions.py", line 600, in get
    return self.request("GET", url, **kwargs)
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/requests/sessions.py", line 587, in request
    resp = self.send(prep, **send_kwargs)
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/requests/sessions.py", line 701, in send
    r = adapter.send(request, **kwargs)
  File "/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/requests/adapters.py", line 563, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='x.x.x.x', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:997)')))

But if I pass the verify option to the get() call, it works:

>>> s.get("https://x.x.x.x", verify=False)
/Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/urllib3/connectionpool.py:1045: InsecureRequestWarning: Unverified HTTPS request is being made to host 'x.x.x.x'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings
  warnings.warn(
<Response [200]>

The URL referenced in the comments above where ssl_verify is saved (http://docs.python-requests.org/en/master/user/advanced/#ssl-cert-verification) is misleading. Looking at the requests.Session.get() the verify property does not appear to be used. Running the example I provided through the debugger appears to confirm this:

python -m pdb src/main.py
> /Users/gethdav/git/naas/virt-lab-man/src/main.py(1)<module>()
-> import os
(Pdb) b /Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/requests/sessions.py:599
Breakpoint 1 at /Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/requests/sessions.py:599
(Pdb) c
SSL Verification disabled
> /Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/requests/sessions.py(599)get()
-> kwargs.setdefault("allow_redirects", True)
(Pdb) kwargs
{}
(Pdb) n
> /Users/gethdav/dbConda-2022_05-py39/envs/virt-lab-man/lib/python3.10/site-packages/requests/sessions.py(600)get()
-> return self.request("GET", url, **kwargs)
(Pdb) kwargs
{'allow_redirects': True}
(Pdb) self.request("GET", url, **kwargs)
*** requests.exceptions.SSLError: HTTPSConnectionPool(host='x.x.x.x', port=443): Max retries exceeded with url: /api/v0/system_information (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:997)')))

virl2_client.exceptions.InitializationError: Controller version 2.2.2+build52 is marked incompatible! List of versions marked explicitly as incompatible: [2.0.0, 2.0.1, 2.1.0, 2.1.1, 2.1.2, 2.2.1, 2.2.2, 2.2.3].

I'm a new virlutils user. New cmlutils installation form pip. Trying to use with Cisco Modeling Labs (CML) v2.2.2 Sandbox on devnet. Getting error message:

virl2_client.exceptions.InitializationError: Controller version 2.2.2+build52 is marked incompatible! List of versions marked explicitly as incompatible: [2.0.0, 2.0.1, 2.1.0, 2.1.1, 2.1.2, 2.2.1, 2.2.2, 2.2.3].

What am I doing wrong?

don't do initial commands in pyats connect

Issue when using cml client to access an sd-wan device via pyats. The initial commands fail as they are not allowed on sd-wan device. The testbed is generated on the fly so I can't see a way to set init_exec_commands=[], init_config_commands=[] on the connect line in virl2_client/models/cl_pyats.py run_command.

Controller version 2.2.3+build63 is incompatible with virl2_client

Tried to create a testbed, but controller version 2.2.3+build63 is incompatible with virl2_client:

% python3 create_testbed_from_cml.py
SSL Verification disabled
Traceback (most recent call last):
File "/Users/danielkuhl/Coding/nauto-lab-connectivity/create_testbed_from_cml.py", line 10, in
client = ClientLibrary(url, user, password, ssl_verify=False)
File "/Users/danielkuhl/Coding/nauto-lab-connectivity/venv/lib/python3.9/site-packages/virl2_client/virl2_client.py", line 281, in init
self.check_controller_version()
File "/Users/danielkuhl/Coding/nauto-lab-connectivity/venv/lib/python3.9/site-packages/virl2_client/virl2_client.py", line 429, in check_controller_version
raise InitializationError(
virl2_client.virl2_client.InitializationError: Controller version 2.2.3+build63 is marked incompatible! List of versions marked explicitly as incompatible: [2.0.0, 2.0.1, 2.1.0, 2.1.1, 2.1.2, 2.2.1, 2.2.2, 2.2.3].

Tested with the following code:

from virl2_client import ClientLibrary
import os

# Set variables
url = os.environ.get("CML_URL")
user = os.environ.get("CML_USER")
password = os.environ.get("CML_PASS")

# Create a client object for interacting with CML
client = ClientLibrary(url, user, password, ssl_verify=False)

# Find your lab. Method returns a list, this assumes the first lab returned is what you want
lab = client.find_labs_by_title("Test-Lab")[0]

# Retrieve the testbed for the lab 
pyats_testbed = lab.get_pyats_testbed()

# Write the YAML testbed out to a file
with open("testbed.yaml", "w") as f: 
    f.write(pyats_testbed)

Tested with Python 3.9.13 in a virtual environment and the following packages installed:

Package                      Version
---------------------------- -----------
aiofiles                     0.8.0
aiohttp                      3.8.1
aiohttp-swagger              1.0.16
aiosignal                    1.2.0
async-lru                    1.0.3
async-timeout                4.0.2
attrs                        21.4.0
bcrypt                       3.2.2
certifi                      2022.5.18.1
cffi                         1.15.0
chardet                      4.0.0
charset-normalizer           2.0.12
cisco-gnmi                   1.0.15
click                        8.1.3
cryptography                 36.0.2
dill                         0.3.5.1
distro                       1.7.0
docopt                       0.6.2
Flask                        2.1.2
frozenlist                   1.3.0
genie                        22.4
genie.libs.clean             22.4.1
genie.libs.conf              22.4
genie.libs.filetransferutils 22.4
genie.libs.health            22.4
genie.libs.ops               22.4
genie.libs.parser            22.4
genie.libs.sdk               22.4
gitdb                        4.0.9
GitPython                    3.1.18
grpcio                       1.46.1
gunicorn                     20.1.0
idna                         3.3
importlib-metadata           4.12.0
itsdangerous                 2.1.2
Jinja2                       3.1.2
jsonpickle                   2.2.0
junit-xml                    1.9
lxml                         4.8.0
MarkupSafe                   2.1.1
multidict                    6.0.2
ncclient                     0.6.9
netaddr                      0.8.0
packaging                    21.3
paramiko                     2.11.0
pathspec                     0.9.0
pip                          22.1.2
prettytable                  3.3.0
protobuf                     3.20.1
psutil                       5.9.0
pyats                        22.4
pyats.aereport               22.4
pyats.aetest                 22.4
pyats.async                  22.4
pyats.connections            22.4
pyats.datastructures         22.4
pyats.easypy                 22.4
pyats.kleenex                22.4
pyats.log                    22.4
pyats.reporter               22.4
pyats.results                22.4
pyats.tcl                    22.4
pyats.topology               22.4
pyats.utils                  22.4
pycparser                    2.21
pyftpdlib                    1.5.6
PyNaCl                       1.5.0
pyparsing                    3.0.9
python-dateutil              2.8.2
python-engineio              3.14.2
python-socketio              4.6.1
PyYAML                       6.0
requests                     2.27.1
requests-toolbelt            0.9.1
ruamel.yaml                  0.17.21
ruamel.yaml.clib             0.2.6
setuptools                   62.3.2
six                          1.16.0
smmap                        5.0.0
tabulate                     0.8.10
tftpy                        0.8.0
tqdm                         4.64.0
unicon                       22.4
unicon.plugins               22.4
urllib3                      1.26.9
virl2-client                 2.4.0
virlutils                    1.3.8
wcwidth                      0.2.5
Werkzeug                     2.1.2
wheel                        0.37.1
xmltodict                    0.13.0
yamllint                     1.26.3
yang.connector               22.4
yarl                         1.7.2
zipp                         3.8.0

create_link failing for device ios when "next_available_interface" is Loopback 0

When using the method connect_two_nodes for two ios nodes
https://github.com/CiscoDevNet/virl2-client/blob/master/virl2_client/models/lab.py#L581

I get an Exception raised.

This occur when the next_available_interface is Loopback0 - I think the JSON payload returned here https://github.com/CiscoDevNet/virl2-client/blob/master/virl2_client/models/lab.py#L571 does not contain the key id most certainly because it makes no sense to create a link betwween Loopback0 and something else so probably it should be caught here.

Debugging logs below:

15:20:35,760 INFO: *** Adding link between Node: ios-1 and Node: ios-2
15:20:35,760 WARNING: Interface: Loopback0 <<<<<<<<<<< this is the output of node1.next_available_interface() or node1.create_interface()
15:20:35,806 WARNING: Interface: GigabitEthernet0/0
15:20:35,847 ERROR: API Error: {
  "description": "The API at /api/v0/labs/fd2fab/links encountered an unexpected error.  Please report this problem to support.",
  "code": 500
}
Traceback (most recent call last):
  File "virl2.py", line 125, in <module>
    add_n_devices(lab, "ios-", "iosv", n)
  File "virl2.py", line 111, in add_n_devices
    create_link(lab, previous_device, device)
  File "virl2.py", line 68, in create_link
    lab.connect_two_nodes(d1, d2)
  File "/Users/gmuloche/.pyenv/versions/3.7.7/lib/python3.7/site-packages/virl2_client/models/lab.py", line 594, in connect_two_nodes
    return self.create_link(iface1, iface2)
  File "/Users/gmuloche/.pyenv/versions/3.7.7/lib/python3.7/site-packages/virl2_client/models/lab.py", line 573, in create_link
    link_id = result["id"]
KeyError: 'id'

Compatibility with CML2.1.1

I am receiving "Please ensure the client version is compatible with the server version. client 2.1.0, server 2.1.1" when trying to run on the new CML 2.1.1. Is there any plan to update this to 2.1.1 soon?

create_image_definition results in 405 Error

The create_image_definition defines url as:
url = self._base_url + "image_definitions/" + image_id
This results in HTTP 405 error. The correct url should be:
url = self._base_url + "image_definitions/"

Enhancement: Show progress in more detail when uploading image

Current NodeImageDefinitions.upload_image_file shows progress like below while uploading image.

$ cml definitions images import image-file -f image.qcow2 
Uploading image.qcow2
Progress: 8192 of 19202219 bytes (0%)

But the progress is updated every 10% of the uploaded size. It won't be helpful if the size of the image is big. And I don't think all of us always have stable and high speed uplink to CML.

So I propose more detailed progress report like below. This will be updated every time monitor is called and new byte is processed.

$ cml definitions images import image-file -f ~/Downloads/image.qcow2
Uploading image.qcow2
 |###-----------------------------------------------| 1032192/19202219 5.4% [00:00:06]


 |##################################################| 19202219/19202219 100.0% [00:02:07]
Upload completed

requests_toolbelt is required

virl2-client requires requests_toolbelt, but it is not listed in the poetry.lock or in the wheel/dist on PyPi.

The workaround is to manually install requests_toolbelt.

Node.stop() and node.wipe() don't wait properly

If you call node.stop() or node.wipe() with the wait=True flag, they still return immediately. I think this is because both methods use the same has_converged() code that node.start() uses. This might be fine, but my guess is the /check_if_converged API endpoint is not doing the right thing for the stop and wipe operations.

For wipe, this may not be a big deal. For stop, my code assumes that when stop(wait=True) completes, the node is down and can be wiped. This is not deterministically true, and therefore I had to add:

node.stop(wait=True)
while node.is_active():
    time.sleep(1)

I'd like the wait=True to be honored.

add_tag() in node.py results in multiple copies of the same tag being added

When using node.py add_tag() because it is reading and subsequently appending the new tag to self._tags and then pushing the list to the API it results in multiple entries of the same tag being pushed to CML.

My test code is:

        # Apply Tags to Nodes
        if len(node_tags) > 0:
            print(f'Tag Count for node {node_label} is {len(node_tags)}')
            print(f'Node Tags for node {node_label} are {new_node.tags()}')
            for tag in node_tags:
                print(f'Adding tag {tag} to node {node_label}...')
                print(f'Node Tags for node {node_label} are {new_node.tags()}')
                new_node.add_tag(tag)
                sleep(2)
                print(f'Node Tags for node {node_label} are {new_node.tags()}')

The output from a test where I'm attempting to add 3 tags (oob, routers, test) to the device shows as follows:

Tag Count for node dc_router01 is 3
Node Tags for node dc_router01 are []
Adding tag oob to node dc_router01...
Node Tags for node dc_router01 are []
Node Tags for node dc_router01 are ['oob']
Adding tag routers to node dc_router01...
Node Tags for node dc_router01 are ['oob']
Node Tags for node dc_router01 are ['oob', 'oob', 'routers']
Adding tag test to node dc_router01...
Node Tags for node dc_router01 are ['oob', 'oob', 'routers']
Node Tags for node dc_router01 are ['oob', 'oob', 'routers', 'oob', 'oob', 'routers', 'test']

I've fixed this with a modification to node.py to only push the single tag to the API endpoint as follows:

    def add_tag(self, tag):
        current = self._tags
        if tag not in current:
            current.append(tag)
            # Push single tag to API
            self._set_node_property("tags", [tag])

And the output after the change:

Tag Count for node dc_router01 is 3
Node Tags for node dc_router01 are []
Adding tag oob to node dc_router01...
Node Tags for node dc_router01 are []
Node Tags for node dc_router01 are ['oob']
Adding tag routers to node dc_router01...
Node Tags for node dc_router01 are ['oob']
Node Tags for node dc_router01 are ['oob', 'routers']
Adding tag test to node dc_router01...
Node Tags for node dc_router01 are ['oob', 'routers']
Node Tags for node dc_router01 are ['oob', 'routers', 'test']

To get the BOOTED value of the lab

Hi,

I want to shut down an abandoned lab at a certain period of time. The startup time of the lab can be obtained in the lab's BOOTED. However, virl2_client does not allow me to get this value.

I hope that virl2_client will be extended to be able to get the BOOTED of the lab.

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.