Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transparent management interfaces for Cisco nodes. #290

Merged
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions c8000v/docker/launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ def bootstrap_spin(self):
def bootstrap_config(self):
"""Do the actual bootstrap config"""
self.logger.info("applying bootstrap configuration")

v4_mgmt_address = vrnetlab.cidr_to_ddn(self.mgmt_address_ipv4)

self.wait_write("", None)
self.wait_write("enable", wait=">")
Expand All @@ -165,17 +167,23 @@ def bootstrap_config(self):
self.wait_write("ip domain-name example.com")
self.wait_write("crypto key generate rsa modulus 2048")

self.wait_write("ipv6 unicast-routing")

self.wait_write("vrf definition clab-mgmt")
self.wait_write("description Containerlab management VRF (DO NOT DELETE)")
self.wait_write("address-family ipv4")
self.wait_write("exit")
self.wait_write("description Containerlab management VRF (DO NOT DELETE)")
self.wait_write("address-family ipv6")
self.wait_write("exit")
self.wait_write("exit")

self.wait_write("ip route vrf clab-mgmt 0.0.0.0 0.0.0.0 10.0.0.2")
self.wait_write(f"ip route vrf clab-mgmt 0.0.0.0 0.0.0.0 {self.mgmt_gw_ipv4}")
self.wait_write(f"ipv6 route vrf clab-mgmt ::/0 {self.mgmt_gw_ipv6}")

self.wait_write("interface GigabitEthernet1")
self.wait_write("vrf forwarding clab-mgmt")
self.wait_write("ip address 10.0.0.15 255.255.255.0")
self.wait_write(f"ip address {v4_mgmt_address[0]} {v4_mgmt_address[1]}")
self.wait_write(f"ipv6 address {self.mgmt_address_ipv6}")
self.wait_write("no shut")
self.wait_write("exit")
self.wait_write("restconf")
Expand Down
10 changes: 8 additions & 2 deletions cat9kv/docker/launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ def bootstrap_spin(self):
def bootstrap_config(self):
"""Do the actual bootstrap config"""
self.logger.info("applying bootstrap configuration")

v4_mgmt_address = vrnetlab.cidr_to_ddn(self.mgmt_address_ipv4)

self.wait_write("", None)
self.wait_write("enable", wait=">")
Expand All @@ -173,12 +175,16 @@ def bootstrap_config(self):
self.wait_write("crypto key generate rsa modulus 2048")

self.wait_write("no ip domain lookup")

self.wait_write("ipv6 unicast-routing")

# add mgmt vrf static route
self.wait_write("ip route vrf Mgmt-vrf 0.0.0.0 0.0.0.0 10.0.0.2")
self.wait_write(f"ip route vrf clab-mgmt 0.0.0.0 0.0.0.0 {self.mgmt_gw_ipv4}")
self.wait_write(f"ipv6 route vrf clab-mgmt ::/0 {self.mgmt_gw_ipv6}")

self.wait_write("interface GigabitEthernet0/0")
self.wait_write("ip address 10.0.0.15 255.255.255.0")
self.wait_write(f"ip address {v4_mgmt_address[0]} {v4_mgmt_address[1]}")
self.wait_write(f"ipv6 address {self.mgmt_address_ipv6}")
self.wait_write("no shut")
self.wait_write("exit")

Expand Down
28 changes: 28 additions & 0 deletions common/vrnetlab.py
Original file line number Diff line number Diff line change
Expand Up @@ -837,3 +837,31 @@ def get_digits(input_str: str) -> int:

non_string_chars = re.findall(r"\d", input_str)
return int("".join(non_string_chars))

def cidr_to_ddn(prefix: str):
"""
Convert a IPv4 CIDR notation prefix to address + mask in DDN notation

Returns a list of IP address (str) and mask (str) in dotted decimal

Example:
get_ddn_mask('192.168.0.1/24')
returns ['192.168.0.1' ,'255.255.255.0']
"""

address, _, mask = prefix.partition("/")
mask = int(mask)

if mask > 32 or mask <= 0:
raise ValueError(f"Prefix: {prefix} has invalid mask length. Should be from 1-32 (inclusive).")

# turn the prefix length into a bitmask
bit_mask = f"{'1' * mask}{'0'*(32-mask)}"

# split bit mask into 4 octets and convert to binary
octets = [bit_mask[i:i+8] for i in range(0, 32, 8)]

# from each octet in the list, turn it into a single string and add the dots
ddn_mask = '.'.join(str(int(octet, 2)) for octet in octets)

return([address, ddn_mask])
hellt marked this conversation as resolved.
Show resolved Hide resolved
14 changes: 11 additions & 3 deletions csr/docker/launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ def bootstrap_spin(self):
def bootstrap_config(self):
"""Do the actual bootstrap config"""
self.logger.info("applying bootstrap configuration")

v4_mgmt_address = vrnetlab.cidr_to_ddn(self.mgmt_address_ipv4)

self.wait_write("", None)
self.wait_write("enable", wait=">")
Expand All @@ -159,17 +161,23 @@ def bootstrap_config(self):
self.wait_write("ip domain-name example.com")
self.wait_write("crypto key generate rsa modulus 2048")

self.wait_write("ipv6 unicast-routing")

self.wait_write("vrf definition clab-mgmt")
self.wait_write("description Containerlab management VRF (DO NOT DELETE)")
self.wait_write("address-family ipv4")
self.wait_write("exit")
self.wait_write("description Containerlab management VRF (DO NOT DELETE)")
self.wait_write("address-family ipv6")
self.wait_write("exit")
self.wait_write("exit")

self.wait_write("ip route vrf clab-mgmt 0.0.0.0 0.0.0.0 10.0.0.2")
self.wait_write(f"ip route vrf clab-mgmt 0.0.0.0 0.0.0.0 {self.mgmt_gw_ipv4}")
self.wait_write(f"ipv6 route vrf clab-mgmt ::/0 {self.mgmt_gw_ipv6}")

self.wait_write("interface GigabitEthernet1")
self.wait_write("vrf forwarding clab-mgmt")
self.wait_write("ip address 10.0.0.15 255.255.255.0")
self.wait_write(f"ip address {v4_mgmt_address[0]} {v4_mgmt_address[1]}")
self.wait_write(f"ipv6 address {self.mgmt_address_ipv6}")
self.wait_write("no shut")
self.wait_write("exit")
self.wait_write("restconf")
Expand Down
15 changes: 5 additions & 10 deletions n9kv/Makefile
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
VENDOR=Cisco
NAME=NXOS 9000v
NAME=n9kv
IMAGE_FORMAT=qcow2
IMAGE_GLOB=*.qcow2

# Match versions similar to the following:
# - nxosv-final.7.0.3.I7.5a.qcow2
# - nxosv-final.7.0.3.I7.9.qcow2
# - nxosv.9.2.1.qcow2
# - nxosv.9.2.4.qcow2
# - nexus9300v.9.3.9.qcow2
# - nexus9300v.9.3.10.qcow2
# - nexus9300v64.10.2.2.F.qcow
VERSION=$(shell echo $(IMAGE) | sed -e 's/.\+\?\.\(\(7\.0\.3\.I[0-9]\.[0-9a-z]\+\)\|\([0-9]\+\.[0-9]\+\.[0-9]\+\)\)\(\..*\|$$\)/\1/')
# rename the disk image file as n9kv-<version>.qcow2
# examples:
# for a file named "n9kv_9300-10.5.2.qcow2" the image will be named "vrnetlab/cisco_n9kv:9300-10.5.2"
kaelemc marked this conversation as resolved.
Show resolved Hide resolved
VERSION=$(shell echo $(IMAGE) | sed -e 's/n9kv-\(.*\)\.qcow2/\1/')

-include ../makefile-sanity.include
-include ../makefile.include
8 changes: 3 additions & 5 deletions n9kv/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
FROM ubuntu:20.04
LABEL maintainer="Kristian Larsson <[email protected]>"
LABEL maintainer="Roman Dodin <[email protected]>"
FROM public.ecr.aws/docker/library/debian:bookworm-slim
LABEL maintainer="Roman Dodin <[email protected]>, Kaelem Chandra <[email protected]>"

ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update -qy \
&& apt-get upgrade -qy \
&& apt-get install -y \
&& apt-get install -y --no-install-recommends \
bridge-utils \
iproute2 \
python3-ipy \
Expand Down
10 changes: 8 additions & 2 deletions n9kv/docker/launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,19 @@ def bootstrap_config(self):

# configure management vrf
self.wait_write("vrf context management")
self.wait_write("ip route 0.0.0.0/0 10.0.0.2")
self.wait_write(f"ip route 0.0.0.0/0 {self.mgmt_gw_ipv4}")
self.wait_write(f"ipv6 route ::/0 {self.mgmt_gw_ipv6}")
self.wait_write("exit")

# configure mgmt interface
self.wait_write("interface mgmt0")
self.wait_write("ip address 10.0.0.15/24")
self.wait_write(f"ip address {self.mgmt_address_ipv4}")
self.wait_write(f"ipv6 address {self.mgmt_address_ipv6}")
self.wait_write("exit")

# configure longer ssh keys
self.wait_write("ssh key rsa 2048 force")
self.wait_write("feature ssh")

# setup nxapi/scp server
self.wait_write("feature scp-server")
Expand Down
15 changes: 14 additions & 1 deletion nxos/docker/launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,23 @@ def bootstrap_config(self):
)
self.wait_write("hostname %s" % (self.hostname))

# configure management vrf
self.wait_write("vrf context management")
self.wait_write(f"ip route 0.0.0.0/0 {self.mgmt_gw_ipv4}")
self.wait_write(f"ipv6 route ::/0 {self.mgmt_gw_ipv6}")
self.wait_write("exit")

# configure mgmt interface
self.wait_write("interface mgmt0")
self.wait_write("ip address 10.0.0.15/24")
self.wait_write(f"ip address {self.mgmt_address_ipv4}")
self.wait_write(f"ipv6 address {self.mgmt_address_ipv6}")
self.wait_write("exit")

# configure longer ssh keys
self.wait_write("no feature ssh")
self.wait_write("ssh key rsa 2048 force")
self.wait_write("feature ssh")

self.wait_write("exit")
self.wait_write("copy running-config startup-config")

Expand Down
9 changes: 3 additions & 6 deletions vios/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ The following protocols are enabled on the management interface:

| ID | Description | Default |
|-----------------|---------------------------|------------|
| USERNAME | SSH username | vrnetlab |
| PASSWORD | SSH password | VR-netlab9 |
| USERNAME | SSH username | admin |
| PASSWORD | SSH password | admin |
| HOSTNAME | device hostname | vios |
| TRACE | enable trace logging | false |
| CONNECTION_MODE | interface connection mode | tc |
Expand All @@ -75,10 +75,7 @@ name: vios-lab
topology:
kinds:
linux:
image: vrnetlab/vr-vios:15.9.3M6
env:
USERNAME: admin
PASSWORD: admin
image: vrnetlab/cisco_vios:15.9.3M6
nodes:
vios1:
kind: linux
Expand Down
20 changes: 15 additions & 5 deletions vios/docker/launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ def _bootstrap_config(self):
self.wait_write(f"hostname {self.hostname}")
self.wait_write(f"ip domain-name {self.hostname}.clab")
self.wait_write("no ip domain-lookup")

# Explicitly enable IPv6
self.wait_write("ipv6 unicast-routing")

self.wait_write(f"username {self.username} privilege 15 secret {self.password}")

Expand All @@ -138,17 +141,24 @@ def _bootstrap_config(self):
self.wait_write("exit")

self.wait_write("vrf definition clab-mgmt")
self.wait_write("description Containerlab management VRF (DO NOT DELETE)")
self.wait_write("address-family ipv4")
self.wait_write("exit")
self.wait_write("description Management network")
self.wait_write("address-family ipv6")
self.wait_write("exit")
self.wait_write("exit")

v4_mgmt_address = vrnetlab.cidr_to_ddn(self.mgmt_address_ipv4)

self.wait_write("interface GigabitEthernet0/0")
self.wait_write("vrf forwarding clab-mgmt")
self.wait_write("ip address 10.0.0.15 255.255.255.0")
self.wait_write(f"ip address {v4_mgmt_address[0]} {v4_mgmt_address[1]}")
self.wait_write(f"ipv6 address {self.mgmt_address_ipv6}")
self.wait_write("no shutdown")
self.wait_write("exit")
self.wait_write("ip route vrf clab-mgmt 0.0.0.0 0.0.0.0 10.0.0.2")

self.wait_write(f"ip route vrf clab-mgmt 0.0.0.0 0.0.0.0 {self.mgmt_gw_ipv4}")
self.wait_write(f"ipv6 route vrf clab-mgmt ::/0 {self.mgmt_gw_ipv6}")

self.wait_write("crypto key generate rsa modulus 2048")
self.wait_write("ip ssh version 2")
Expand Down Expand Up @@ -195,10 +205,10 @@ def __init__(self, hostname: str, username: str, password: str, conn_mode: str):
default=os.getenv("TRACE", "false").lower() == "true",
)
parser.add_argument(
"--username", help="Username", default=os.getenv("USERNAME", "vrnetlab")
"--username", help="Username", default=os.getenv("USERNAME", "admin")
)
parser.add_argument(
"--password", help="Password", default=os.getenv("PASSWORD", "VR-netlab9")
"--password", help="Password", default=os.getenv("PASSWORD", "admin")
)
parser.add_argument(
"--hostname", help="Router hostname", default=os.getenv("HOSTNAME", "vios")
Expand Down
10 changes: 8 additions & 2 deletions xrv/docker/launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,18 @@ def bootstrap_config(self):
self.wait_write("description Containerlab management VRF (DO NOT DELETE)")
self.wait_write("address-family ipv4 unicast")
self.wait_write("exit")
self.wait_write("address-family ipv6 unicast")
self.wait_write("exit")
self.wait_write("exit")

# add static route for management
self.wait_write("router static")
self.wait_write("vrf clab-mgmt")
self.wait_write("address-family ipv4 unicast")
self.wait_write("0.0.0.0/0 10.0.0.2")
self.wait_write(f"0.0.0.0/0 {self.mgmt_gw_ipv4}")
self.wait_write("exit")
self.wait_write("address-family ipv6 unicast")
self.wait_write(f"::/0 {self.mgmt_gw_ipv6}")
self.wait_write("exit")
self.wait_write("exit")
self.wait_write("exit")
Expand All @@ -203,7 +208,8 @@ def bootstrap_config(self):
self.wait_write("interface MgmtEth 0/0/CPU0/0")
self.wait_write("vrf clab-mgmt")
self.wait_write("no shutdown")
self.wait_write("ipv4 address 10.0.0.15/24")
self.wait_write(f"ipv4 address {self.mgmt_address_ipv4}")
self.wait_write(f"ipv6 address {self.mgmt_address_ipv6}")
self.wait_write("exit")
self.wait_write("commit")
self.wait_write("exit")
Expand Down
Loading