Underscore 'parent' refs to make pydantic happy.
Rename attributes like connected_link and connected_node to start with an underscore. This will prevent circular dependency and stack recursion depth error.
This commit is contained in:
@@ -89,9 +89,9 @@ class NIC(SimComponent):
|
|||||||
"The Maximum Transmission Unit (MTU) of the NIC in Bytes. Default is 1500 B"
|
"The Maximum Transmission Unit (MTU) of the NIC in Bytes. Default is 1500 B"
|
||||||
wake_on_lan: bool = False
|
wake_on_lan: bool = False
|
||||||
"Indicates if the NIC supports Wake-on-LAN functionality."
|
"Indicates if the NIC supports Wake-on-LAN functionality."
|
||||||
connected_node: Optional[Node] = None
|
_connected_node: Optional[Node] = None
|
||||||
"The Node to which the NIC is connected."
|
"The Node to which the NIC is connected."
|
||||||
connected_link: Optional[Link] = None
|
_connected_link: Optional[Link] = None
|
||||||
"The Link to which the NIC is connected."
|
"The Link to which the NIC is connected."
|
||||||
enabled: bool = False
|
enabled: bool = False
|
||||||
"Indicates whether the NIC is enabled."
|
"Indicates whether the NIC is enabled."
|
||||||
@@ -166,21 +166,21 @@ class NIC(SimComponent):
|
|||||||
"""Attempt to enable the NIC."""
|
"""Attempt to enable the NIC."""
|
||||||
if self.enabled:
|
if self.enabled:
|
||||||
return
|
return
|
||||||
if not self.connected_node:
|
if not self._connected_node:
|
||||||
_LOGGER.error(f"NIC {self} cannot be enabled as it is not connected to a Node")
|
_LOGGER.error(f"NIC {self} cannot be enabled as it is not connected to a Node")
|
||||||
return
|
return
|
||||||
if self.connected_node.operating_state != NodeOperatingState.ON:
|
if self._connected_node.operating_state != NodeOperatingState.ON:
|
||||||
self.connected_node.sys_log.error(f"NIC {self} cannot be enabled as the endpoint is not turned on")
|
self._connected_node.sys_log.error(f"NIC {self} cannot be enabled as the endpoint is not turned on")
|
||||||
return
|
return
|
||||||
if not self.connected_link:
|
if not self._connected_link:
|
||||||
_LOGGER.error(f"NIC {self} cannot be enabled as it is not connected to a Link")
|
_LOGGER.error(f"NIC {self} cannot be enabled as it is not connected to a Link")
|
||||||
return
|
return
|
||||||
|
|
||||||
self.enabled = True
|
self.enabled = True
|
||||||
self.connected_node.sys_log.info(f"NIC {self} enabled")
|
self._connected_node.sys_log.info(f"NIC {self} enabled")
|
||||||
self.pcap = PacketCapture(hostname=self.connected_node.hostname, ip_address=self.ip_address)
|
self.pcap = PacketCapture(hostname=self._connected_node.hostname, ip_address=self.ip_address)
|
||||||
if self.connected_link:
|
if self._connected_link:
|
||||||
self.connected_link.endpoint_up()
|
self._connected_link.endpoint_up()
|
||||||
|
|
||||||
def disable(self):
|
def disable(self):
|
||||||
"""Disable the NIC."""
|
"""Disable the NIC."""
|
||||||
@@ -188,12 +188,12 @@ class NIC(SimComponent):
|
|||||||
return
|
return
|
||||||
|
|
||||||
self.enabled = False
|
self.enabled = False
|
||||||
if self.connected_node:
|
if self._connected_node:
|
||||||
self.connected_node.sys_log.info(f"NIC {self} disabled")
|
self._connected_node.sys_log.info(f"NIC {self} disabled")
|
||||||
else:
|
else:
|
||||||
_LOGGER.debug(f"NIC {self} disabled")
|
_LOGGER.debug(f"NIC {self} disabled")
|
||||||
if self.connected_link:
|
if self._connected_link:
|
||||||
self.connected_link.endpoint_down()
|
self._connected_link.endpoint_down()
|
||||||
|
|
||||||
def connect_link(self, link: Link):
|
def connect_link(self, link: Link):
|
||||||
"""
|
"""
|
||||||
@@ -202,26 +202,26 @@ class NIC(SimComponent):
|
|||||||
:param link: The link to which the NIC is connected.
|
:param link: The link to which the NIC is connected.
|
||||||
:type link: :class:`~primaite.simulator.network.transmission.physical_layer.Link`
|
:type link: :class:`~primaite.simulator.network.transmission.physical_layer.Link`
|
||||||
"""
|
"""
|
||||||
if self.connected_link:
|
if self._connected_link:
|
||||||
_LOGGER.error(f"Cannot connect Link to NIC ({self.mac_address}) as it already has a connection")
|
_LOGGER.error(f"Cannot connect Link to NIC ({self.mac_address}) as it already has a connection")
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.connected_link == link:
|
if self._connected_link == link:
|
||||||
_LOGGER.error(f"Cannot connect Link to NIC ({self.mac_address}) as it is already connected")
|
_LOGGER.error(f"Cannot connect Link to NIC ({self.mac_address}) as it is already connected")
|
||||||
return
|
return
|
||||||
|
|
||||||
# TODO: Inform the Node that a link has been connected
|
# TODO: Inform the Node that a link has been connected
|
||||||
self.connected_link = link
|
self._connected_link = link
|
||||||
self.enable()
|
self.enable()
|
||||||
_LOGGER.debug(f"NIC {self} connected to Link {link}")
|
_LOGGER.debug(f"NIC {self} connected to Link {link}")
|
||||||
|
|
||||||
def disconnect_link(self):
|
def disconnect_link(self):
|
||||||
"""Disconnect the NIC from the connected Link."""
|
"""Disconnect the NIC from the connected Link."""
|
||||||
if self.connected_link.endpoint_a == self:
|
if self._connected_link.endpoint_a == self:
|
||||||
self.connected_link.endpoint_a = None
|
self._connected_link.endpoint_a = None
|
||||||
if self.connected_link.endpoint_b == self:
|
if self._connected_link.endpoint_b == self:
|
||||||
self.connected_link.endpoint_b = None
|
self._connected_link.endpoint_b = None
|
||||||
self.connected_link = None
|
self._connected_link = None
|
||||||
|
|
||||||
def add_dns_server(self, ip_address: IPv4Address):
|
def add_dns_server(self, ip_address: IPv4Address):
|
||||||
"""
|
"""
|
||||||
@@ -251,7 +251,7 @@ class NIC(SimComponent):
|
|||||||
if self.enabled:
|
if self.enabled:
|
||||||
frame.set_sent_timestamp()
|
frame.set_sent_timestamp()
|
||||||
self.pcap.capture(frame)
|
self.pcap.capture(frame)
|
||||||
self.connected_link.transmit_frame(sender_nic=self, frame=frame)
|
self._connected_link.transmit_frame(sender_nic=self, frame=frame)
|
||||||
return True
|
return True
|
||||||
# Cannot send Frame as the NIC is not enabled
|
# Cannot send Frame as the NIC is not enabled
|
||||||
return False
|
return False
|
||||||
@@ -270,7 +270,7 @@ class NIC(SimComponent):
|
|||||||
self.pcap.capture(frame)
|
self.pcap.capture(frame)
|
||||||
# If this destination or is broadcast
|
# If this destination or is broadcast
|
||||||
if frame.ethernet.dst_mac_addr == self.mac_address or frame.ethernet.dst_mac_addr == "ff:ff:ff:ff:ff:ff":
|
if frame.ethernet.dst_mac_addr == self.mac_address or frame.ethernet.dst_mac_addr == "ff:ff:ff:ff:ff:ff":
|
||||||
self.connected_node.receive_frame(frame=frame, from_nic=self)
|
self._connected_node.receive_frame(frame=frame, from_nic=self)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -295,9 +295,9 @@ class SwitchPort(SimComponent):
|
|||||||
"The speed of the SwitchPort in Mbps. Default is 100 Mbps."
|
"The speed of the SwitchPort in Mbps. Default is 100 Mbps."
|
||||||
mtu: int = 1500
|
mtu: int = 1500
|
||||||
"The Maximum Transmission Unit (MTU) of the SwitchPort in Bytes. Default is 1500 B"
|
"The Maximum Transmission Unit (MTU) of the SwitchPort in Bytes. Default is 1500 B"
|
||||||
connected_node: Optional[Node] = None
|
_connected_node: Optional[Node] = None
|
||||||
"The Node to which the SwitchPort is connected."
|
"The Node to which the SwitchPort is connected."
|
||||||
connected_link: Optional[Link] = None
|
_connected_link: Optional[Link] = None
|
||||||
"The Link to which the SwitchPort is connected."
|
"The Link to which the SwitchPort is connected."
|
||||||
enabled: bool = False
|
enabled: bool = False
|
||||||
"Indicates whether the SwitchPort is enabled."
|
"Indicates whether the SwitchPort is enabled."
|
||||||
@@ -334,31 +334,31 @@ class SwitchPort(SimComponent):
|
|||||||
if self.enabled:
|
if self.enabled:
|
||||||
return
|
return
|
||||||
|
|
||||||
if not self.connected_node:
|
if not self._connected_node:
|
||||||
_LOGGER.error(f"SwitchPort {self} cannot be enabled as it is not connected to a Node")
|
_LOGGER.error(f"SwitchPort {self} cannot be enabled as it is not connected to a Node")
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.connected_node.operating_state != NodeOperatingState.ON:
|
if self._connected_node.operating_state != NodeOperatingState.ON:
|
||||||
self.connected_node.sys_log.info(f"SwitchPort {self} cannot be enabled as the endpoint is not turned on")
|
self._connected_node.sys_log.info(f"SwitchPort {self} cannot be enabled as the endpoint is not turned on")
|
||||||
return
|
return
|
||||||
|
|
||||||
self.enabled = True
|
self.enabled = True
|
||||||
self.connected_node.sys_log.info(f"SwitchPort {self} enabled")
|
self._connected_node.sys_log.info(f"SwitchPort {self} enabled")
|
||||||
self.pcap = PacketCapture(hostname=self.connected_node.hostname, switch_port_number=self.port_num)
|
self.pcap = PacketCapture(hostname=self._connected_node.hostname, switch_port_number=self.port_num)
|
||||||
if self.connected_link:
|
if self._connected_link:
|
||||||
self.connected_link.endpoint_up()
|
self._connected_link.endpoint_up()
|
||||||
|
|
||||||
def disable(self):
|
def disable(self):
|
||||||
"""Disable the SwitchPort."""
|
"""Disable the SwitchPort."""
|
||||||
if not self.enabled:
|
if not self.enabled:
|
||||||
return
|
return
|
||||||
self.enabled = False
|
self.enabled = False
|
||||||
if self.connected_node:
|
if self._connected_node:
|
||||||
self.connected_node.sys_log.info(f"SwitchPort {self} disabled")
|
self._connected_node.sys_log.info(f"SwitchPort {self} disabled")
|
||||||
else:
|
else:
|
||||||
_LOGGER.debug(f"SwitchPort {self} disabled")
|
_LOGGER.debug(f"SwitchPort {self} disabled")
|
||||||
if self.connected_link:
|
if self._connected_link:
|
||||||
self.connected_link.endpoint_down()
|
self._connected_link.endpoint_down()
|
||||||
|
|
||||||
def connect_link(self, link: Link):
|
def connect_link(self, link: Link):
|
||||||
"""
|
"""
|
||||||
@@ -366,26 +366,26 @@ class SwitchPort(SimComponent):
|
|||||||
|
|
||||||
:param link: The link to which the SwitchPort is connected.
|
:param link: The link to which the SwitchPort is connected.
|
||||||
"""
|
"""
|
||||||
if self.connected_link:
|
if self._connected_link:
|
||||||
_LOGGER.error(f"Cannot connect link to SwitchPort {self.mac_address} as it already has a connection")
|
_LOGGER.error(f"Cannot connect link to SwitchPort {self.mac_address} as it already has a connection")
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.connected_link == link:
|
if self._connected_link == link:
|
||||||
_LOGGER.error(f"Cannot connect Link to SwitchPort {self.mac_address} as it is already connected")
|
_LOGGER.error(f"Cannot connect Link to SwitchPort {self.mac_address} as it is already connected")
|
||||||
return
|
return
|
||||||
|
|
||||||
# TODO: Inform the Switch that a link has been connected
|
# TODO: Inform the Switch that a link has been connected
|
||||||
self.connected_link = link
|
self._connected_link = link
|
||||||
_LOGGER.debug(f"SwitchPort {self} connected to Link {link}")
|
_LOGGER.debug(f"SwitchPort {self} connected to Link {link}")
|
||||||
self.enable()
|
self.enable()
|
||||||
|
|
||||||
def disconnect_link(self):
|
def disconnect_link(self):
|
||||||
"""Disconnect the SwitchPort from the connected Link."""
|
"""Disconnect the SwitchPort from the connected Link."""
|
||||||
if self.connected_link.endpoint_a == self:
|
if self._connected_link.endpoint_a == self:
|
||||||
self.connected_link.endpoint_a = None
|
self._connected_link.endpoint_a = None
|
||||||
if self.connected_link.endpoint_b == self:
|
if self._connected_link.endpoint_b == self:
|
||||||
self.connected_link.endpoint_b = None
|
self._connected_link.endpoint_b = None
|
||||||
self.connected_link = None
|
self._connected_link = None
|
||||||
|
|
||||||
def send_frame(self, frame: Frame) -> bool:
|
def send_frame(self, frame: Frame) -> bool:
|
||||||
"""
|
"""
|
||||||
@@ -395,7 +395,7 @@ class SwitchPort(SimComponent):
|
|||||||
"""
|
"""
|
||||||
if self.enabled:
|
if self.enabled:
|
||||||
self.pcap.capture(frame)
|
self.pcap.capture(frame)
|
||||||
self.connected_link.transmit_frame(sender_nic=self, frame=frame)
|
self._connected_link.transmit_frame(sender_nic=self, frame=frame)
|
||||||
return True
|
return True
|
||||||
# Cannot send Frame as the SwitchPort is not enabled
|
# Cannot send Frame as the SwitchPort is not enabled
|
||||||
return False
|
return False
|
||||||
@@ -411,7 +411,7 @@ class SwitchPort(SimComponent):
|
|||||||
if self.enabled:
|
if self.enabled:
|
||||||
frame.decrement_ttl()
|
frame.decrement_ttl()
|
||||||
self.pcap.capture(frame)
|
self.pcap.capture(frame)
|
||||||
connected_node: Node = self.connected_node
|
connected_node: Node = self._connected_node
|
||||||
connected_node.forward_frame(frame=frame, incoming_port=self)
|
connected_node.forward_frame(frame=frame, incoming_port=self)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
@@ -1037,7 +1037,7 @@ class Node(SimComponent):
|
|||||||
self.operating_state = NodeOperatingState.ON
|
self.operating_state = NodeOperatingState.ON
|
||||||
self.sys_log.info("Turned on")
|
self.sys_log.info("Turned on")
|
||||||
for nic in self.nics.values():
|
for nic in self.nics.values():
|
||||||
if nic.connected_link:
|
if nic._connected_link:
|
||||||
nic.enable()
|
nic.enable()
|
||||||
|
|
||||||
def power_off(self):
|
def power_off(self):
|
||||||
@@ -1058,7 +1058,7 @@ class Node(SimComponent):
|
|||||||
if nic.uuid not in self.nics:
|
if nic.uuid not in self.nics:
|
||||||
self.nics[nic.uuid] = nic
|
self.nics[nic.uuid] = nic
|
||||||
self.ethernet_port[len(self.nics)] = nic
|
self.ethernet_port[len(self.nics)] = nic
|
||||||
nic.connected_node = self
|
nic._connected_node = self
|
||||||
nic.parent = self
|
nic.parent = self
|
||||||
self.sys_log.info(f"Connected NIC {nic}")
|
self.sys_log.info(f"Connected NIC {nic}")
|
||||||
if self.operating_state == NodeOperatingState.ON:
|
if self.operating_state == NodeOperatingState.ON:
|
||||||
@@ -1225,7 +1225,7 @@ class Switch(Node):
|
|||||||
if not self.switch_ports:
|
if not self.switch_ports:
|
||||||
self.switch_ports = {i: SwitchPort() for i in range(1, self.num_ports + 1)}
|
self.switch_ports = {i: SwitchPort() for i in range(1, self.num_ports + 1)}
|
||||||
for port_num, port in self.switch_ports.items():
|
for port_num, port in self.switch_ports.items():
|
||||||
port.connected_node = self
|
port._connected_node = self
|
||||||
port.parent = self
|
port.parent = self
|
||||||
port.port_num = port_num
|
port.port_num = port_num
|
||||||
|
|
||||||
@@ -1298,7 +1298,7 @@ class Switch(Node):
|
|||||||
_LOGGER.error(msg)
|
_LOGGER.error(msg)
|
||||||
raise NetworkError(msg)
|
raise NetworkError(msg)
|
||||||
|
|
||||||
if port.connected_link != link:
|
if port._connected_link != link:
|
||||||
msg = f"The link does not match the connection at port number {port_number}"
|
msg = f"The link does not match the connection at port number {port_number}"
|
||||||
_LOGGER.error(msg)
|
_LOGGER.error(msg)
|
||||||
raise NetworkError(msg)
|
raise NetworkError(msg)
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class Switch(Node):
|
|||||||
if not self.switch_ports:
|
if not self.switch_ports:
|
||||||
self.switch_ports = {i: SwitchPort() for i in range(1, self.num_ports + 1)}
|
self.switch_ports = {i: SwitchPort() for i in range(1, self.num_ports + 1)}
|
||||||
for port_num, port in self.switch_ports.items():
|
for port_num, port in self.switch_ports.items():
|
||||||
port.connected_node = self
|
port._connected_node = self
|
||||||
port.parent = self
|
port.parent = self
|
||||||
port.port_num = port_num
|
port.port_num = port_num
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ class Switch(Node):
|
|||||||
_LOGGER.error(msg)
|
_LOGGER.error(msg)
|
||||||
raise NetworkError(msg)
|
raise NetworkError(msg)
|
||||||
|
|
||||||
if port.connected_link != link:
|
if port._connected_link != link:
|
||||||
msg = f"The link does not match the connection at port number {port_number}"
|
msg = f"The link does not match the connection at port number {port_number}"
|
||||||
_LOGGER.error(msg)
|
_LOGGER.error(msg)
|
||||||
raise NetworkError(msg)
|
raise NetworkError(msg)
|
||||||
|
|||||||
@@ -70,8 +70,8 @@ def test_connecting_node_to_itself():
|
|||||||
net.connect(node.nics[nic1.uuid], node.nics[nic2.uuid], bandwidth=30)
|
net.connect(node.nics[nic1.uuid], node.nics[nic2.uuid], bandwidth=30)
|
||||||
|
|
||||||
assert node in net
|
assert node in net
|
||||||
assert nic1.connected_link is None
|
assert nic1._connected_link is None
|
||||||
assert nic2.connected_link is None
|
assert nic2._connected_link is None
|
||||||
assert len(net.links) == 0
|
assert len(net.links) == 0
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user