From 773c5581edceef75864f7d67e5ea38fab056bc87 Mon Sep 17 00:00:00 2001 From: Komal Thareja Date: Thu, 27 Jun 2024 23:50:33 -0400 Subject: [PATCH 01/15] changes for sub interface support --- fabrictestbed_extensions/fablib/component.py | 38 +++++------ fabrictestbed_extensions/fablib/constants.py | 13 ++++ fabrictestbed_extensions/fablib/interface.py | 70 +++++++++++++++++++- 3 files changed, 100 insertions(+), 21 deletions(-) diff --git a/fabrictestbed_extensions/fablib/component.py b/fabrictestbed_extensions/fablib/component.py index eb7c383a..de0a7702 100644 --- a/fabrictestbed_extensions/fablib/component.py +++ b/fabrictestbed_extensions/fablib/component.py @@ -44,6 +44,8 @@ import jinja2 +from fabrictestbed_extensions.fablib.constants import Constants + if TYPE_CHECKING: from fabrictestbed_extensions.fablib.slice import Slice from fabrictestbed_extensions.fablib.node import Node @@ -60,17 +62,17 @@ class Component: component_model_map = { - "NIC_Basic": ComponentModelType.SharedNIC_ConnectX_6, - "NIC_ConnectX_6": ComponentModelType.SmartNIC_ConnectX_6, - "NIC_ConnectX_5": ComponentModelType.SmartNIC_ConnectX_5, - "NIC_P4": "P4_DedicatedPort", - "NVME_P4510": ComponentModelType.NVME_P4510, - "GPU_TeslaT4": ComponentModelType.GPU_Tesla_T4, - "GPU_RTX6000": ComponentModelType.GPU_RTX6000, - "GPU_A40": ComponentModelType.GPU_A40, - "GPU_A30": ComponentModelType.GPU_A30, - "NIC_OpenStack": ComponentModelType.SharedNIC_OpenStack_vNIC, - "FPGA_Xilinx_U280": ComponentModelType.FPGA_Xilinx_U280, + Constants.CMP_NIC_Basic: ComponentModelType.SharedNIC_ConnectX_6, + Constants.CMP_NIC_ConnectX_6: ComponentModelType.SmartNIC_ConnectX_6, + Constants.CMP_NIC_ConnectX_5: ComponentModelType.SmartNIC_ConnectX_5, + Constants.CMP_NIC_P4: Constants.P4_DedicatedPort, + Constants.CMP_NVME_P4510: ComponentModelType.NVME_P4510, + Constants.CMP_GPU_TeslaT4: ComponentModelType.GPU_Tesla_T4, + Constants.CMP_GPU_RTX6000: ComponentModelType.GPU_RTX6000, + Constants.CMP_GPU_A40: ComponentModelType.GPU_A40, + Constants.CMP_GPU_A30: ComponentModelType.GPU_A30, + Constants.CMP_NIC_OpenStack: ComponentModelType.SharedNIC_OpenStack_vNIC, + Constants.CMP_FPGA_Xilinx_U280: ComponentModelType.FPGA_Xilinx_U280, } def __str__(self): @@ -448,25 +450,23 @@ def get_model(self) -> str: str(self.get_type()) == "SmartNIC" and str(self.get_fim_model()) == "ConnectX-6" ): - return "NIC_ConnectX_6" + return Constants.CMP_NIC_ConnectX_6 elif ( str(self.get_type()) == "SmartNIC" and str(self.get_fim_model()) == "ConnectX-5" ): - return "NIC_ConnectX_5" + return Constants.CMP_NIC_ConnectX_5 elif str(self.get_type()) == "NVME" and str(self.get_fim_model()) == "P4510": - return "NVME_P4510" + return Constants.CMP_NVME_P4510 elif str(self.get_type()) == "GPU" and str(self.get_fim_model()) == "Tesla T4": - return "GPU_TeslaT4" + return Constants.CMP_GPU_TeslaT4 elif str(self.get_type()) == "GPU" and str(self.get_fim_model()) == "RTX6000": - return "GPU_RTX6000" + return Constants.CMP_GPU_RTX6000 elif ( str(self.get_type()) == "SharedNIC" and str(self.get_fim_model()) == "ConnectX-6" ): - return "NIC_Basic" - else: - return None + return Constants.CMP_NIC_Basic def get_reservation_id(self) -> str or None: """ diff --git a/fabrictestbed_extensions/fablib/constants.py b/fabrictestbed_extensions/fablib/constants.py index f53e98ef..7d8df3eb 100644 --- a/fabrictestbed_extensions/fablib/constants.py +++ b/fabrictestbed_extensions/fablib/constants.py @@ -183,3 +183,16 @@ class Constants: CPUS = "CPUs" HOSTS = "Hosts" P4_SWITCH = "P4-Switch" + + CMP_NIC_Basic = "NIC_Basic" + CMP_NIC_ConnectX_6 = "NIC_ConnectX_6" + CMP_NIC_ConnectX_5 = "NIC_ConnectX_5" + CMP_NIC_P4 = "NIC_P4" + CMP_NVME_P4510 = "NVME_P4510" + CMP_GPU_TeslaT4 = "GPU_TeslaT4" + CMP_GPU_RTX6000 = "GPU_RTX6000" + CMP_GPU_A40 = "GPU_A40" + CMP_GPU_A30 = "GPU_A30" + CMP_NIC_OpenStack = "NIC_OpenStack" + CMP_FPGA_Xilinx_U280 = "FPGA_Xilinx_U280" + P4_DedicatedPort = "P4_DedicatedPort" diff --git a/fabrictestbed_extensions/fablib/interface.py b/fabrictestbed_extensions/fablib/interface.py index dd825474..0246b18f 100644 --- a/fabrictestbed_extensions/fablib/interface.py +++ b/fabrictestbed_extensions/fablib/interface.py @@ -33,13 +33,15 @@ import json import logging from ipaddress import IPv4Address -from typing import TYPE_CHECKING, Any, Union +from typing import TYPE_CHECKING, Any, Union, List import jinja2 from fabrictestbed.slice_editor import Flags -from fim.user import Labels +from fim.user import Labels, InterfaceType from tabulate import tabulate +from fabrictestbed_extensions.fablib.constants import Constants + if TYPE_CHECKING: from fabrictestbed_extensions.fablib.slice import Slice from fabrictestbed_extensions.fablib.node import Node @@ -89,6 +91,7 @@ def __init__( self.dev = None self.node = node self.model = model + self.interfaces = None def get_fablib_manager(self): return self.get_slice().get_fablib_manager() @@ -1278,3 +1281,66 @@ def get_peer_account_id(self): """ if self.get_fim() and self.get_fim().peer_labels: return self.get_fim().peer_labels.account_id + + def get_interfaces(self) -> List[Interface]: + """ + Gets the interfaces attached to this fablib component's FABRIC component. + + :return: a list of the interfaces on this component. + :rtype: List[Interface] + """ + + if not self.interfaces: + self.interfaces = [] + for fim_interface in self.get_fim().interface_list: + self.interfaces.append( + Interface(component=self.get_component(), fim_interface=fim_interface, + model=str(InterfaceType.SubInterface)) + ) + + return self.interfaces + + def add_sub_interface(self, name: str, vlan: str, bw: int = 10): + """ + Add a sub-interface to a dedicated NIC. + + This method adds a sub-interface to a NIC (Network Interface Card) with the specified + name, VLAN (Virtual Local Area Network) ID, and bandwidth. It supports only specific + NIC models. + + :param name: The name of the sub-interface. + :type name: str + + :param vlan: The VLAN ID for the sub-interface. + :type vlan: str + + :param bw: The bandwidth allocated to the sub-interface, in Gbps. Default is 10 Gbps. + :type bw: int + + :raises Exception: If the NIC model does not support sub-interfaces. + """ + if self.get_model() not in [Constants.CMP_NIC_ConnectX_5, Constants.CMP_NIC_ConnectX_6]: + raise Exception(f"Sub interfaces are only supported for the following NIC models: " + f"{Constants.CMP_NIC_ConnectX_5}, {Constants.CMP_NIC_ConnectX_6}") + + if self.get_fim(): + self.get_fim().add_child_interface(name=name, labels=Labels(vlan=vlan, bw=bw)) + + def remove_sub_interface(self, name: str): + """ + Remove a sub-interface from a dedicated NIC. + + This method removes a sub-interface from a NIC with the specified name. It supports + only specific NIC models. + + :param name: The name of the sub-interface to remove. + :type name: str + + :raises Exception: If the NIC model does not support sub-interfaces. + """ + if self.get_model() not in [Constants.CMP_NIC_ConnectX_5, Constants.CMP_NIC_ConnectX_6]: + raise Exception(f"Sub interfaces are only supported for the following NIC models: " + f"{Constants.CMP_NIC_ConnectX_5}, {Constants.CMP_NIC_ConnectX_6}") + + if self.get_fim(): + self.get_fim().remove_child_interface(name=name) From 16e62d03449337c1ce4555bb01874961dd8fdf42 Mon Sep 17 00:00:00 2001 From: Komal Thareja Date: Thu, 27 Jun 2024 23:59:03 -0400 Subject: [PATCH 02/15] set bw in capacities --- fabrictestbed_extensions/fablib/interface.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fabrictestbed_extensions/fablib/interface.py b/fabrictestbed_extensions/fablib/interface.py index 0246b18f..25edf802 100644 --- a/fabrictestbed_extensions/fablib/interface.py +++ b/fabrictestbed_extensions/fablib/interface.py @@ -1324,7 +1324,14 @@ def add_sub_interface(self, name: str, vlan: str, bw: int = 10): f"{Constants.CMP_NIC_ConnectX_5}, {Constants.CMP_NIC_ConnectX_6}") if self.get_fim(): - self.get_fim().add_child_interface(name=name, labels=Labels(vlan=vlan, bw=bw)) + child_interface = self.get_fim().add_child_interface(name=name, labels=Labels(vlan=vlan)) + child_if_capacities = child_interface.get_property(pname="capacities") + child_if_capacities.bw = int(bw) + child_interface.set_properties(capacities=child_if_capacities) + if not self.interfaces: + self.interfaces = [] + self.interfaces.append(Interface(component=self.get_component(), fim_interface=child_interface, + model=str(InterfaceType.SubInterface))) def remove_sub_interface(self, name: str): """ From 0f29b47db521a9f078db5d2e4b7b210cc06ec4eb Mon Sep 17 00:00:00 2001 From: Komal Thareja Date: Fri, 28 Jun 2024 00:00:30 -0400 Subject: [PATCH 03/15] set bw in capacities --- fabrictestbed_extensions/fablib/interface.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fabrictestbed_extensions/fablib/interface.py b/fabrictestbed_extensions/fablib/interface.py index 25edf802..f989283f 100644 --- a/fabrictestbed_extensions/fablib/interface.py +++ b/fabrictestbed_extensions/fablib/interface.py @@ -37,7 +37,7 @@ import jinja2 from fabrictestbed.slice_editor import Flags -from fim.user import Labels, InterfaceType +from fim.user import Labels, InterfaceType, Capacities from tabulate import tabulate from fabrictestbed_extensions.fablib.constants import Constants @@ -1326,6 +1326,8 @@ def add_sub_interface(self, name: str, vlan: str, bw: int = 10): if self.get_fim(): child_interface = self.get_fim().add_child_interface(name=name, labels=Labels(vlan=vlan)) child_if_capacities = child_interface.get_property(pname="capacities") + if not child_if_capacities: + child_if_capacities = Capacities() child_if_capacities.bw = int(bw) child_interface.set_properties(capacities=child_if_capacities) if not self.interfaces: From 0a317b2f4ed97f65f011841bbc3403de74d68c57 Mon Sep 17 00:00:00 2001 From: Komal Thareja Date: Fri, 28 Jun 2024 00:02:42 -0400 Subject: [PATCH 04/15] set bw in capacities --- fabrictestbed_extensions/fablib/interface.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fabrictestbed_extensions/fablib/interface.py b/fabrictestbed_extensions/fablib/interface.py index f989283f..76d1bb9c 100644 --- a/fabrictestbed_extensions/fablib/interface.py +++ b/fabrictestbed_extensions/fablib/interface.py @@ -1332,8 +1332,11 @@ def add_sub_interface(self, name: str, vlan: str, bw: int = 10): child_interface.set_properties(capacities=child_if_capacities) if not self.interfaces: self.interfaces = [] - self.interfaces.append(Interface(component=self.get_component(), fim_interface=child_interface, - model=str(InterfaceType.SubInterface))) + + ch_iface = Interface(component=self.get_component(), fim_interface=child_interface, + model=str(InterfaceType.SubInterface)) + self.interfaces.append(ch_iface) + return ch_iface def remove_sub_interface(self, name: str): """ From 703746cd2d310b727fa8de0390d0964b6a83d49c Mon Sep 17 00:00:00 2001 From: Komal Thareja Date: Fri, 28 Jun 2024 12:24:24 -0400 Subject: [PATCH 05/15] list interfaces to list sub interfaces --- fabrictestbed_extensions/fablib/component.py | 8 +++++--- fabrictestbed_extensions/fablib/interface.py | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/fabrictestbed_extensions/fablib/component.py b/fabrictestbed_extensions/fablib/component.py index de0a7702..f39814d0 100644 --- a/fabrictestbed_extensions/fablib/component.py +++ b/fabrictestbed_extensions/fablib/component.py @@ -332,9 +332,11 @@ def get_interfaces(self) -> List[Interface]: if not self.interfaces: self.interfaces = [] for fim_interface in self.get_fim_component().interface_list: - self.interfaces.append( - Interface(component=self, fim_interface=fim_interface) - ) + iface = Interface(component=self, fim_interface=fim_interface) + self.interfaces.append(iface) + child_interfaces = iface.get_interfaces() + if child_interfaces and len(child_interfaces): + self.interfaces.extend(child_interfaces) return self.interfaces diff --git a/fabrictestbed_extensions/fablib/interface.py b/fabrictestbed_extensions/fablib/interface.py index 76d1bb9c..27129818 100644 --- a/fabrictestbed_extensions/fablib/interface.py +++ b/fabrictestbed_extensions/fablib/interface.py @@ -112,6 +112,7 @@ def __str__(self): table = [ ["Name", self.get_name()], + ["Type", self.get_type()], ["Network", network_name], ["Bandwidth", self.get_bandwidth()], ["Mode", self.get_mode()], @@ -159,6 +160,7 @@ def get_pretty_name_dict(): return { "name": "Name", "short_name": "Short Name", + "type": "Type", "node": "Node", "network": "Network", "bandwidth": "Bandwidth", @@ -216,6 +218,7 @@ def toDict(self, skip=[]): return { "name": str(self.get_name()), "short_name": str(self.get_short_name()), + "type": str(self.get_type()), "node": str(node_name), "network": str(network_name), "bandwidth": str(self.get_bandwidth()), @@ -722,6 +725,10 @@ def get_short_name(self): :return: Shortened name of the interface. :rtype: str """ + interface_type = self.get_type() + if interface_type and interface_type == str(InterfaceType.SubInterface): + return self.get_name() + # Strip off the extra parts of the name added by FIM prefix_length = len( f"{self.get_node().get_name()}-{self.get_component().get_short_name()}-" @@ -1356,3 +1363,12 @@ def remove_sub_interface(self, name: str): if self.get_fim(): self.get_fim().remove_child_interface(name=name) + + def get_type(self) -> str: + """ + Get Interface type + :return: get interface type + :rtype: String + """ + if self.get_fim(): + return self.get_fim().type From 0cfa8f791f515b302cf7682c4dd4624705a43d69 Mon Sep 17 00:00:00 2001 From: Komal Thareja Date: Fri, 28 Jun 2024 15:20:31 -0400 Subject: [PATCH 06/15] return mac from parent --- fabrictestbed_extensions/fablib/interface.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fabrictestbed_extensions/fablib/interface.py b/fabrictestbed_extensions/fablib/interface.py index 27129818..f0ceb2e2 100644 --- a/fabrictestbed_extensions/fablib/interface.py +++ b/fabrictestbed_extensions/fablib/interface.py @@ -68,6 +68,7 @@ def __init__( fim_interface: FimInterface = None, node: Union[Switch, FacilityPort] = None, model: str = None, + parent: Interface = None ): """ .. note:: @@ -92,6 +93,7 @@ def __init__( self.node = node self.model = model self.interfaces = None + self.parent = parent def get_fablib_manager(self): return self.get_slice().get_fablib_manager() @@ -112,7 +114,6 @@ def __str__(self): table = [ ["Name", self.get_name()], - ["Type", self.get_type()], ["Network", network_name], ["Bandwidth", self.get_bandwidth()], ["Mode", self.get_mode()], @@ -160,7 +161,6 @@ def get_pretty_name_dict(): return { "name": "Name", "short_name": "Short Name", - "type": "Type", "node": "Node", "network": "Network", "bandwidth": "Bandwidth", @@ -218,7 +218,6 @@ def toDict(self, skip=[]): return { "name": str(self.get_name()), "short_name": str(self.get_short_name()), - "type": str(self.get_type()), "node": str(node_name), "network": str(network_name), "bandwidth": str(self.get_bandwidth()), @@ -454,7 +453,10 @@ def get_mac(self) -> str: :rtype: String """ try: - mac = self.get_fim_interface().get_property(pname="label_allocations").mac + if self.parent: + mac = self.parent.get_mac() + else: + mac = self.get_fim_interface().get_property(pname="label_allocations").mac except: mac = None From 667c4a782a67b327d193df8b49bb840f5be04a36 Mon Sep 17 00:00:00 2001 From: Komal Thareja Date: Fri, 28 Jun 2024 15:33:38 -0400 Subject: [PATCH 07/15] return mac from parent --- fabrictestbed_extensions/fablib/interface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabrictestbed_extensions/fablib/interface.py b/fabrictestbed_extensions/fablib/interface.py index f0ceb2e2..340dd5d8 100644 --- a/fabrictestbed_extensions/fablib/interface.py +++ b/fabrictestbed_extensions/fablib/interface.py @@ -1304,7 +1304,7 @@ def get_interfaces(self) -> List[Interface]: for fim_interface in self.get_fim().interface_list: self.interfaces.append( Interface(component=self.get_component(), fim_interface=fim_interface, - model=str(InterfaceType.SubInterface)) + model=str(InterfaceType.SubInterface), parent=self) ) return self.interfaces From 09e3b3c6b1b6a6d0ff5dd6671108279ea2f38218 Mon Sep 17 00:00:00 2001 From: Komal Thareja Date: Fri, 28 Jun 2024 15:35:54 -0400 Subject: [PATCH 08/15] return mac from parent --- fabrictestbed_extensions/fablib/interface.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fabrictestbed_extensions/fablib/interface.py b/fabrictestbed_extensions/fablib/interface.py index 340dd5d8..da3fb28d 100644 --- a/fabrictestbed_extensions/fablib/interface.py +++ b/fabrictestbed_extensions/fablib/interface.py @@ -727,8 +727,7 @@ def get_short_name(self): :return: Shortened name of the interface. :rtype: str """ - interface_type = self.get_type() - if interface_type and interface_type == str(InterfaceType.SubInterface): + if self.parent: return self.get_name() # Strip off the extra parts of the name added by FIM From dd17c44c4c0ec6bc7f7861c262648efe1fcb664e Mon Sep 17 00:00:00 2001 From: Komal Thareja Date: Fri, 28 Jun 2024 17:06:13 -0400 Subject: [PATCH 09/15] modify get_interfaces to not include subinterfaces on request --- fabrictestbed_extensions/fablib/component.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/fabrictestbed_extensions/fablib/component.py b/fabrictestbed_extensions/fablib/component.py index f39814d0..ba78e624 100644 --- a/fabrictestbed_extensions/fablib/component.py +++ b/fabrictestbed_extensions/fablib/component.py @@ -319,10 +319,13 @@ def __init__(self, node: Node = None, fim_component: FimComponent = None): self.node = node self.interfaces = None - def get_interfaces(self) -> List[Interface]: + def get_interfaces(self, exclude_sub_interfaces: bool = False) -> List[Interface]: """ Gets the interfaces attached to this fablib component's FABRIC component. + :param exclude_sub_interfaces: Flag indicating if Sub interfaces should be included + :type exclude_sub_interfaces: bool + :return: a list of the interfaces on this component. :rtype: List[Interface] """ @@ -334,9 +337,10 @@ def get_interfaces(self) -> List[Interface]: for fim_interface in self.get_fim_component().interface_list: iface = Interface(component=self, fim_interface=fim_interface) self.interfaces.append(iface) - child_interfaces = iface.get_interfaces() - if child_interfaces and len(child_interfaces): - self.interfaces.extend(child_interfaces) + if not exclude_sub_interfaces: + child_interfaces = iface.get_interfaces() + if child_interfaces and len(child_interfaces): + self.interfaces.extend(child_interfaces) return self.interfaces From 9980effc8512ab33b74017e28762f0c9d144fd89 Mon Sep 17 00:00:00 2001 From: Komal Thareja Date: Fri, 28 Jun 2024 17:10:08 -0400 Subject: [PATCH 10/15] modify get_interfaces to not include subinterfaces on request --- fabrictestbed_extensions/fablib/component.py | 8 ++++---- fabrictestbed_extensions/fablib/node.py | 7 +++++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/fabrictestbed_extensions/fablib/component.py b/fabrictestbed_extensions/fablib/component.py index ba78e624..c9eea51b 100644 --- a/fabrictestbed_extensions/fablib/component.py +++ b/fabrictestbed_extensions/fablib/component.py @@ -319,12 +319,12 @@ def __init__(self, node: Node = None, fim_component: FimComponent = None): self.node = node self.interfaces = None - def get_interfaces(self, exclude_sub_interfaces: bool = False) -> List[Interface]: + def get_interfaces(self, include_subs: bool = True) -> List[Interface]: """ Gets the interfaces attached to this fablib component's FABRIC component. - :param exclude_sub_interfaces: Flag indicating if Sub interfaces should be included - :type exclude_sub_interfaces: bool + :param include_subs: Flag indicating if sub interfaces should be included + :type include_subs: bool :return: a list of the interfaces on this component. :rtype: List[Interface] @@ -337,7 +337,7 @@ def get_interfaces(self, exclude_sub_interfaces: bool = False) -> List[Interface for fim_interface in self.get_fim_component().interface_list: iface = Interface(component=self, fim_interface=fim_interface) self.interfaces.append(iface) - if not exclude_sub_interfaces: + if include_subs: child_interfaces = iface.get_interfaces() if child_interfaces and len(child_interfaces): self.interfaces.extend(child_interfaces) diff --git a/fabrictestbed_extensions/fablib/node.py b/fabrictestbed_extensions/fablib/node.py index 851bfd50..530a00be 100644 --- a/fabrictestbed_extensions/fablib/node.py +++ b/fabrictestbed_extensions/fablib/node.py @@ -1024,16 +1024,19 @@ def get_error_message(self) -> str or None: except: return "" - def get_interfaces(self) -> List[Interface] or None: + def get_interfaces(self, include_subs: bool = True) -> List[Interface] or None: """ Gets a list of the interfaces associated with the FABRIC node. + :param include_subs: Flag indicating if sub interfaces should be included + :type include_subs: bool + :return: a list of interfaces on the node :rtype: List[Interface] """ interfaces = [] for component in self.get_components(): - for interface in component.get_interfaces(): + for interface in component.get_interfaces(include_subs=include_subs): interfaces.append(interface) return interfaces From 16c05ac749f511262a196c0b96b270b04db01b72 Mon Sep 17 00:00:00 2001 From: Komal Thareja Date: Mon, 1 Jul 2024 16:44:13 -0400 Subject: [PATCH 11/15] remove sub interface --- fabrictestbed_extensions/fablib/interface.py | 21 ++------------------ 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/fabrictestbed_extensions/fablib/interface.py b/fabrictestbed_extensions/fablib/interface.py index da3fb28d..fd2fe151 100644 --- a/fabrictestbed_extensions/fablib/interface.py +++ b/fabrictestbed_extensions/fablib/interface.py @@ -1204,6 +1204,8 @@ def delete(self): net = self.get_network() if net: net.remove_interface(self) + if self.parent and self.parent.get_fim(): + self.parent.get_fim().remove_child_interface(name=self.get_name()) def set_subnet(self, ipv4_subnet: str = None, ipv6_subnet: str = None): """ @@ -1346,25 +1348,6 @@ def add_sub_interface(self, name: str, vlan: str, bw: int = 10): self.interfaces.append(ch_iface) return ch_iface - def remove_sub_interface(self, name: str): - """ - Remove a sub-interface from a dedicated NIC. - - This method removes a sub-interface from a NIC with the specified name. It supports - only specific NIC models. - - :param name: The name of the sub-interface to remove. - :type name: str - - :raises Exception: If the NIC model does not support sub-interfaces. - """ - if self.get_model() not in [Constants.CMP_NIC_ConnectX_5, Constants.CMP_NIC_ConnectX_6]: - raise Exception(f"Sub interfaces are only supported for the following NIC models: " - f"{Constants.CMP_NIC_ConnectX_5}, {Constants.CMP_NIC_ConnectX_6}") - - if self.get_fim(): - self.get_fim().remove_child_interface(name=name) - def get_type(self) -> str: """ Get Interface type From 76bee46497a692aafb221ca390ca6143d4a8dbd6 Mon Sep 17 00:00:00 2001 From: Komal Thareja Date: Mon, 8 Jul 2024 14:47:54 -0400 Subject: [PATCH 12/15] deleting the child interface even if not connected to network --- fabrictestbed_extensions/fablib/interface.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fabrictestbed_extensions/fablib/interface.py b/fabrictestbed_extensions/fablib/interface.py index fd2fe151..fd679beb 100644 --- a/fabrictestbed_extensions/fablib/interface.py +++ b/fabrictestbed_extensions/fablib/interface.py @@ -1204,8 +1204,8 @@ def delete(self): net = self.get_network() if net: net.remove_interface(self) - if self.parent and self.parent.get_fim(): - self.parent.get_fim().remove_child_interface(name=self.get_name()) + if self.parent and self.parent.get_fim(): + self.parent.get_fim().remove_child_interface(name=self.get_name()) def set_subnet(self, ipv4_subnet: str = None, ipv6_subnet: str = None): """ From c1b3a2a28ddc93aa32d48d95d01afe8516fe377a Mon Sep 17 00:00:00 2001 From: Komal Thareja Date: Mon, 8 Jul 2024 14:52:10 -0400 Subject: [PATCH 13/15] up the dependency --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index f8d6b00f..9db3b3d1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ dependencies = [ "ipyleaflet", "ipycytoscape", "tabulate", - "fabrictestbed==1.7.0b11", + "fabrictestbed==1.7.0b12", "paramiko", "jinja2>=3.0.0", "pandas", From 1cebda221fc646edb91f15e4a316a3d336bf6d1c Mon Sep 17 00:00:00 2001 From: Komal Thareja Date: Mon, 8 Jul 2024 14:54:56 -0400 Subject: [PATCH 14/15] black,isort, changelog --- CHANGELOG.md | 1 + fabrictestbed_extensions/fablib/interface.py | 40 ++++++++++++++------ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2174af84..e3ec4799 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 # Unreleased ### Fixed +- Sub Interface Support (Issue [#350](https://github.com/fabric-testbed/fabrictestbed-extensions/issues/350)) - Advanced reservations (Issue [#345](https://github.com/fabric-testbed/fabrictestbed-extensions/issues/345)) - Port Mirroring with Basic NICs (Issue [#343](https://github.com/fabric-testbed/fabrictestbed-extensions/issues/343)) - P4 support (Issue [#340](https://github.com/fabric-testbed/fabrictestbed-extensions/issues/340)) diff --git a/fabrictestbed_extensions/fablib/interface.py b/fabrictestbed_extensions/fablib/interface.py index fd679beb..3174c0e4 100644 --- a/fabrictestbed_extensions/fablib/interface.py +++ b/fabrictestbed_extensions/fablib/interface.py @@ -33,11 +33,11 @@ import json import logging from ipaddress import IPv4Address -from typing import TYPE_CHECKING, Any, Union, List +from typing import TYPE_CHECKING, Any, List, Union import jinja2 from fabrictestbed.slice_editor import Flags -from fim.user import Labels, InterfaceType, Capacities +from fim.user import Capacities, InterfaceType, Labels from tabulate import tabulate from fabrictestbed_extensions.fablib.constants import Constants @@ -68,7 +68,7 @@ def __init__( fim_interface: FimInterface = None, node: Union[Switch, FacilityPort] = None, model: str = None, - parent: Interface = None + parent: Interface = None, ): """ .. note:: @@ -456,7 +456,9 @@ def get_mac(self) -> str: if self.parent: mac = self.parent.get_mac() else: - mac = self.get_fim_interface().get_property(pname="label_allocations").mac + mac = ( + self.get_fim_interface().get_property(pname="label_allocations").mac + ) except: mac = None @@ -1304,8 +1306,12 @@ def get_interfaces(self) -> List[Interface]: self.interfaces = [] for fim_interface in self.get_fim().interface_list: self.interfaces.append( - Interface(component=self.get_component(), fim_interface=fim_interface, - model=str(InterfaceType.SubInterface), parent=self) + Interface( + component=self.get_component(), + fim_interface=fim_interface, + model=str(InterfaceType.SubInterface), + parent=self, + ) ) return self.interfaces @@ -1329,12 +1335,19 @@ def add_sub_interface(self, name: str, vlan: str, bw: int = 10): :raises Exception: If the NIC model does not support sub-interfaces. """ - if self.get_model() not in [Constants.CMP_NIC_ConnectX_5, Constants.CMP_NIC_ConnectX_6]: - raise Exception(f"Sub interfaces are only supported for the following NIC models: " - f"{Constants.CMP_NIC_ConnectX_5}, {Constants.CMP_NIC_ConnectX_6}") + if self.get_model() not in [ + Constants.CMP_NIC_ConnectX_5, + Constants.CMP_NIC_ConnectX_6, + ]: + raise Exception( + f"Sub interfaces are only supported for the following NIC models: " + f"{Constants.CMP_NIC_ConnectX_5}, {Constants.CMP_NIC_ConnectX_6}" + ) if self.get_fim(): - child_interface = self.get_fim().add_child_interface(name=name, labels=Labels(vlan=vlan)) + child_interface = self.get_fim().add_child_interface( + name=name, labels=Labels(vlan=vlan) + ) child_if_capacities = child_interface.get_property(pname="capacities") if not child_if_capacities: child_if_capacities = Capacities() @@ -1343,8 +1356,11 @@ def add_sub_interface(self, name: str, vlan: str, bw: int = 10): if not self.interfaces: self.interfaces = [] - ch_iface = Interface(component=self.get_component(), fim_interface=child_interface, - model=str(InterfaceType.SubInterface)) + ch_iface = Interface( + component=self.get_component(), + fim_interface=child_interface, + model=str(InterfaceType.SubInterface), + ) self.interfaces.append(ch_iface) return ch_iface From 187fb5333145db05365c626d9b61a0695cab6bbb Mon Sep 17 00:00:00 2001 From: Komal Thareja Date: Mon, 8 Jul 2024 15:02:33 -0400 Subject: [PATCH 15/15] add whitespace --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 10793291..e5877eb2 100644 --- a/README.md +++ b/README.md @@ -90,3 +90,4 @@ help FABlib, please review the [guidelines] first. [guidelines]: ./CONTRIBUTING.md +