Skip to content

Instantly share code, notes, and snippets.

@hoelsner
Created January 16, 2022 15:22
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save hoelsner/ec0d9f49274442b4e3fc674f64f3230e to your computer and use it in GitHub Desktop.
Save hoelsner/ec0d9f49274442b4e3fc674f64f3230e to your computer and use it in GitHub Desktop.
Example script to create a lab with some routers on CML 2.2
#!python3.8
"""
==================================
Create CML Example Network via API
==================================
To use the script, simply create a .env file in the same directory as the script and add the following content (with the options required in your environment):
CML_SERVER=https://cml.codingnetworker.com/
CML_SSL_VERIFY=yes
CML_USERNAME=admin
CML_PASSWORD=plschgme
DEVICE_USERNAME=cisco
DEVICE_PASSWORD=cisco
OOB_NETMASK=255.255.255.0
OOB_R1_IP=192.168.164.231
OOB_R2_IP=192.168.164.232
OOB_R3_IP=192.168.164.233
You need to install the following requirements prior using this script:
virl2_client==2.2.1.post2
python-dotenv==0.19.2
"""
import os
from string import Template
import distutils.util
from virl2_client import ClientLibrary
from dotenv import load_dotenv
if __name__ == "__main__":
load_dotenv()
# connect to CML instance
print("Connected to CML...", end="")
client = ClientLibrary(
os.environ.get("CML_SERVER", "https://cml.codingnetworker.com/"),
os.environ.get("CML_USERNAME", "admin"),
os.environ.get("CML_PASSWORD", "plschgme"),
ssl_verify=bool(distutils.util.strtobool(os.environ.get("CML_SSL_VERIFY", "yes")))
)
client.is_system_ready(wait=True)
print("DONE")
# now let's create three routers that are connected to each other and to an OOB switch for external connectivity
# furthermore, we need to set a start configuration for the IOS switches so that they are reachable after the start of the lab
print("Create test lab with three routers...", end="")
lab = client.create_lab(title="TestLab_A")
# $hostname and $oob_ip are used as attributes when rendering a Template with the substitute function
config_template = Template(f"""\
no service config
hostname $hostname
ip domain name cml.local
no ip domain lookup
interface GigabitEthernet0/0
description out-of-band interface
no ip address
ip address $oob_ip {os.environ.get('OOB_NETMASK','255.255.255.0')}
no shut
username {os.environ.get('DEVICE_USERNAME','cisco')} privilege 15 secret {os.environ.get('DEVICE_PASSWORD','cisco')}
enable secret {os.environ.get('DEVICE_PASSWORD','cisco')}
line vty 0 4
login local
transport input telnet ssh
!
! overwrite default banners
no banner exec
no banner incoming
no banner login""")
# create three routers and set the startup configuration
r1 = lab.create_node(label="r1", node_definition="iosv", x=100, y=0)
r1.config = config_template.substitute(hostname="r1", oob_ip=os.environ.get("OOB_R1_IP", "192.168.164.231"))
r2 = lab.create_node(label="r2", node_definition="iosv", x=200, y=200)
r2.config = config_template.substitute(hostname="r2", oob_ip=os.environ.get("OOB_R2_IP", "192.168.164.232"))
r3 = lab.create_node(label="r3", node_definition="iosv", x=0, y=200)
r3.config = config_template.substitute(hostname="r3", oob_ip=os.environ.get("OOB_R3_IP", "192.168.164.233"))
# add an external connector together with an Unmanaged Switch for OOB connectivity
ext_conn = lab.create_node(label="external bridge", node_definition="external_connector", x=400, y=0)
ext_conn.config = "bridge0"
usw = lab.create_node(label="oob_sw", node_definition="unmanaged_switch", x=300, y=0)
# create all required interfaces
lab.connect_two_nodes(usw, ext_conn)
lab.connect_two_nodes(usw, r2)
lab.connect_two_nodes(usw, r3)
lab.connect_two_nodes(usw, r1)
lab.connect_two_nodes(r1, r2)
lab.connect_two_nodes(r2, r3)
lab.connect_two_nodes(r3, r1)
print("DONE")
print("Start the lab...", end="")
lab.start()
print("DONE")
input("--- Press anykey to stop the lab ---")
# stop, wipe and remove the lab
print("\nRemove the lab from server...", end="")
lab.stop()
lab.wipe()
lab.remove()
print("DONE")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment