daemon: refactored NodeData to reference a node instead of replicating fields as an intermediate passthrough, removed data() functions from nodes due to this change
This commit is contained in:
parent
1702fe256f
commit
ecc3eb1c89
10 changed files with 52 additions and 129 deletions
daemon
core
api
emulator
nodes
plugins
tests
|
@ -15,24 +15,28 @@ from core.emulator.data import (
|
||||||
from core.emulator.session import Session
|
from core.emulator.session import Session
|
||||||
|
|
||||||
|
|
||||||
def handle_node_event(event: NodeData) -> core_pb2.NodeEvent:
|
def handle_node_event(node_data: NodeData) -> core_pb2.NodeEvent:
|
||||||
"""
|
"""
|
||||||
Handle node event when there is a node event
|
Handle node event when there is a node event
|
||||||
|
|
||||||
:param event: node data
|
:param node_data: node data
|
||||||
:return: node event that contains node id, name, model, position, and services
|
:return: node event that contains node id, name, model, position, and services
|
||||||
"""
|
"""
|
||||||
position = core_pb2.Position(x=event.x_position, y=event.y_position)
|
node = node_data.node
|
||||||
geo = core_pb2.Geo(lat=event.latitude, lon=event.longitude, alt=event.altitude)
|
x, y, _ = node.position.get()
|
||||||
|
position = core_pb2.Position(x=x, y=y)
|
||||||
|
lon, lat, alt = node.position.get_geo()
|
||||||
|
geo = core_pb2.Geo(lon=lon, lat=lat, alt=alt)
|
||||||
|
services = [x.name for x in node.services]
|
||||||
node_proto = core_pb2.Node(
|
node_proto = core_pb2.Node(
|
||||||
id=event.id,
|
id=node.id,
|
||||||
name=event.name,
|
name=node.name,
|
||||||
model=event.model,
|
model=node.type,
|
||||||
position=position,
|
position=position,
|
||||||
geo=geo,
|
geo=geo,
|
||||||
services=event.services,
|
services=services,
|
||||||
)
|
)
|
||||||
return core_pb2.NodeEvent(node=node_proto, source=event.source)
|
return core_pb2.NodeEvent(node=node_proto, source=node_data.source)
|
||||||
|
|
||||||
|
|
||||||
def handle_link_event(event: LinkData) -> core_pb2.LinkEvent:
|
def handle_link_event(event: LinkData) -> core_pb2.LinkEvent:
|
||||||
|
|
|
@ -329,7 +329,6 @@ class CoreHandler(socketserver.BaseRequestHandler):
|
||||||
"""
|
"""
|
||||||
logging.debug("handling broadcast node: %s", node_data)
|
logging.debug("handling broadcast node: %s", node_data)
|
||||||
message = dataconversion.convert_node(node_data)
|
message = dataconversion.convert_node(node_data)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.sendall(message)
|
self.sendall(message)
|
||||||
except IOError:
|
except IOError:
|
||||||
|
|
|
@ -8,35 +8,39 @@ from typing import Dict, List
|
||||||
from core.api.tlv import coreapi, structutils
|
from core.api.tlv import coreapi, structutils
|
||||||
from core.api.tlv.enumerations import ConfigTlvs, NodeTlvs
|
from core.api.tlv.enumerations import ConfigTlvs, NodeTlvs
|
||||||
from core.config import ConfigGroup, ConfigurableOptions
|
from core.config import ConfigGroup, ConfigurableOptions
|
||||||
from core.emulator.data import ConfigData
|
from core.emulator.data import ConfigData, NodeData
|
||||||
|
|
||||||
|
|
||||||
def convert_node(node_data):
|
def convert_node(node_data: NodeData):
|
||||||
"""
|
"""
|
||||||
Convenience method for converting NodeData to a packed TLV message.
|
Convenience method for converting NodeData to a packed TLV message.
|
||||||
|
|
||||||
:param core.emulator.data.NodeData node_data: node data to convert
|
:param core.emulator.data.NodeData node_data: node data to convert
|
||||||
:return: packed node message
|
:return: packed node message
|
||||||
"""
|
"""
|
||||||
|
node = node_data.node
|
||||||
services = None
|
services = None
|
||||||
if node_data.services is not None:
|
if node.services is not None:
|
||||||
services = "|".join([x for x in node_data.services])
|
services = "|".join([x.name for x in node.services])
|
||||||
|
server = None
|
||||||
|
if node.server is not None:
|
||||||
|
server = node.server.name
|
||||||
tlv_data = structutils.pack_values(
|
tlv_data = structutils.pack_values(
|
||||||
coreapi.CoreNodeTlv,
|
coreapi.CoreNodeTlv,
|
||||||
[
|
[
|
||||||
(NodeTlvs.NUMBER, node_data.id),
|
(NodeTlvs.NUMBER, node.id),
|
||||||
(NodeTlvs.TYPE, node_data.type.value),
|
(NodeTlvs.TYPE, node.apitype.value),
|
||||||
(NodeTlvs.NAME, node_data.name),
|
(NodeTlvs.NAME, node.name),
|
||||||
(NodeTlvs.MODEL, node_data.model),
|
(NodeTlvs.MODEL, node.type),
|
||||||
(NodeTlvs.EMULATION_SERVER, node_data.server),
|
(NodeTlvs.EMULATION_SERVER, server),
|
||||||
(NodeTlvs.X_POSITION, int(node_data.x_position)),
|
(NodeTlvs.X_POSITION, int(node.position.x)),
|
||||||
(NodeTlvs.Y_POSITION, int(node_data.y_position)),
|
(NodeTlvs.Y_POSITION, int(node.position.y)),
|
||||||
(NodeTlvs.CANVAS, node_data.canvas),
|
(NodeTlvs.CANVAS, node.canvas),
|
||||||
(NodeTlvs.SERVICES, services),
|
(NodeTlvs.SERVICES, services),
|
||||||
(NodeTlvs.LATITUDE, str(node_data.latitude)),
|
(NodeTlvs.LATITUDE, str(node.position.lat)),
|
||||||
(NodeTlvs.LONGITUDE, str(node_data.longitude)),
|
(NodeTlvs.LONGITUDE, str(node.position.lon)),
|
||||||
(NodeTlvs.ALTITUDE, str(node_data.altitude)),
|
(NodeTlvs.ALTITUDE, str(node.position.alt)),
|
||||||
(NodeTlvs.ICON, node_data.icon),
|
(NodeTlvs.ICON, node.icon),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
return coreapi.CoreNodeMessage.pack(node_data.message_type.value, tlv_data)
|
return coreapi.CoreNodeMessage.pack(node_data.message_type.value, tlv_data)
|
||||||
|
|
|
@ -12,11 +12,10 @@ from core.emulator.enumerations import (
|
||||||
ExceptionLevels,
|
ExceptionLevels,
|
||||||
LinkTypes,
|
LinkTypes,
|
||||||
MessageFlags,
|
MessageFlags,
|
||||||
NodeTypes,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from core.nodes.base import CoreNode
|
from core.nodes.base import CoreNode, NodeBase
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
@ -121,23 +120,11 @@ class NodeOptions:
|
||||||
@dataclass
|
@dataclass
|
||||||
class NodeData:
|
class NodeData:
|
||||||
"""
|
"""
|
||||||
Used to represent nodes being broadcasted.
|
Node to broadcast.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
node: "NodeBase"
|
||||||
message_type: MessageFlags = None
|
message_type: MessageFlags = None
|
||||||
type: NodeTypes = None
|
|
||||||
id: int = None
|
|
||||||
name: str = None
|
|
||||||
model: str = None
|
|
||||||
server: str = None
|
|
||||||
icon: str = None
|
|
||||||
canvas: int = None
|
|
||||||
services: List[str] = None
|
|
||||||
x_position: float = None
|
|
||||||
y_position: float = None
|
|
||||||
latitude: float = None
|
|
||||||
longitude: float = None
|
|
||||||
altitude: float = None
|
|
||||||
source: str = None
|
source: str = None
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -807,9 +807,9 @@ class Session:
|
||||||
:param source: source of broadcast, None by default
|
:param source: source of broadcast, None by default
|
||||||
:return: nothing
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
node_data = node.data(message_type, source)
|
if not node.apitype:
|
||||||
if not node_data:
|
|
||||||
return
|
return
|
||||||
|
node_data = NodeData(node=node, message_type=message_type, source=source)
|
||||||
for handler in self.node_handlers:
|
for handler in self.node_handlers:
|
||||||
handler(node_data)
|
handler(node_data)
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ import netaddr
|
||||||
from core import utils
|
from core import utils
|
||||||
from core.configservice.dependencies import ConfigServiceDependencies
|
from core.configservice.dependencies import ConfigServiceDependencies
|
||||||
from core.constants import MOUNT_BIN, VNODED_BIN
|
from core.constants import MOUNT_BIN, VNODED_BIN
|
||||||
from core.emulator.data import InterfaceData, LinkData, LinkOptions, NodeData
|
from core.emulator.data import InterfaceData, LinkData, LinkOptions
|
||||||
from core.emulator.enumerations import LinkTypes, MessageFlags, NodeTypes
|
from core.emulator.enumerations import LinkTypes, MessageFlags, NodeTypes
|
||||||
from core.errors import CoreCommandError, CoreError
|
from core.errors import CoreCommandError, CoreError
|
||||||
from core.nodes.client import VnodeClient
|
from core.nodes.client import VnodeClient
|
||||||
|
@ -182,42 +182,6 @@ class NodeBase(abc.ABC):
|
||||||
self.iface_id += 1
|
self.iface_id += 1
|
||||||
return iface_id
|
return iface_id
|
||||||
|
|
||||||
def data(
|
|
||||||
self, message_type: MessageFlags = MessageFlags.NONE, source: str = None
|
|
||||||
) -> Optional[NodeData]:
|
|
||||||
"""
|
|
||||||
Build a data object for this node.
|
|
||||||
|
|
||||||
:param message_type: purpose for the data object we are creating
|
|
||||||
:param source: source of node data
|
|
||||||
:return: node data object
|
|
||||||
"""
|
|
||||||
if self.apitype is None:
|
|
||||||
return None
|
|
||||||
x, y, _ = self.getposition()
|
|
||||||
model = self.type
|
|
||||||
server = None
|
|
||||||
if self.server is not None:
|
|
||||||
server = self.server.name
|
|
||||||
services = [x.name for x in self.services]
|
|
||||||
return NodeData(
|
|
||||||
message_type=message_type,
|
|
||||||
type=self.apitype,
|
|
||||||
id=self.id,
|
|
||||||
name=self.name,
|
|
||||||
model=model,
|
|
||||||
server=server,
|
|
||||||
canvas=self.canvas,
|
|
||||||
icon=self.icon,
|
|
||||||
x_position=x,
|
|
||||||
y_position=y,
|
|
||||||
latitude=self.position.lat,
|
|
||||||
longitude=self.position.lon,
|
|
||||||
altitude=self.position.alt,
|
|
||||||
services=services,
|
|
||||||
source=source,
|
|
||||||
)
|
|
||||||
|
|
||||||
def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
|
def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
|
||||||
"""
|
"""
|
||||||
Build link data for this node.
|
Build link data for this node.
|
||||||
|
|
|
@ -8,7 +8,7 @@ from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Tuple
|
||||||
|
|
||||||
from core import utils
|
from core import utils
|
||||||
from core.emulator.data import LinkOptions
|
from core.emulator.data import LinkOptions
|
||||||
from core.emulator.enumerations import MessageFlags, TransportType
|
from core.emulator.enumerations import TransportType
|
||||||
from core.errors import CoreCommandError
|
from core.errors import CoreCommandError
|
||||||
from core.nodes.netclient import LinuxNetClient, get_net_client
|
from core.nodes.netclient import LinuxNetClient, get_net_client
|
||||||
|
|
||||||
|
@ -561,23 +561,4 @@ class GreTap(CoreInterface):
|
||||||
self.net_client.delete_device(self.localname)
|
self.net_client.delete_device(self.localname)
|
||||||
except CoreCommandError:
|
except CoreCommandError:
|
||||||
logging.exception("error during shutdown")
|
logging.exception("error during shutdown")
|
||||||
|
|
||||||
self.localname = None
|
self.localname = None
|
||||||
|
|
||||||
def data(self, message_type: int) -> None:
|
|
||||||
"""
|
|
||||||
Data for a gre tap.
|
|
||||||
|
|
||||||
:param message_type: message type for data
|
|
||||||
:return: None
|
|
||||||
"""
|
|
||||||
return None
|
|
||||||
|
|
||||||
def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List:
|
|
||||||
"""
|
|
||||||
Retrieve link data.
|
|
||||||
|
|
||||||
:param flags: link flags
|
|
||||||
:return: link data
|
|
||||||
"""
|
|
||||||
return []
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import netaddr
|
||||||
|
|
||||||
from core import utils
|
from core import utils
|
||||||
from core.constants import EBTABLES_BIN, TC_BIN
|
from core.constants import EBTABLES_BIN, TC_BIN
|
||||||
from core.emulator.data import InterfaceData, LinkData, LinkOptions, NodeData
|
from core.emulator.data import InterfaceData, LinkData, LinkOptions
|
||||||
from core.emulator.enumerations import (
|
from core.emulator.enumerations import (
|
||||||
LinkTypes,
|
LinkTypes,
|
||||||
MessageFlags,
|
MessageFlags,
|
||||||
|
@ -862,19 +862,6 @@ class PtpNet(CoreNetwork):
|
||||||
)
|
)
|
||||||
super().attach(iface)
|
super().attach(iface)
|
||||||
|
|
||||||
def data(
|
|
||||||
self, message_type: MessageFlags = MessageFlags.NONE, source: str = None
|
|
||||||
) -> Optional[NodeData]:
|
|
||||||
"""
|
|
||||||
Do not generate a Node Message for point-to-point links. They are
|
|
||||||
built using a link message instead.
|
|
||||||
|
|
||||||
:param message_type: purpose for the data object we are creating
|
|
||||||
:param source: source of node data
|
|
||||||
:return: node data object
|
|
||||||
"""
|
|
||||||
return None
|
|
||||||
|
|
||||||
def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
|
def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
|
||||||
"""
|
"""
|
||||||
Build CORE API TLVs for a point-to-point link. One Link message
|
Build CORE API TLVs for a point-to-point link. One Link message
|
||||||
|
|
|
@ -314,26 +314,22 @@ class Sdt:
|
||||||
:param node_data: node data being updated
|
:param node_data: node data being updated
|
||||||
:return: nothing
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
logging.debug("sdt handle node update: %s - %s", node_data.id, node_data.name)
|
|
||||||
if not self.connect():
|
if not self.connect():
|
||||||
return
|
return
|
||||||
|
node = node_data.node
|
||||||
# delete node
|
logging.debug("sdt handle node update: %s - %s", node.id, node.name)
|
||||||
if node_data.message_type == MessageFlags.DELETE:
|
if node_data.message_type == MessageFlags.DELETE:
|
||||||
self.cmd(f"delete node,{node_data.id}")
|
self.cmd(f"delete node,{node.id}")
|
||||||
else:
|
else:
|
||||||
x = node_data.x_position
|
x, y, _ = node.position.get()
|
||||||
y = node_data.y_position
|
lon, lat, alt = node.position.get_geo()
|
||||||
lat = node_data.latitude
|
|
||||||
lon = node_data.longitude
|
|
||||||
alt = node_data.altitude
|
|
||||||
if all([lat is not None, lon is not None, alt is not None]):
|
if all([lat is not None, lon is not None, alt is not None]):
|
||||||
pos = f"pos {lon:.6f},{lat:.6f},{alt:.6f}"
|
pos = f"pos {lon:.6f},{lat:.6f},{alt:.6f}"
|
||||||
self.cmd(f"node {node_data.id} {pos}")
|
self.cmd(f"node {node.id} {pos}")
|
||||||
elif node_data.message_type == 0:
|
elif node_data.message_type == 0:
|
||||||
lat, lon, alt = self.session.location.getgeo(x, y, 0)
|
lat, lon, alt = self.session.location.getgeo(x, y, 0)
|
||||||
pos = f"pos {lon:.6f},{lat:.6f},{alt:.6f}"
|
pos = f"pos {lon:.6f},{lat:.6f},{alt:.6f}"
|
||||||
self.cmd(f"node {node_data.id} {pos}")
|
self.cmd(f"node {node.id} {pos}")
|
||||||
|
|
||||||
def wireless_net_check(self, node_id: int) -> bool:
|
def wireless_net_check(self, node_id: int) -> bool:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1198,9 +1198,10 @@ class TestGrpc:
|
||||||
queue = Queue()
|
queue = Queue()
|
||||||
|
|
||||||
def node_handler(node_data: NodeData):
|
def node_handler(node_data: NodeData):
|
||||||
assert node_data.longitude == lon
|
n = node_data.node
|
||||||
assert node_data.latitude == lat
|
assert n.position.lon == lon
|
||||||
assert node_data.altitude == alt
|
assert n.position.lat == lat
|
||||||
|
assert n.position.alt == alt
|
||||||
queue.put(node_data)
|
queue.put(node_data)
|
||||||
|
|
||||||
session.node_handlers.append(node_handler)
|
session.node_handlers.append(node_handler)
|
||||||
|
|
Loading…
Add table
Reference in a new issue