Skip to content

Commit dd794ff

Browse files
authored
Merge pull request #77 from sacckth/srsim
SR-SIM support coming on EDA 25.8.1
2 parents 9d42d04 + ef7a2c5 commit dd794ff

File tree

11 files changed

+127
-68
lines changed

11 files changed

+127
-68
lines changed

clab_connector/cli/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
# Disable urllib3 warnings (optional)
2424
urllib3.disable_warnings()
2525

26-
SUPPORTED_KINDS = ["nokia_srlinux", "nokia_sros"]
26+
SUPPORTED_KINDS = ["nokia_srlinux", "nokia_sros", "nokia_srsim"]
2727
NODE_DISPLAY_LIMIT = 5
2828

2929

clab_connector/models/node/factory.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
KIND_MAPPING = {
1212
"nokia_srlinux": NokiaSRLinuxNode,
1313
"nokia_sros": NokiaSROSNode,
14+
"nokia_srsim": NokiaSROSNode,
1415
}
1516

1617

clab_connector/models/node/nokia_srl.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,9 @@ def get_default_node_type(self):
9797
Returns
9898
-------
9999
str
100-
The default node type (e.g., "ixrd3l").
100+
The default node type (e.g., "ixr-d3l").
101101
"""
102-
return "ixrd3l"
102+
return "ixr-d3l"
103103

104104
def get_platform(self):
105105
"""
@@ -110,13 +110,22 @@ def get_platform(self):
110110
str
111111
The platform name (e.g. '7220 IXR-D3L').
112112
"""
113-
# Handle IXS-A1 with both old (ixsa1) and new (ixs-a1) syntax
114-
if self.node_type and self.node_type.lower() in ["ixsa1", "ixs-a1"]:
115-
return "7215 IXS-A1"
116-
117-
# Handle both old (ixrd2l) and new (ixr-d2l) clab type syntax
118-
t = self.node_type.replace("ixr-", "").replace("ixr", "")
119-
return f"7220 IXR-{t.upper()}"
113+
m = re.match(r"(?i)(^ixr|^sxr|^ixs)-?(.*)$", self.node_type)
114+
if m:
115+
prefix = m.group(1) or ""
116+
suffix = m.group(2) or ""
117+
if prefix.lower().startswith("ixr") and suffix.lower().startswith(
118+
("h", "d")
119+
):
120+
return f"7220 IXR-{suffix.upper()}"
121+
elif prefix.lower().startswith("sxr"):
122+
return f"7730 IXR-{suffix.upper()}"
123+
elif prefix.lower().startswith("ixs"):
124+
return f"7215 IXS-{suffix.upper()}"
125+
else:
126+
return f"7250 IXR-{suffix.upper()}"
127+
else:
128+
return "NoMatchOnClabType"
120129

121130
def is_eda_supported(self):
122131
"""

clab_connector/models/node/nokia_sros.py

Lines changed: 53 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -242,45 +242,59 @@ def get_toponode(self, topology):
242242
return helpers.render_template("toponode.j2", data)
243243

244244
def get_interface_name_for_kind(self, ifname):
245-
"""Convert a containerlab interface name to the SR OS EDA format."""
246-
247-
eda_name = ifname
248-
249-
m = re.match(r"^(\d+)/(\d+)/(\d+)$", ifname)
250-
if m:
251-
slot, mda_num, port = m.groups()
252-
mda_letter = chr(96 + int(mda_num))
253-
eda_name = f"ethernet-{slot}-{mda_letter}-{port}-1"
254-
else:
255-
m = re.match(r"^(\d+)/(\d+)/c(\d+)/(\d+)$", ifname)
256-
if m:
257-
slot, mda_num, channel, port = m.groups()
258-
if mda_num == "1":
259-
eda_name = f"ethernet-{slot}-{channel}-{port}"
260-
else:
261-
mda_letter = chr(96 + int(mda_num))
262-
eda_name = f"ethernet-{slot}-{mda_letter}-{channel}-{port}"
263-
else:
264-
m = re.match(r"^(\d+)/x(\d+)/(\d+)/(\d+)$", ifname)
265-
if m:
266-
slot, xiom_id, mda_num, port = m.groups()
267-
mda_letter = chr(96 + int(mda_num))
268-
eda_name = f"ethernet-{slot}-{xiom_id}-{mda_letter}-{port}"
269-
else:
270-
m = re.match(r"^eth(\d+)$", ifname)
271-
if m:
272-
eda_name = f"ethernet-1-a-{m.group(1)}-1"
273-
else:
274-
m = re.match(r"^e(\d+)-(\d+)$", ifname)
275-
if m:
276-
slot, port = m.groups()
277-
eda_name = f"ethernet-{slot}-a-{port}-1"
278-
else:
279-
m = re.match(r"^lo(\d+)$", ifname)
280-
if m:
281-
eda_name = f"loopback-{m.group(1)}"
282-
283-
return eda_name
245+
"""Convert a containerlab interface name to the SR OS EDA format.
246+
247+
Supported input formats:
248+
- "1-2-3" -> "ethernet-1-b-3"
249+
- "1-2-c3-4" -> "ethernet-1-b-3-4" (mda>1) | "1-1-c3-4" -> "ethernet-1-3-4" (mda=1)
250+
- "1-x2-1-3" -> "ethernet-1-2-1-3"
251+
- "1-x2-1-c3-1" -> "ethernet-1-2-1-3-1"
252+
253+
Args:
254+
ifname: Interface name in containerlab format
255+
256+
Returns:
257+
Interface name in SR OS EDA format
258+
"""
259+
260+
def mda_to_letter(mda_num):
261+
"""Convert MDA number to letter (1->a, 2->b, etc.)"""
262+
return chr(96 + int(mda_num))
263+
264+
# Define patterns with their transformation logic
265+
patterns = [
266+
# Pattern: "1-2-3" -> "ethernet-1-b-3"
267+
(
268+
r"^e(\d+)-(\d+)-(\d+)$",
269+
lambda m: f"ethernet-{m[0]}-{mda_to_letter(m[1])}-{m[2]}",
270+
),
271+
# Pattern: "1-2-c3-4" -> conditional format
272+
(
273+
r"^e(\d+)-(\d+)-c(\d+)-(\d+)$",
274+
lambda m: f"ethernet-{m[0]}-{m[2]}-{m[3]}"
275+
if m[2] == "1"
276+
else f"ethernet-{m[0]}-{mda_to_letter(m[1])}-{m[2]}-{m[3]}",
277+
),
278+
# Pattern: "1-x2-1-c3-1" -> "ethernet-1-2-1-c3-1"
279+
(
280+
r"^e(\d+)-x(\d+)-(\d+)-c(\d+)-(\d+)$",
281+
lambda m: f"ethernet-{m[0]}-{m[1]}-{mda_to_letter(m[2])}-{m[3]}-{m[4]}",
282+
),
283+
# Pattern: "1-x2-1-3" -> "ethernet-1-2-1-3"
284+
(
285+
r"^e(\d+)-x(\d+)-(\d+)-(\d+)$",
286+
lambda m: f"ethernet-{m[0]}-{m[1]}-{mda_to_letter(m[2])}-{m[3]}",
287+
),
288+
]
289+
290+
# Try each pattern
291+
for pattern, transformer in patterns:
292+
match = re.match(pattern, ifname)
293+
if match:
294+
return transformer(match.groups())
295+
296+
# Return "bollocks" if no pattern matches
297+
return "Bollocks"
284298

285299
def get_topolink_interface_name(self, topology, ifname):
286300
"""

clab_connector/services/export/topology_exporter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def _build_node_definition(self, node_item):
160160
# guess 'nokia_srlinux' if operating_system is 'srl*'
161161
kind = "nokia_srlinux"
162162
if operating_system.lower().startswith("sros"):
163-
kind = "nokia_sros"
163+
kind = "nokia_srsim"
164164

165165
node_def = {
166166
"kind": kind,

clab_connector/services/integration/sros_post_integration.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -353,21 +353,24 @@ def prepare_sros_node(
353353
namespace: str,
354354
version: str,
355355
mgmt_ip: str,
356+
node_type: str,
356357
username: str = "admin",
357358
password: str | None = None,
358-
quiet: bool = False,
359+
quiet: bool = True,
359360
) -> bool:
360361
"""
361362
Perform SROS-specific post-integration steps.
362363
"""
363364
# First check if we can login with admin:admin
364365
# If we can't, assume the node is already bootstrapped
365-
admin_pwd = "admin"
366+
admin_pwd = "admin" if node_type == "nokia_sros" else "NokiaSros1!"
366367
can_login = verify_ssh_credentials(mgmt_ip, username, [admin_pwd], quiet)
367368

368-
if not can_login:
369+
if not can_login and node_type == "nokia_sros":
369370
logger.info("Node: %s already bootstrapped", node_name)
370371
return True
372+
if not can_login:
373+
logger.error("Can't login to node %s of kind %s", node_name, node_type)
371374

372375
# Proceed with original logic if admin:admin works
373376
# 1. determine password list (keep provided one first if present)
@@ -382,7 +385,6 @@ def prepare_sros_node(
382385
if not working_pw:
383386
logger.error("No valid password found - aborting")
384387
return False
385-
386388
# 2. create temp artefacts
387389
with tempfile.TemporaryDirectory() as tdir:
388390
tdir_path = Path(tdir)

clab_connector/services/integration/topology_integrator.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -386,13 +386,17 @@ def create_topolinks(self, skip_edge_links: bool = False):
386386

387387
def run_sros_post_integration(self, node, namespace, normalized_version, quiet):
388388
"""Run SROS post-integration"""
389+
password = "NokiaSros1!"
390+
if node.kind == "nokia_sros":
391+
password = "admin"
389392
return prepare_sros_node(
390393
node_name=node.get_node_name(self.topology),
391394
namespace=namespace,
392395
version=normalized_version,
393396
mgmt_ip=node.mgmt_ipv4,
394397
username="admin",
395-
password="admin",
398+
password=password,
399+
node_type=node.kind,
396400
quiet=quiet,
397401
)
398402

@@ -406,9 +410,9 @@ def run_post_integration(self):
406410

407411
# Look for SROS nodes and run post-integration for them
408412
for node in self.topology.nodes:
409-
if node.kind == "nokia_sros":
413+
if node.kind in {"nokia_sros", "nokia_srsim"}:
410414
logger.info(
411-
f"{SUBSTEP_INDENT}Running SROS post-integration for node {node.name}"
415+
f"{SUBSTEP_INDENT}Running SROS post-integration for node {node.name} kind {node.kind}"
412416
)
413417
try:
414418
# Get normalized version from the node

example-topologies/EDA-sros.clab.yml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,27 @@ name: eda_sros
33
topology:
44
kinds:
55
nokia_srlinux:
6-
image: ghcr.io/nokia/srlinux:24.10.1
7-
nokia_sros:
8-
image: registry.srlinux.dev/pub/vr-sros:25.3.R2
6+
image: ghcr.io/nokia/srlinux:25.7.1
7+
nokia_srsim:
8+
image: registry.srlinux.dev/pub/nokia_srsim:25.7.R1
99
type: SR-1
10-
license: license.txt
10+
license: /opt/nokia/license_sros.txt
1111
nodes:
1212
dc-gw-1:
13-
kind: nokia_sros
13+
kind: nokia_srsim
14+
env:
15+
NOKIA_SROS_MDA_1: me12-100gb-qsfp28
1416
spine1:
1517
kind: nokia_srlinux
16-
type: ixrd5
18+
type: ixr-d5
1719
leaf1:
1820
kind: nokia_srlinux
19-
type: ixrd3l
21+
type: ixr-d3l
2022
leaf2:
2123
kind: nokia_srlinux
22-
type: ixrd3l
24+
type: ixr-d3l
2325

2426
links:
2527
- endpoints: ["spine1:e1-1", "leaf1:e1-33"]
2628
- endpoints: ["spine1:e1-2", "leaf2:e1-34"]
27-
- endpoints: ["spine1:e1-3", "dc-gw-1:1/1/3"]
29+
- endpoints: ["spine1:e1-3", "dc-gw-1:1/1/c3/1"]
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: eda_sros
2+
3+
topology:
4+
kinds:
5+
nokia_srlinux:
6+
image: ghcr.io/nokia/srlinux:24.10.1
7+
nokia_sros:
8+
image: registry.srlinux.dev/pub/vr-sros:25.3.R2
9+
type: SR-1
10+
license: license.txt
11+
nodes:
12+
dc-gw-1:
13+
kind: nokia_sros
14+
spine1:
15+
kind: nokia_srlinux
16+
type: ixrd5
17+
leaf1:
18+
kind: nokia_srlinux
19+
type: ixrd3l
20+
leaf2:
21+
kind: nokia_srlinux
22+
type: ixrd3l
23+
24+
links:
25+
- endpoints: ["spine1:e1-1", "leaf1:e1-33"]
26+
- endpoints: ["spine1:e1-2", "leaf2:e1-34"]
27+
- endpoints: ["spine1:e1-3", "dc-gw-1:1/1/3"]

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "clab-connector"
7-
version = "0.5.10"
7+
version = "0.6.0"
88
description = "EDA Containerlab Connector"
99
readme = "README.md"
1010
requires-python = ">=3.11"

0 commit comments

Comments
 (0)