daemon: fixed sdt icons due to legacy gui removal, updated node.type to node.model to avoid variables with the same names with different meanings

This commit is contained in:
Blake Harnden 2022-04-05 13:39:57 -07:00
parent ea751727b4
commit 5ee561b210
15 changed files with 73 additions and 93 deletions

View file

@ -748,9 +748,9 @@ class CoreGrpcClient:
:raises grpc.RpcError: when session doesn't exist
"""
defaults = []
for node_type in service_defaults:
services = service_defaults[node_type]
default = ServiceDefaults(node_type=node_type, services=services)
for model in service_defaults:
services = service_defaults[model]
default = ServiceDefaults(model=model, services=services)
defaults.append(default)
request = SetServiceDefaultsRequest(session_id=session_id, defaults=defaults)
response = self.stub.SetServiceDefaults(request)

View file

@ -33,7 +33,7 @@ def handle_node_event(node_data: NodeData) -> core_pb2.Event:
node_proto = core_pb2.Node(
id=node.id,
name=node.name,
model=node.type,
model=node.model,
icon=node.icon,
position=position,
geo=geo,

View file

@ -286,7 +286,6 @@ def get_node_proto(
lat=node.position.lat, lon=node.position.lon, alt=node.position.alt
)
services = [x.name for x in node.services]
model = node.type
node_dir = None
config_services = []
if isinstance(node, CoreNodeBase):
@ -341,7 +340,7 @@ def get_node_proto(
id=node.id,
name=node.name,
emane=emane_model,
model=model,
model=node.model,
type=node_type.value,
position=position,
geo=geo,
@ -729,8 +728,8 @@ def get_default_services(session: Session) -> List[ServiceDefaults]:
:return: list of default service sets
"""
default_services = []
for name, services in session.services.default_services.items():
default_service = ServiceDefaults(node_type=name, services=services)
for model, services in session.services.default_services.items():
default_service = ServiceDefaults(model=model, services=services)
default_services.append(default_service)
return default_services

View file

@ -920,7 +920,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
session.services.default_services.clear()
for service_defaults in request.defaults:
session.services.default_services[
service_defaults.node_type
service_defaults.model
] = service_defaults.services
return SetServiceDefaultsResponse(result=True)

View file

@ -210,12 +210,12 @@ class Service:
@dataclass
class ServiceDefault:
node_type: str
model: str
services: List[str]
@classmethod
def from_proto(cls, proto: services_pb2.ServiceDefaults) -> "ServiceDefault":
return ServiceDefault(node_type=proto.node_type, services=list(proto.services))
return ServiceDefault(model=proto.model, services=list(proto.services))
@dataclass
@ -884,9 +884,7 @@ class Session:
def from_proto(cls, proto: core_pb2.Session) -> "Session":
nodes: Dict[int, Node] = {x.id: Node.from_proto(x) for x in proto.nodes}
links = [Link.from_proto(x) for x in proto.links]
default_services = {
x.node_type: set(x.services) for x in proto.default_services
}
default_services = {x.model: set(x.services) for x in proto.default_services}
hooks = {x.file: Hook.from_proto(x) for x in proto.hooks}
file_path = Path(proto.file) if proto.file else None
options = ConfigOption.from_dict(proto.options)
@ -914,9 +912,9 @@ class Session:
options = {k: v.to_proto() for k, v in self.options.items()}
servers = [x.to_proto() for x in self.servers]
default_services = []
for node_type, services in self.default_services.items():
for model, services in self.default_services.items():
default_service = services_pb2.ServiceDefaults(
node_type=node_type, services=services
model=model, services=services
)
default_services.append(default_service)
file = str(self.file) if self.file else None

View file

@ -536,15 +536,15 @@ class Session:
# add services to needed nodes
if isinstance(node, (CoreNode, PhysicalNode)):
node.type = options.model
node.model = options.model
if options.legacy or options.services:
logger.debug("set node type: %s", node.type)
self.services.add_services(node, node.type, options.services)
logger.debug("set node type: %s", node.model)
self.services.add_services(node, node.model, options.services)
# add config services
config_services = options.config_services
if not options.legacy and not config_services and not node.services:
config_services = self.services.default_services.get(node.type, [])
config_services = self.services.default_services.get(node.model, [])
logger.info("setting node config services: %s", config_services)
for name in config_services:
service_class = self.service_manager.get_service(name)

View file

@ -62,11 +62,9 @@ class NodeBase(abc.ABC):
if _id is None:
_id = session.next_node_id()
self.id: int = _id
if name is None:
name = f"o{self.id}"
self.name: str = name
self.name: str = name or f"o{self.id}"
self.server: "DistributedServer" = server
self.type: Optional[str] = None
self.model: Optional[str] = None
self.services: CoreServices = []
self.ifaces: Dict[int, CoreInterface] = {}
self.iface_id: int = 0

View file

@ -663,7 +663,6 @@ class SwitchNode(CoreNetwork):
apitype: NodeTypes = NodeTypes.SWITCH
policy: NetworkPolicy = NetworkPolicy.ACCEPT
type: str = "lanswitch"
class HubNode(CoreNetwork):
@ -674,7 +673,6 @@ class HubNode(CoreNetwork):
apitype: NodeTypes = NodeTypes.HUB
policy: NetworkPolicy = NetworkPolicy.ACCEPT
type: str = "hub"
def startup(self) -> None:
"""
@ -694,7 +692,6 @@ class WlanNode(CoreNetwork):
apitype: NodeTypes = NodeTypes.WIRELESS_LAN
linktype: LinkTypes = LinkTypes.WIRED
policy: NetworkPolicy = NetworkPolicy.DROP
type: str = "wlan"
def __init__(
self,
@ -794,4 +791,3 @@ class TunnelNode(GreTapBridge):
apitype: NodeTypes = NodeTypes.TUNNEL
policy: NetworkPolicy = NetworkPolicy.ACCEPT
type: str = "tunnel"

View file

@ -29,7 +29,6 @@ class Rj45Node(CoreNodeBase):
"""
apitype: NodeTypes = NodeTypes.RJ45
type: str = "rj45"
def __init__(
self,

View file

@ -4,16 +4,18 @@ sdt.py: Scripted Display Tool (SDT3D) helper
import logging
import socket
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple
from pathlib import Path
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple, Type
from urllib.parse import urlparse
from core.constants import CORE_CONF_DIR, CORE_DATA_DIR
from core.constants import CORE_CONF_DIR
from core.emane.nodes import EmaneNet
from core.emulator.data import LinkData, NodeData
from core.emulator.enumerations import EventTypes, MessageFlags
from core.errors import CoreError
from core.nodes.base import NodeBase
from core.nodes.network import WlanNode
from core.nodes.base import CoreNode, NodeBase
from core.nodes.network import HubNode, SwitchNode, TunnelNode, WlanNode
from core.nodes.physical import Rj45Node
from core.nodes.wireless import WirelessNode
logger = logging.getLogger(__name__)
@ -21,12 +23,22 @@ logger = logging.getLogger(__name__)
if TYPE_CHECKING:
from core.emulator.session import Session
LOCAL_ICONS_PATH: Path = Path(__file__).parent.parent / "gui" / "data" / "icons"
CORE_LAYER: str = "CORE"
NODE_LAYER: str = "CORE::Nodes"
LINK_LAYER: str = "CORE::Links"
WIRED_LINK_LAYER: str = f"{LINK_LAYER}::wired"
CORE_LAYERS: List[str] = [CORE_LAYER, LINK_LAYER, NODE_LAYER, WIRED_LINK_LAYER]
DEFAULT_LINK_COLOR: str = "red"
NODE_TYPES: Dict[Type[NodeBase], str] = {
HubNode: "hub",
SwitchNode: "lanswitch",
TunnelNode: "tunnel",
WlanNode: "wlan",
EmaneNet: "emane",
WirelessNode: "wireless",
Rj45Node: "rj45",
}
def is_wireless(node: NodeBase) -> bool:
@ -52,16 +64,18 @@ class Sdt:
DEFAULT_ALT: int = 2500
# TODO: read in user"s nodes.conf here; below are default node types from the GUI
DEFAULT_SPRITES: Dict[str, str] = [
("router", "router.gif"),
("host", "host.gif"),
("PC", "pc.gif"),
("mdr", "mdr.gif"),
("prouter", "router_green.gif"),
("hub", "hub.gif"),
("lanswitch", "lanswitch.gif"),
("wlan", "wlan.gif"),
("rj45", "rj45.gif"),
("tunnel", "tunnel.gif"),
("router", "router.png"),
("host", "host.png"),
("PC", "pc.png"),
("mdr", "mdr.png"),
("prouter", "prouter.png"),
("hub", "hub.png"),
("lanswitch", "lanswitch.png"),
("wlan", "wlan.png"),
("emane", "emane.png"),
("wireless", "wireless.png"),
("rj45", "rj45.png"),
("tunnel", "tunnel.png"),
]
def __init__(self, session: "Session") -> None:
@ -144,7 +158,7 @@ class Sdt:
:return: initialize command status
"""
if not self.cmd(f'path "{CORE_DATA_DIR}/icons/normal"'):
if not self.cmd(f'path "{LOCAL_ICONS_PATH.absolute()}"'):
return False
# send node type to icon mappings
for node_type, icon in self.DEFAULT_SPRITES:
@ -166,7 +180,6 @@ class Sdt:
logger.error("error closing socket")
finally:
self.sock = None
self.connected = False
def shutdown(self) -> None:
@ -194,7 +207,6 @@ class Sdt:
"""
if self.sock is None:
return False
try:
cmd = f"{cmdstr}\n".encode()
logger.debug("sdt cmd: %s", cmd)
@ -259,13 +271,14 @@ class Sdt:
pos = self.get_node_position(node)
if not pos:
return
node_type = node.type
if node_type is None:
node_type = type(node).type
if isinstance(node, CoreNode):
node_type = node.model
else:
node_type = NODE_TYPES.get(type(node), "PC")
icon = node.icon
if icon:
node_type = node.name
icon = icon.replace("$CORE_DATA_DIR", str(CORE_DATA_DIR))
icon = icon.replace("$CORE_DATA_DIR", str(LOCAL_ICONS_PATH.absolute()))
icon = icon.replace("$CORE_CONF_DIR", str(CORE_CONF_DIR))
self.cmd(f"sprite {node_type} image {icon}")
self.cmd(

View file

@ -234,26 +234,6 @@ class CoreServices:
"""
self.custom_services.clear()
def get_default_services(self, node_type: str) -> List[Type["CoreService"]]:
"""
Get the list of default services that should be enabled for a
node for the given node type.
:param node_type: node type to get default services for
:return: default services
"""
logger.debug("getting default services for type: %s", node_type)
results = []
defaults = self.default_services.get(node_type, [])
for name in defaults:
logger.debug("checking for service with service manager: %s", name)
service = ServiceManager.get(name)
if not service:
logger.warning("default service %s is unknown", name)
else:
results.append(service)
return results
def get_service(
self, node_id: int, service_name: str, default_service: bool = False
) -> "CoreService":
@ -293,21 +273,21 @@ class CoreServices:
node_services[service.name] = service
def add_services(
self, node: CoreNode, node_type: str, services: List[str] = None
self, node: CoreNode, model: str, services: List[str] = None
) -> None:
"""
Add services to a node.
:param node: node to add services to
:param node_type: node type to add services to
:param model: node model type to add services for
:param services: names of services to add to node
:return: nothing
"""
if not services:
logger.info(
"using default services for node(%s) type(%s)", node.name, node_type
"using default services for node(%s) type(%s)", node.name, model
)
services = self.default_services.get(node_type, [])
services = self.default_services.get(model, [])
logger.info("setting services for node(%s): %s", node.name, services)
for service_name in services:
service = self.get_service(node.id, service_name, default_service=True)

View file

@ -211,7 +211,7 @@ class ServiceElement:
class DeviceElement(NodeElement):
def __init__(self, session: "Session", node: NodeBase) -> None:
super().__init__(session, node, "device")
add_attribute(self.element, "type", node.type)
add_attribute(self.element, "type", node.model)
self.add_class()
self.add_services()
@ -434,15 +434,14 @@ class CoreXmlWriter:
self.scenario.append(service_configurations)
def write_default_services(self) -> None:
node_types = etree.Element("default_services")
for node_type in self.session.services.default_services:
services = self.session.services.default_services[node_type]
node_type = etree.SubElement(node_types, "node", type=node_type)
models = etree.Element("default_services")
for model in self.session.services.default_services:
services = self.session.services.default_services[model]
model = etree.SubElement(models, "node", type=model)
for service in services:
etree.SubElement(node_type, "service", name=service)
if node_types.getchildren():
self.scenario.append(node_types)
etree.SubElement(model, "service", name=service)
if models.getchildren():
self.scenario.append(models)
def write_nodes(self) -> None:
for node_id in self.session.nodes:
@ -586,14 +585,12 @@ class CoreXmlReader:
return
for node in default_services.iterchildren():
node_type = node.get("type")
model = node.get("type")
services = []
for service in node.iterchildren():
services.append(service.get("name"))
logger.info(
"reading default services for nodes(%s): %s", node_type, services
)
self.session.services.default_services[node_type] = services
logger.info("reading default services for nodes(%s): %s", model, services)
self.session.services.default_services[model] = services
def read_session_metadata(self) -> None:
session_metadata = self.scenario.find("session_metadata")

View file

@ -37,7 +37,7 @@ message ServiceAction {
}
message ServiceDefaults {
string node_type = 1;
string model = 1;
repeated string services = 2;
}

View file

@ -641,16 +641,16 @@ class TestGrpc:
# given
client = CoreGrpcClient()
session = grpc_server.coreemu.create_session()
node_type = "test"
model = "test"
services = ["SSH"]
# then
with client.context_connect():
result = client.set_service_defaults(session.id, {node_type: services})
result = client.set_service_defaults(session.id, {model: services})
# then
assert result is True
assert session.services.default_services[node_type] == services
assert session.services.default_services[model] == services
def test_get_node_service(self, grpc_server: CoreGrpcServer):
# given

View file

@ -53,7 +53,7 @@ class TestServices:
total_service = len(node.services)
# when
session.services.add_services(node, node.type, [SERVICE_ONE, SERVICE_TWO])
session.services.add_services(node, node.model, [SERVICE_ONE, SERVICE_TWO])
# then
assert node.services